diff --git a/.travis.yml b/.travis.yml index 0e324ea037..57ea14f692 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,12 +7,6 @@ services: - docker addons: chrome: stable - artifacts: - paths: - - ./e2e-reports - target_paths: - - e2e - debug: true before_install: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start @@ -33,25 +27,31 @@ cache: - "$HOME/.cache" - node_modules stages: -- Frontend Lint -- Frontend Unit Tests -- Backend -- name: E2E tests - if: type != pull_request OR commit_message =~ /\[e2e\-full\]/ -- name: E2E tests quick - if: type != pull_request OR head_branch =~ ^(?i:e2e)-.*$ OR commit_message =~ /\[e2e\]/ +- Lint +- Test jobs: include: - - stage: Frontend Lint + - stage: Lint + name: Frontend Lint script: - npm run lint - - stage: Frontend Unit Tests + - name: Backend Lint + before_script: + - curl -sL -o ~/bin/gimme https://raw.githubusercontent.com/travis-ci/gimme/master/gimme + - chmod +x ~/bin/gimme + - eval "$(gimme 1.9)" + - go get -u golang.org/x/lint/golint + script: + - golint src/jetstream/... + - ./deploy/ci/travis/update-go-report-card.sh + - stage: Test + name: Frontend Unit Tests env: - CI_ENV=true script: - npm test - npm run codecov - - stage: Backend + - name: Backend Unit Tests before_script: - curl -sL -o ~/bin/gimme https://raw.githubusercontent.com/travis-ci/gimme/master/gimme - chmod +x ~/bin/gimme @@ -59,16 +59,12 @@ jobs: - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh script: - npm run test-backend - - stage: E2E tests - before_script: - - chmod +x ./deploy/ci/travis/run-e2e-tests.sh - script: - - "./deploy/ci/travis/run-e2e-tests.sh" - - stage: E2E tests quick + - name: E2E Tests before_script: - chmod +x ./deploy/ci/travis/run-e2e-tests.sh script: - "./deploy/ci/travis/run-e2e-tests.sh quick" + - "./deploy/ci/travis/upload-e2e-test-report.sh" notifications: slack: secure: s5SFnFKwzfxLrjGR5lJ2AJG1FSWCKtHdQi8K2Kmx5ZhrYL/7P+KLc/ks18WnzCPoy705LbHCBSULcnWbLjqCpnkKxNjsFAyFl2nZZPxBjl2/mHpulbr3gmultDOrMDbmYL4oWPKBlxKResElz9nQwknlLWZ/L94AIx8zuMfRIWdEt1bJBDAQts4fx2D4cIEx0yZUq7JGAKjSiXKR9eDyMWFb+SWw6mvr5WtFM8uq35rPvRVEfm56LIgSuMUpVeYtnYiY2JP7W8iKX0gD+54wAiSXRZiQVCLJq606/TlJo7j8Na9Dn1Q5XDkX3b3XzcgmEZThoO1GFtv3yNYOVxv+50p2tSnc8CT0VEVOYOGJuz17AESZAYK+AyjEmeZmDiroj1czmIq8/ZYKbmvDYSZgGuDcSkQurX/6BPac6ra69WmSQmwv0tS3A/IzDw7X+CuC+3QubQ7GfaiVe25PUU+tRSEDM4PMUJY8QRF5Q+oeN5NjjWmJBqf/ic2TO2xTU1j+qysdqK34qIV1qyVcPMUIiYW+5ltH71qiy05TSvvfGS+oatRBMzINRl3zl2gOV1CKNU801XehRKCx9XDCw5NL1HSx5HD5psOyBRpAMYYBOqa+rv9VAza9MsfpslCoibg5rdrq4rZqqUgRhayNp/LKzlhe/g62+qbGNT+iFuHtB+Y= diff --git a/README.md b/README.md index de50318cde..a3b3c4fe3f 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ # Stratos   - - + + [![GitHub release](https://img.shields.io/github/release/cloudfoundry-incubator/stratos.svg)](https://github.com/cloudfoundry-incubator/stratos/releases/latest) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/cloudfoundry-incubator/stratos/blob/master/LICENSE) [![slack.cloudfoundry.org](https://slack.cloudfoundry.org/badge.svg)](https://cloudfoundry.slack.com/messages/C80EP4Y57/) + Stratos is an Open Source Web-based UI (Console) for managing Cloud Foundry. It allows users and administrators to both manage applications running in the Cloud Foundry cluster and perform cluster management tasks. If you are looking for the V1 version of Stratos, you can find it in the [master](https://github.com/cloudfoundry-incubator/stratos/tree/master) branch. @@ -69,3 +70,4 @@ You can join the Cloud Foundry Slack here - https://slack.cloudfoundry.org/ - a ## License The work done has been licensed under Apache License 2.0. The license file can be found [here](LICENSE). + diff --git a/deploy/ci/tasks/dev-releases/create-chart-helper.sh b/deploy/ci/tasks/dev-releases/create-chart-helper.sh index 7bd3b416c5..cb135d77b6 100644 --- a/deploy/ci/tasks/dev-releases/create-chart-helper.sh +++ b/deploy/ci/tasks/dev-releases/create-chart-helper.sh @@ -40,6 +40,16 @@ setupAndPushChange() { } +updateHelmDependency() { + START_CWD=$(pwd) + cd ${STRATOS}/deploy/kubernetes/console + # Extract helm repo + HELM_REPO=$(cat requirements.yaml | grep repo | sed -e 's/.*repository:\s\(.*\)/\1/p' | head -1) + helm repo add repo ${HELM_REPO} + helm dependency update + cd ${START_CWD} +} + fetchImageTag() { echo "$(cat ${STRATOS}/deploy/ci/tasks/dev-releases/nightly-tag)-$(git rev-parse HEAD | head -c 8)" } diff --git a/deploy/ci/tasks/dev-releases/create-chart.yml b/deploy/ci/tasks/dev-releases/create-chart.yml index 55fc0e4df1..12250ef75d 100644 --- a/deploy/ci/tasks/dev-releases/create-chart.yml +++ b/deploy/ci/tasks/dev-releases/create-chart.yml @@ -30,6 +30,7 @@ run: cd ${STRATOS}/deploy/kubernetes/ patchHelmChart ${GIT_TAG} ${DOCKER_ORG} ${DOCKER_REGISTRY} ./console # Generate Helm package + updateHelmDependency helm package console cp console*.tgz ${ROOT_DIR}/helm-chart/console-helm-chart-${GIT_TAG}.tgz cd ${ROOT_DIR}/helm-chart/ diff --git a/deploy/ci/tasks/dev-releases/create-nightly-chart.yml b/deploy/ci/tasks/dev-releases/create-nightly-chart.yml index 01866b5066..0159e3922c 100644 --- a/deploy/ci/tasks/dev-releases/create-nightly-chart.yml +++ b/deploy/ci/tasks/dev-releases/create-nightly-chart.yml @@ -30,6 +30,7 @@ run: patchHelmChartDev ${IMAGE_TAG} ${DOCKER_ORG} ${DOCKER_REGISTRY} ./console # Generate Helm package + updateHelmDependency helm package console cp console*.tgz ${ROOT_DIR}/helm-chart/console-helm-chart-v${IMAGE_TAG}.tgz cd ${ROOT_DIR}/helm-chart/ diff --git a/deploy/ci/travis/create-pr-branch.sh b/deploy/ci/travis/create-pr-branch.sh old mode 100644 new mode 100755 diff --git a/deploy/ci/travis/run-e2e-tests.sh b/deploy/ci/travis/run-e2e-tests.sh old mode 100644 new mode 100755 index b14a25cb2c..6a796b996d --- a/deploy/ci/travis/run-e2e-tests.sh +++ b/deploy/ci/travis/run-e2e-tests.sh @@ -91,7 +91,7 @@ fi # Output backend log if the tests failed if [ "${RUN_TYPE}" == "quick" ]; then if [ $RESULT -ne 0 ]; then - cat outputs/backend.log + cat src/jetstream/backend.log fi fi diff --git a/deploy/ci/travis/update-go-report-card.sh b/deploy/ci/travis/update-go-report-card.sh new file mode 100755 index 0000000000..8293c3404f --- /dev/null +++ b/deploy/ci/travis/update-go-report-card.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Only update if this is running against v2-master +if [ "$TRAVIS_BRANCH" == "v2-master" ] && [ "$TRAVIS_EVENT_TYPE" != "pull_request" ]; then + echo "Updating GO Report Card for: github.com/${TRAVIS_REPO_SLUG}" + curl -m 300 -d "repo=github.com/${TRAVIS_REPO_SLUG}" https://goreportcard.com/checks +fi + +# Always return success - any failure is down to the goreportcad site not being available +# Don't fail our build for this reason +exit 0 \ No newline at end of file diff --git a/deploy/ci/travis/upload-e2e-test-report.sh b/deploy/ci/travis/upload-e2e-test-report.sh new file mode 100755 index 0000000000..59e578478c --- /dev/null +++ b/deploy/ci/travis/upload-e2e-test-report.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +echo "Stratos e2e test report upload" +echo "==============================" + +if [ -z "${AWS_ENDPOINT}" ]; then + echo "Need S3 endpoint URL" + exit 1 +fi + +wget https://dl.minio.io/client/mc/release/linux-amd64/mc +chmod +x mc + +echo "Uploading test report...." + +echo "Configuring upload client" +./mc config host add s3 ${AWS_ENDPOINT} ${AWS_ACCESS_KEY_ID} ${AWS_SECRET_ACCESS_KEY} --insecure + +echo "Uploading ..." +# Sync the E2E reports +./mc cp --insecure -r e2e-reports s3/${S3_BUCKET} + +# Test report upload failure will not fail the Travis job +exit 0 \ No newline at end of file diff --git a/deploy/kubernetes/README.md b/deploy/kubernetes/README.md index ec9482c9b5..942bb936ac 100644 --- a/deploy/kubernetes/README.md +++ b/deploy/kubernetes/README.md @@ -351,3 +351,32 @@ Install ``` helm install stratos/console --namespace=console --name my-console --version 2.0.0-dev-9a5611dc ``` + +### Enabled Metrics + +[Stratos Metrics](https://github.com/suse/stratos-metrics) can be deployed as part of the Stratos helm chart. The following override file will configure the Metrics component to fetch metrics from a PCF Dev instance. + +Save the following to a file called `values.yaml` +``` +consoleVersion: 2.0.0 +metrics: + enabled: true + env: + CLUSTER_ADMIN_PASSWORD: admin + UAA_CF_IDENTITY_ZONE: uaa + DOMAIN: local.pcfdev.io + UAA_ADMIN_CLIENT_SECRET: admin-client-secret + UAA_HOST: uaa.local.pcfdev.io + UAA_PORT: 443 + DOPPLER_PORT: 443 + firehoseExporter: + noIdentityZone: true +``` + +Deploy Stratos with Metrics enabled +``` +$ helm install ./console -f values.yaml --name console --namespace stratos + +``` + +The metrics endpoint will be available as `https://console-metrics-nginx`. This can registered as an endpoint in Stratos as a `Metrics` type. \ No newline at end of file diff --git a/deploy/kubernetes/build.sh b/deploy/kubernetes/build.sh index 1f09098c3e..d6bfc89430 100755 --- a/deploy/kubernetes/build.sh +++ b/deploy/kubernetes/build.sh @@ -168,6 +168,9 @@ buildPostflightJob buildMariaDb buildUI +# Fetch subcharts +helm dependency update + if [ ${CONCOURSE_BUILD:-"not-set"} == "not-set" ]; then # Patch Values.yaml file cp values.yaml.tmpl values.yaml diff --git a/deploy/kubernetes/console/requirements.lock b/deploy/kubernetes/console/requirements.lock new file mode 100644 index 0000000000..fe6d63559e --- /dev/null +++ b/deploy/kubernetes/console/requirements.lock @@ -0,0 +1,6 @@ +dependencies: +- name: metrics + repository: https://cloudfoundry-incubator.github.io/stratos + version: 2.0.0-metrics-dev +digest: sha256:82dc83e153f6c8115db7c2e0030c9d378bbeaa08bdddad97cf23a559aa9a12c8 +generated: 2018-08-02T11:02:52.066583002+01:00 diff --git a/deploy/kubernetes/console/requirements.yaml b/deploy/kubernetes/console/requirements.yaml new file mode 100644 index 0000000000..a3bd2b288a --- /dev/null +++ b/deploy/kubernetes/console/requirements.yaml @@ -0,0 +1,5 @@ +dependencies: + - name: metrics + version: 2.0.0-metrics-dev + repository: https://cloudfoundry-incubator.github.io/stratos + condition: metrics.enabled diff --git a/deploy/kubernetes/console/templates/deployment.yaml b/deploy/kubernetes/console/templates/deployment.yaml index 246d447628..763db6f481 100644 --- a/deploy/kubernetes/console/templates/deployment.yaml +++ b/deploy/kubernetes/console/templates/deployment.yaml @@ -207,6 +207,10 @@ spec: value: "{{ .Chart.Version }}" - name: HELM_LAST_MODIFIED value: "{{ .Release.Time }}" + - name: SSO_LOGIN + value: {{default "false" .Values.console.ssoLogin | quote}} + - name: SSO_OPTIONS + value: {{default "" .Values.console.ssoOptions | quote}} ports: - containerPort: 3003 name: proxy diff --git a/deploy/kubernetes/console/values.yaml b/deploy/kubernetes/console/values.yaml index 955f29b561..b0b486b050 100644 --- a/deploy/kubernetes/console/values.yaml +++ b/deploy/kubernetes/console/values.yaml @@ -17,6 +17,8 @@ console: cookieDomain: # externalIP: 127.0.0.1 backendLogLevel: info + ssoLogin: false + ssoOptions: images: console: stratos-console proxy: stratos-jetstream @@ -78,4 +80,6 @@ kube: password: email: default services: - loadbalanced: false \ No newline at end of file + loadbalanced: false +metrics: + enabled: false \ No newline at end of file diff --git a/docs/status_updates.md b/docs/status_updates.md index 08eefc0e6d..e18d51c6cc 100644 --- a/docs/status_updates.md +++ b/docs/status_updates.md @@ -2,6 +2,26 @@ Weekly status updates are published here. + +## 31st August 2018 + +Update for this week: + +- Go-backend re-structure - The additional cleanup work has been merged. + +- Single-Sign-On - Further work on Single-Sign On: + - Improvements - improve error handling, add navigate straight to login option [#2522](https://github.com/cloudfoundry-incubator/stratos/pull/2522) + - Link tokens rather than copying them [#2916](https://github.com/cloudfoundry-incubator/stratos/pull/2916) + - Allow a Cloud Foundry endpoint to be connected with SSO login [#2928](https://github.com/cloudfoundry-incubator/stratos/pull/2928) + +- Allow Client ID and Secret to be set when registering an endpoint [#2920](https://github.com/cloudfoundry-incubator/stratos/pull/2920) + +- Scalability: + - Change application list in service instance table row from vertical to chip list [#2915](https://github.com/cloudfoundry-incubator/stratos/pull/2915) + - Convert space apps list from local to remote [#2913](https://github.com/cloudfoundry-incubator/stratos/pull/2913) + +- Metrics - Work has started on tidying up and improving the metrics views + ## 24th August 2018 Update for this week: diff --git a/protractor.conf.js b/protractor.conf.js index 765a3fb99c..e784e474f8 100644 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -35,8 +35,11 @@ try { process.exit(1); } +// This is the maximum amount of time ALL before/after/it's must execute in +const timeout = 40000 + exports.config = { - allScriptsTimeout: 30000, + allScriptsTimeout: timeout, specs: [ './src/test-e2e/**/*-e2e.spec.ts', ], @@ -53,7 +56,7 @@ exports.config = { framework: 'jasmine', jasmineNodeOpts: { showColors: true, - defaultTimeoutInterval: 30000, + defaultTimeoutInterval: timeout, print: function () {} }, params: secrets, diff --git a/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.html b/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.html index 666397b387..0b0a2a5a70 100644 --- a/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.html +++ b/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.html @@ -2,7 +2,7 @@ Selected Users: -
* Not all roles are known for user.
+
* Not all roles are known for user.
diff --git a/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts b/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts index 1be3529e91..2afbcb53a4 100644 --- a/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts +++ b/src/frontend/app/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts @@ -169,6 +169,7 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { } const users$: Observable = this.store.select(selectUsersRolesPicked).pipe( + filter(users => !!users), distinctUntilChanged(), map(users => users.map(this.mapUser.bind(this))) ); @@ -190,9 +191,10 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { private mapUser(user: CfUser): CfUserWithWarning { // If we're at the org level or lower we guarantee org roles. If we're at the space we guarantee space roles. - const showWarning = user.missingRoles && - (user.missingRoles.org.length && !this.activeRouteCfOrgSpace.orgGuid) || - (user.missingRoles.space.length && !this.activeRouteCfOrgSpace.spaceGuid); + + const showWarning = !!user.missingRoles && + ((user.missingRoles.org.length && !this.activeRouteCfOrgSpace.orgGuid) || + (user.missingRoles.space.length && !this.activeRouteCfOrgSpace.spaceGuid)); // Ensure we're in an object where the username is always populated (in some cases it's missing) const newUser = { ...user, diff --git a/src/frontend/app/features/dashboard/side-nav/side-nav.component.ts b/src/frontend/app/features/dashboard/side-nav/side-nav.component.ts index 72ea293333..f3bc3968b4 100644 --- a/src/frontend/app/features/dashboard/side-nav/side-nav.component.ts +++ b/src/frontend/app/features/dashboard/side-nav/side-nav.component.ts @@ -1,8 +1,8 @@ -import {filter, map, buffer, debounceTime} from 'rxjs/operators'; +import { filter, map, buffer, debounceTime } from 'rxjs/operators'; import { Component, Inject, InjectionToken, Input, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { BehaviorSubject , Observable } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { Customizations, CustomizationsMetadata } from '../../../core/customizations.types'; import { ActionHistoryDump } from '../../../store/actions/action-history.actions'; import { AppState } from '../../../store/app-state'; diff --git a/src/frontend/app/features/endpoints/endpoint-helpers.ts b/src/frontend/app/features/endpoints/endpoint-helpers.ts index 0a3f58b46b..43d460173d 100644 --- a/src/frontend/app/features/endpoints/endpoint-helpers.ts +++ b/src/frontend/app/features/endpoints/endpoint-helpers.ts @@ -5,6 +5,10 @@ export function getFullEndpointApiUrl(endpoint: EndpointModel) { return endpoint && endpoint.api_endpoint ? `${endpoint.api_endpoint.Scheme}://${endpoint.api_endpoint.Host}` : 'Unknown'; } +export function getEndpointUsername(endpoint: EndpointModel) { + return endpoint && endpoint.user ? endpoint.user.name : '-'; +} + export const DEFAULT_ENDPOINT_TYPE = 'cf'; export interface EndpointTypeHelper { diff --git a/src/frontend/app/features/service-catalog/services.service.ts b/src/frontend/app/features/service-catalog/services.service.ts index 4c12ee5090..8b1cb08410 100644 --- a/src/frontend/app/features/service-catalog/services.service.ts +++ b/src/frontend/app/features/service-catalog/services.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; -import { combineLatest, filter, first, map, publishReplay, refCount, switchMap, tap } from 'rxjs/operators'; +import { combineLatest, filter, first, map, publishReplay, refCount, switchMap } from 'rxjs/operators'; import { IService, diff --git a/src/frontend/app/features/services/services/services-wall.service.ts b/src/frontend/app/features/services/services/services-wall.service.ts index e7537e7349..72cfdcf6d2 100644 --- a/src/frontend/app/features/services/services/services-wall.service.ts +++ b/src/frontend/app/features/services/services/services-wall.service.ts @@ -4,7 +4,6 @@ import { Observable } from 'rxjs'; import { filter, map, publishReplay, refCount } from 'rxjs/operators'; import { IService } from '../../../core/cf-api-svc.types'; -import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory'; import { GetAllServices } from '../../../store/actions/service.actions'; import { GetServicesForSpace } from '../../../store/actions/space.actions'; diff --git a/src/frontend/app/shared/components/add-service-instance/add-service-instance/add-service-instance.component.ts b/src/frontend/app/shared/components/add-service-instance/add-service-instance/add-service-instance.component.ts index 5280cbe810..e5ad35d822 100644 --- a/src/frontend/app/shared/components/add-service-instance/add-service-instance/add-service-instance.component.ts +++ b/src/frontend/app/shared/components/add-service-instance/add-service-instance/add-service-instance.component.ts @@ -12,13 +12,13 @@ import { getIdFromRoute } from '../../../../features/cloud-foundry/cf.helpers'; import { servicesServiceFactoryProvider } from '../../../../features/service-catalog/service-catalog.helpers'; import { GetApplication } from '../../../../store/actions/application.actions'; import { + ResetCreateServiceInstanceOrgAndSpaceState, ResetCreateServiceInstanceState, SetCreateServiceInstance, SetCreateServiceInstanceCFDetails, SetCreateServiceInstanceServiceGuid, - SetServiceInstanceGuid, - ResetCreateServiceInstanceOrgAndSpaceState, SetCreateServiceInstanceServicePlan, + SetServiceInstanceGuid, } from '../../../../store/actions/create-service-instance.actions'; import { GetServiceInstance } from '../../../../store/actions/service-instances.actions'; import { GetAllAppsInSpace, GetSpace } from '../../../../store/actions/space.actions'; diff --git a/src/frontend/app/shared/components/add-service-instance/create-service-instance-helper.service.ts b/src/frontend/app/shared/components/add-service-instance/create-service-instance-helper.service.ts index ca95250d0a..859ac56d56 100644 --- a/src/frontend/app/shared/components/add-service-instance/create-service-instance-helper.service.ts +++ b/src/frontend/app/shared/components/add-service-instance/create-service-instance-helper.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Inject } from '@angular/core'; +import { Inject } from '@angular/core'; import { Store } from '@ngrx/store'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { filter, first, map, publishReplay, refCount, share, switchMap } from 'rxjs/operators'; @@ -25,13 +25,16 @@ import { spaceSchemaKey, spaceWithOrgKey, } from '../../../store/helpers/entity-factory'; -import { createEntityRelationKey, createEntityRelationPaginationKey } from '../../../store/helpers/entity-relations/entity-relations.types'; +import { + createEntityRelationKey, + createEntityRelationPaginationKey, +} from '../../../store/helpers/entity-relations/entity-relations.types'; import { getPaginationObservables } from '../../../store/reducers/pagination-reducer/pagination-reducer.helper'; import { selectCreateServiceInstanceServicePlan } from '../../../store/selectors/create-service-instance.selectors'; import { APIResource } from '../../../store/types/api.types'; import { QParam } from '../../../store/types/pagination.types'; -import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory'; import { CF_GUID } from '../../entity.tokens'; +import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory'; export class CreateServiceInstanceHelper { servicePlanVisibilities$: Observable[]>; diff --git a/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.html b/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.html index a152cb77de..c930955d41 100644 --- a/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.html +++ b/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.html @@ -12,7 +12,9 @@ diff --git a/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.spec.ts b/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.spec.ts index b6cb7bafca..c4f35c6e89 100644 --- a/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.spec.ts +++ b/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.spec.ts @@ -1,9 +1,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { - generateTestCfEndpointService, BaseTestModulesNoShared, + generateTestCfEndpointService, } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; +import { BooleanIndicatorComponent } from '../../boolean-indicator/boolean-indicator.component'; import { MetadataItemComponent } from '../../metadata-item/metadata-item.component'; import { CardCfInfoComponent } from './card-cf-info.component'; @@ -13,7 +14,7 @@ describe('CardCfInfoComponent', () => { beforeEach( async(() => { TestBed.configureTestingModule({ - declarations: [CardCfInfoComponent, MetadataItemComponent], + declarations: [CardCfInfoComponent, MetadataItemComponent, BooleanIndicatorComponent], imports: [...BaseTestModulesNoShared], providers: [generateTestCfEndpointService()] }).compileComponents(); diff --git a/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.ts b/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.ts index 694808f07f..a4555e8bde 100644 --- a/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.ts +++ b/src/frontend/app/shared/components/cards/card-cf-info/card-cf-info.component.ts @@ -37,10 +37,6 @@ export class CardCfInfoComponent implements OnInit, OnDestroy { return `${apiEndpoint.Scheme}://${apiEndpoint.Host}${path}`; } - isAdmin(user) { - return user && user.admin ? 'Yes' : 'No'; - } - ngOnDestroy(): void { this.subs.forEach(s => s.unsubscribe()); } diff --git a/src/frontend/app/shared/components/list/data-sources-controllers/local-filtering-sorting.ts b/src/frontend/app/shared/components/list/data-sources-controllers/local-filtering-sorting.ts index 7c90014f6f..1b421ebbc1 100644 --- a/src/frontend/app/shared/components/list/data-sources-controllers/local-filtering-sorting.ts +++ b/src/frontend/app/shared/components/list/data-sources-controllers/local-filtering-sorting.ts @@ -95,7 +95,7 @@ function getValue(obj, fieldArray: string[], index = 0, castToString = false): s } return obj; } - if (typeof obj[field] === 'undefined') { + if (!obj[field]) { return ''; } return getValue(obj[field], fieldArray, ++index); diff --git a/src/frontend/app/shared/components/list/list-cards/card/card.component.ts b/src/frontend/app/shared/components/list/list-cards/card/card.component.ts index da7868c227..966a0776bd 100644 --- a/src/frontend/app/shared/components/list/list-cards/card/card.component.ts +++ b/src/frontend/app/shared/components/list/list-cards/card/card.component.ts @@ -25,8 +25,10 @@ import { import { CfServiceCardComponent } from '../../list-types/cf-services/cf-service-card/cf-service-card.component'; import { CfSpaceCardComponent } from '../../list-types/cf-spaces/cf-space-card/cf-space-card.component'; import { CfStacksCardComponent } from '../../list-types/cf-stacks/cf-stacks-card/cf-stacks-card.component'; -import { TableCellCustom, CardCell } from '../../list.types'; -import { ServiceInstanceCardComponent } from '../../list-types/services-wall/service-instance-card/service-instance-card.component'; +import { + ServiceInstanceCardComponent, +} from '../../list-types/services-wall/service-instance-card/service-instance-card.component'; +import { CardCell } from '../../list.types'; export const listCards = [ CardAppComponent, diff --git a/src/frontend/app/shared/components/list/list-table/table-cell/table-cell.component.ts b/src/frontend/app/shared/components/list/list-table/table-cell/table-cell.component.ts index 2d6dabebf7..2b32b1c360 100644 --- a/src/frontend/app/shared/components/list/list-table/table-cell/table-cell.component.ts +++ b/src/frontend/app/shared/components/list/list-table/table-cell/table-cell.component.ts @@ -1,3 +1,6 @@ +import { + TableCellEndpointIsAdminComponent, +} from '../../list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component'; import { Component, ComponentFactoryResolver, @@ -141,7 +144,8 @@ export const listTableCells = [ TableCellRequestMonitorIconComponent, TableCellSpaceNameComponent, TableCellAppCfOrgSpaceHeaderComponent, - TableCellAppCfOrgSpaceComponent + TableCellAppCfOrgSpaceComponent, + TableCellEndpointIsAdminComponent ]; @Component({ diff --git a/src/frontend/app/shared/components/list/list-types/cf-users/cf-permission-cell.ts b/src/frontend/app/shared/components/list/list-types/cf-users/cf-permission-cell.ts index 02d7747d5c..513b609fa7 100644 --- a/src/frontend/app/shared/components/list/list-types/cf-users/cf-permission-cell.ts +++ b/src/frontend/app/shared/components/list/list-types/cf-users/cf-permission-cell.ts @@ -75,17 +75,17 @@ export abstract class CfPermissionCell extends TableCellCustom !can), - switchMap(can => { - if (!can) { + switchMap(hide => { + if (!hide) { if (perm.string === UserRoleLabels.org.short.users) { // If there are other roles than Org User, disable clear button return this.userEntity.pipe( filter(p => !!p), - map((entity: CfUser) => this.cfUserService.hasRolesInOrg(entity, perm.orgGuid)), + map((entity: CfUser) => this.cfUserService.hasRolesInOrg(entity, perm.orgGuid, true)), ); } } - return observableOf(can); + return observableOf(hide); }) ); return chipConfig; diff --git a/src/frontend/app/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts b/src/frontend/app/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts index 52b0aa84ea..185e6fd776 100644 --- a/src/frontend/app/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts +++ b/src/frontend/app/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts @@ -8,7 +8,11 @@ import { CurrentUserPermissionsService } from '../../../../../core/current-user- import { ConnectEndpointDialogComponent, } from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component'; -import { getFullEndpointApiUrl, getNameForEndpointType } from '../../../../../features/endpoints/endpoint-helpers'; +import { + getFullEndpointApiUrl, + getNameForEndpointType, + getEndpointUsername, +} from '../../../../../features/endpoints/endpoint-helpers'; import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../store/actions/endpoint.actions'; import { ShowSnackBar } from '../../../../../store/actions/snackBar.actions'; import { GetSystemInfo } from '../../../../../store/actions/system.actions'; @@ -29,6 +33,7 @@ import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status/t import { map, pairwise } from 'rxjs/operators'; import { combineLatest, Observable } from 'rxjs'; +import { TableCellEndpointIsAdminComponent } from './table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component'; function getEndpointTypeString(endpoint: EndpointModel): string { @@ -71,6 +76,30 @@ export const endpointColumns: ITableColumn[] = [ }, cellFlex: '2' }, + { + columnId: 'username', + headerCell: () => 'Username', + cellDefinition: { + getValue: getEndpointUsername + }, + sort: { + type: 'sort', + orderKey: 'username', + field: 'user.name' + }, + cellFlex: '2' + }, + { + columnId: 'user-type', + headerCell: () => 'Admin', + cellComponent: TableCellEndpointIsAdminComponent, + sort: { + type: 'sort', + orderKey: 'user-type', + field: 'user.admin' + }, + cellFlex: '2' + }, { columnId: 'address', headerCell: () => 'Address', @@ -139,7 +168,7 @@ export class EndpointsListConfigService implements IListConfig { private listActionConnect: IListAction = { action: (item) => { - const dialogRef = this.dialog.open(ConnectEndpointDialogComponent, { + this.dialog.open(ConnectEndpointDialogComponent, { data: { name: item.name, guid: item.guid, diff --git a/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html new file mode 100644 index 0000000000..63aafdd572 --- /dev/null +++ b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html @@ -0,0 +1,3 @@ + + +- diff --git a/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss @@ -0,0 +1 @@ + diff --git a/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts new file mode 100644 index 0000000000..a0404e9707 --- /dev/null +++ b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts @@ -0,0 +1,33 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CoreModule } from '../../../../../../core/core.module'; +import { EndpointModel } from '../../../../../../store/types/endpoint.types'; +import { BooleanIndicatorComponent } from '../../../../boolean-indicator/boolean-indicator.component'; +import { TableCellEndpointIsAdminComponent } from './table-cell-endpoint-is-admin.component'; + + +describe('TableCellEndpointIsAdminComponent', () => { + let component: TableCellEndpointIsAdminComponent<{}>; + let fixture: ComponentFixture>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TableCellEndpointIsAdminComponent, BooleanIndicatorComponent], + imports: [ + CoreModule + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TableCellEndpointIsAdminComponent); + component = fixture.componentInstance; + component.row = {} as EndpointModel; + fixture.detectChanges(); + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts new file mode 100644 index 0000000000..0624a37b3d --- /dev/null +++ b/src/frontend/app/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +import { TableCellCustom } from '../../../list.types'; + +/* tslint:disable:no-access-missing-member https://github.com/mgechev/codelyzer/issues/191*/ +@Component({ + selector: 'app-table-cell-endpoint-is-admin', + templateUrl: './table-cell-endpoint-is-admin.component.html', + styleUrls: ['./table-cell-endpoint-is-admin.component.scss'] +}) +export class TableCellEndpointIsAdminComponent extends TableCellCustom { } diff --git a/src/frontend/app/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.html b/src/frontend/app/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.html index 81492e2307..483a0ddb5a 100644 --- a/src/frontend/app/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.html +++ b/src/frontend/app/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.html @@ -1,6 +1,6 @@ - + -
{{ serviceInstanceEntity?.entity.name }}
+
{{ serviceInstanceEntity.entity.name }}
Space @@ -14,20 +14,20 @@ Service Plan - {{ serviceInstanceEntity?.entity.service_plan?.entity.name}} + {{ serviceInstanceEntity.entity.service_plan?.entity.name}} Applications Attached - {{ serviceInstanceEntity?.entity.service_bindings.length }} + {{ serviceInstanceEntity.entity.service_bindings.length }} Last Updated - {{ serviceInstanceEntity?.entity.last_operation?.updated_at | date:'medium' }} + {{ serviceInstanceEntity.entity.last_operation?.updated_at | date:'medium' }} Dashboard -
+