From 2bf477b08174f5135b370a18bf77409fea4c6682 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Fri, 16 Oct 2020 14:31:15 +0100 Subject: [PATCH 01/16] k8s: Add support for more resource types in a generic way --- .../kubernetes/kubernetes-entity-catalog.ts | 3 + .../kubernetes/kubernetes-entity-factory.ts | 5 +- .../kubernetes/kubernetes-entity-generator.ts | 203 ++++++++++++++++-- .../kubernetes-namespace.component.ts | 33 ++- .../generic-resource.module.ts | 32 +++ .../generic-resource.routing.ts | 14 ++ .../kubernetes-resource-list.component.html | 1 + .../kubernetes-resource-list.component.scss | 0 ...kubernetes-resource-list.component.spec.ts | 25 +++ .../kubernetes-resource-list.component.ts | 29 +++ .../kubernetes-resource-list.ts | 188 ++++++++++++++++ .../kubernetes-tab-base.component.html | 1 + .../kubernetes-tab-base.component.ts | 61 +++++- .../src/kubernetes/kubernetes.routing.ts | 36 +++- .../kube-resource.action-builder.ts | 27 +++ .../kubernetes/store/kube-resource.actions.ts | 80 +++++++ .../src/kubernetes/store/kube.getIds.ts | 35 ++- .../src/kubernetes/store/kube.types.ts | 36 ++++ .../kubernetes/store/kubernetes.actions.ts | 4 +- .../kubernetes/store/kubernetes.effects.ts | 58 +++++ 20 files changed, 834 insertions(+), 37 deletions(-) create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.routing.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts index f90866eebe..6f23dc1022 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts @@ -3,6 +3,7 @@ import { StratosCatalogEntity, } from '../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { IFavoriteMetadata } from '../../../store/src/types/user-favorites.types'; +import { KubeResourceActionBuilders } from './store/action-builders/kube-resource.action-builder'; import { AnalysisReportsActionBuilders, KubeDashboardActionBuilders, @@ -15,6 +16,7 @@ import { } from './store/action-builders/kube.action-builders'; import { AnalysisReport, + KubernetesConfigMap, KubernetesDeployment, KubernetesNamespace, KubernetesNode, @@ -37,6 +39,7 @@ export class KubeEntityCatalog { public service: StratosCatalogEntity; public dashboard: StratosCatalogEntity; public analysisReport: StratosCatalogEntity; + public configMap: StratosCatalogEntity; } /** diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts index 3b82c7d712..05f6848ba5 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts @@ -4,13 +4,13 @@ import { getAPIResourceGuid } from '../../../cloud-foundry/src/store/selectors/a import { EntitySchema } from '../../../store/src/helpers/entity-schema'; import { metricEntityType } from '../../../store/src/helpers/stratos-entity-factory'; import { - getGuidFromKubeDashboardObj, getGuidFromKubeDeploymentObj, getGuidFromKubeNamespaceObj, getGuidFromKubeNodeObj, getGuidFromKubePodObj, getGuidFromKubeServiceObj, getGuidFromKubeStatefulSetObj, + getGuidFromResource, } from './store/kube.getIds'; import { KubernetesApp } from './store/kube.types'; @@ -23,6 +23,7 @@ export const kubernetesStatefulSetsEntityType = 'kubernetesStatefulSet'; export const kubernetesDeploymentsEntityType = 'kubernetesDeployment'; export const kubernetesDashboardEntityType = 'kubernetesDashboard'; export const analysisReportEntityType = 'analysisReport'; +export const kubernetesConfigMapEntityType = 'kubernetesConfigMap'; export const getKubeAppId = (object: KubernetesApp) => object.name; @@ -102,7 +103,7 @@ entityCache[kubernetesServicesEntityType] = new KubernetesEntitySchema( entityCache[kubernetesDashboardEntityType] = new KubernetesEntitySchema( kubernetesDashboardEntityType, {}, - { idAttribute: getGuidFromKubeDashboardObj } + { idAttribute: getGuidFromResource } ); // Analysis Reports - should not be bound to an endpoint diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index 7f5c090d20..b6d8157ce6 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -27,17 +27,24 @@ import { import { KubeConfigRegistrationComponent } from './kube-config-registration/kube-config-registration.component'; import { kubeEntityCatalog } from './kubernetes-entity-catalog'; import { + addKubernetesEntitySchema, analysisReportEntityType, KUBERNETES_ENDPOINT_TYPE, + kubernetesConfigMapEntityType, kubernetesDashboardEntityType, kubernetesDeploymentsEntityType, kubernetesEntityFactory, + KubernetesEntitySchema, kubernetesNamespacesEntityType, kubernetesNodesEntityType, kubernetesPodsEntityType, kubernetesServicesEntityType, kubernetesStatefulSetsEntityType, } from './kubernetes-entity-factory'; +import { + createKubeResourceActionBuilder, + KubeResourceActionBuilders, +} from './store/action-builders/kube-resource.action-builder'; import { AnalysisReportsActionBuilders, analysisReportsActionBuilders, @@ -56,7 +63,11 @@ import { KubeStatefulSetsActionBuilders, kubeStatefulSetsActionBuilders, } from './store/action-builders/kube.action-builders'; +import { getGuidFromKubePodObj } from './store/kube.getIds'; import { + KubeAPIResource, + KubeResourceEntityDefinition, + KubernetesConfigMap, KubernetesDeployment, KubernetesNamespace, KubernetesNode, @@ -136,6 +147,45 @@ const kubeAuthTypeMap: { [type: string]: EndpointAuthTypeConfig, } = { } }; +class KubeResourceEntityHelper { + + constructor(private endpointDefinition: StratosEndpointExtensionDefinition) { } + + public entities: any[] = []; + + public add(defn: KubeResourceEntityDefinition): KubeResourceEntityHelper { + + // Simplify registration by registrtering the schema in the entity cache + addKubernetesEntitySchema(defn.type, new KubernetesEntitySchema(defn.type, {}, { idAttribute: getGuidFromKubePodObj })); + + defn.labelTab = defn.labelTab || defn.labelPlural || `${defn.label}s`; + + if (defn.apiNamespaced !== false) { + defn.apiNamespaced = true; + } + + const d: IStratosEntityDefinition = { + ...defn, + endpoint: this.endpointDefinition, + schema: kubernetesEntityFactory(defn.type), + iconFont: defn.iconFont || 'stratos-icons', + labelPlural: defn.labelPlural || `${defn.label}s` + } + + if (defn.getKubeCatalogEntity) { + console.log(defn); + kubeEntityCatalog[defn.kubeCatalogEntity] = defn.getKubeCatalogEntity(d); + } else { + kubeEntityCatalog[defn.kubeCatalogEntity] = new StratosCatalogEntity(d, { + actionBuilders: createKubeResourceActionBuilder(d.type) + }); + } + + this.entities.push(kubeEntityCatalog[defn.kubeCatalogEntity]); + return this; + } +} + export function generateKubernetesEntities(): StratosBaseCatalogEntity[] { const endpointDefinition: StratosEndpointExtensionDefinition = { type: KUBERNETES_ENDPOINT_TYPE, @@ -201,7 +251,7 @@ export function generateKubernetesEntities(): StratosBaseCatalogEntity[] { return [ generateEndpointEntity(endpointDefinition), generateStatefulSetsEntity(endpointDefinition), - generatePodsEntity(endpointDefinition), + ...generateKubeResourceEntities(endpointDefinition), generateDeploymentsEntity(endpointDefinition), generateNodesEntity(endpointDefinition), generateNamespacesEntity(endpointDefinition), @@ -234,18 +284,6 @@ function generateStatefulSetsEntity(endpointDefinition: StratosEndpointExtension return kubeEntityCatalog.statefulSet; } -function generatePodsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesPodsEntityType, - schema: kubernetesEntityFactory(kubernetesPodsEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.pod = new StratosCatalogEntity(definition, { - actionBuilders: kubePodActionBuilders - }); - return kubeEntityCatalog.pod; -} - function generateDeploymentsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { const definition: IStratosEntityDefinition = { type: kubernetesDeploymentsEntityType, @@ -329,3 +367,142 @@ function generateMetricEntity(endpointDefinition: StratosEndpointExtensionDefini }; return new StratosCatalogEntity(definition); } + +// ============================================================================================================= +// Kubernetes Resources using generic resource pattern +// ============================================================================================================= + +function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensionDefinition) { + + const entities = new KubeResourceEntityHelper(endpointDefinition); + + entities.add({ + type: kubernetesPodsEntityType, + icon: 'pod', + label: 'Pod', + apiVersion: '/api/v1', + apiName: 'pods', + apiNamespaced: true, + kubeCatalogEntity: 'pod', + route: 'pods', + getKubeCatalogEntity: (definition) => new StratosCatalogEntity( + definition, { actionBuilders: kubePodActionBuilders } + ) + }); + + entities.add({ + type: kubernetesConfigMapEntityType, + icon: 'config_maps', + label: 'Config Map', + apiVersion: '/api/v1', + apiName: 'configmaps', + kubeCatalogEntity: 'configMap' + }); + + entities.add({ + type: 'kubernetesSecrets', + icon: 'config_maps', + label: 'Secret', + apiVersion: '/api/v1', + apiName: 'secrets', + kubeCatalogEntity: 'secrets' + }); + + entities.add({ + type: 'kubernetesPersistentVolumeClaims', + icon: 'job', + label: 'Persistent Volume Claim', + labelTab: 'PVCs', + apiVersion: '/api/v1', + apiName: 'persistentvolumeclaims', + kubeCatalogEntity: 'pvcs', + listColumns: [ + { + header: 'Phase', + field: 'status.phase', + sort: true + }, + { + header: 'Capacity', + field: 'status.capacity.storage', + } + ] + }); + + entities.add({ + type: 'kubernetesStorageClass', + icon: 'storage_class', + label: 'Storage Class', + labelPlural: 'Storage Classes', + apiVersion: '/apis/storage.k8s.io/v1', + apiName: 'storageclasses', + apiNamespaced: false, + kubeCatalogEntity: 'storageClass', + listColumns: [ + { + header: 'Provisioner', + field: 'provisioner', + sort: true + }, + { + header: 'Reclaim Policy', + field: 'reclaimPolicy', + sort: true + }, + { + header: 'Binding Mode', + field: 'volumeBindingMode', + sort: true + } + ] + }); + + entities.add({ + type: 'kubernetesPersistentVolume', + icon: 'persistent_volume', + label: 'Persistent Volume', + apiVersion: '/api/v1', + apiName: 'persistentvolumes', + apiNamespaced: false, + kubeCatalogEntity: 'persistentVolumes' + }); + + entities.add({ + type: 'kubernetesReplicaSet', + icon: 'replica_set', + label: 'Replica Set', + apiVersion: '/apis/apps/v1', + apiName: 'replicasets', + kubeCatalogEntity: 'replicaSets' + }); + + entities.add({ + type: 'kubernetesClusterRole', + icon: 'cluster_role', + label: 'Cluster Role', + apiVersion: '/apis/rbac.authorization.k8s.io/v1', + apiName: 'clusterroles', + apiNamespaced: false, + kubeCatalogEntity: 'clusterroles' + }); + + entities.add({ + type: 'kubernetesServiceAccount', + icon: 'replica_set', + label: 'Service Account', + apiVersion: '/api/v1', + apiName: 'serviceaccounts', + kubeCatalogEntity: 'serviceaccounts' + }); + + entities.add({ + type: 'kubernetesRole', + icon: 'role_binding', + label: 'Role', + apiVersion: '/apis/rbac.authorization.k8s.io/v1', + apiName: 'roles', + kubeCatalogEntity: 'role' + }); + + return entities.entities; +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts index 0a7eab7a1e..14e27807eb 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts @@ -4,11 +4,13 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { IHeaderBreadcrumb } from '../../../../core/src/shared/components/page-header/page-header.types'; +import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; import { KubernetesNamespaceService } from '../services/kubernetes-namespace.service'; import { KubernetesAnalysisService } from '../services/kubernetes.analysis.service'; import { KubernetesService } from '../services/kubernetes.service'; +import { KubeResourceEntityDefinition } from '../store/kube.types'; @Component({ selector: 'app-kubernetes-namespace', @@ -53,9 +55,36 @@ export class KubernetesNamespaceComponent { ); this.tabLinks = [ - { link: 'pods', label: 'Pods', icon: 'pod', iconFont: 'stratos-icons' }, - { link: 'services', label: 'Services', icon: 'service', iconFont: 'stratos-icons' }, { link: 'analysis', label: 'Analysis', icon: 'assignment', hidden$: this.analysisService.hideAnalysis$ }, + { link: 'services', label: 'Services', icon: 'service', iconFont: 'stratos-icons' }, ]; + + this.tabLinks.push(...this.getTabsFromEntityConfig(true)); + } + + private getTabsFromEntityConfig(namespaced: boolean = true) { + const entityNames = Object.getOwnPropertyNames(kubeEntityCatalog); + const tabsFromRouterConfig = []; + + // Get the tabs from the router configuration + entityNames.forEach(key => { + // See if we can find an entity for the key + const catalogEntity = kubeEntityCatalog[key]; + if (catalogEntity) { + const defn = catalogEntity.definition as KubeResourceEntityDefinition; + if (defn.apiNamespaced === namespaced) { + tabsFromRouterConfig.push({ + link: defn.route || `resource/${key}`, + label: defn.labelTab || defn.labelPlural, + icon: defn.icon, + iconFont: defn.iconFont, + }); + } + } + }) + + tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); + return tabsFromRouterConfig; } + } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts new file mode 100644 index 0000000000..7015ffd273 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts @@ -0,0 +1,32 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { CoreModule } from '@angular/flex-layout'; + +import { SharedModule } from '../../../../core/src/public-api'; +import { BaseKubeGuid } from '../kubernetes-page.types'; +import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; +import { KubernetesService } from '../services/kubernetes.service'; +import { KubernetesResourceRoutingModule } from './generic-resource.routing'; +import { KubernetesResourceListComponent } from './kubernetes-resource-list/kubernetes-resource-list.component'; + +@NgModule({ + imports: [ + CoreModule, + CommonModule, + SharedModule, + KubernetesResourceRoutingModule, + ], + declarations: [ + KubernetesResourceListComponent, + ], + providers: [ + KubernetesService, + BaseKubeGuid, + KubernetesEndpointService, + ], + exports: [ + KubernetesResourceListComponent, + ] +}) +export class KubernetesGenericResourceModule { } + diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.routing.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.routing.ts new file mode 100644 index 0000000000..36827ebcee --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.routing.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { KubernetesResourceListComponent } from './kubernetes-resource-list/kubernetes-resource-list.component'; + +const genericResource: Routes = [{ + path: '', + component: KubernetesResourceListComponent +}]; + +@NgModule({ + imports: [RouterModule.forChild(genericResource)] +}) +export class KubernetesResourceRoutingModule { } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html new file mode 100644 index 0000000000..dd2b6cb351 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts new file mode 100644 index 0000000000..882339bb62 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { KubernetesResourceListComponent } from './kubernetes-resource-list.component'; + +describe('KubernetesResourceListComponent', () => { + let component: KubernetesResourceListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ KubernetesResourceListComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(KubernetesResourceListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts new file mode 100644 index 0000000000..068616f7a0 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -0,0 +1,29 @@ +import { Component } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { ListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; +import { KubernetesResourceListConfigService } from './kubernetes-resource-list'; + +@Component({ + selector: 'app-kubernetes-resource-list', + template: '', + styleUrls: ['./kubernetes-resource-list.component.scss'], + providers: [{ + provide: ListConfig, + useClass: KubernetesResourceListConfigService, + }] +}) +export class KubernetesResourceListComponent { + + public entityCatalogKey: string; + + constructor(route: ActivatedRoute, router: Router) { + // Entity Catalog Key can be specified in the route config + this.entityCatalogKey = route.snapshot.data.entityCatalogKey; + if (!this.entityCatalogKey) { + // Default is to use the last part of the route + const routeParts = router.url.split('/'); + this.entityCatalogKey = routeParts[routeParts.length - 1]; + } + } +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts new file mode 100644 index 0000000000..1f29469f91 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts @@ -0,0 +1,188 @@ +import { Injectable, Optional } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { + IListDataSource, +} from 'frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types'; +import { of } from 'rxjs'; + +import { ListDataSource } from '../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; +import { + TableCellSidePanelComponent, + TableCellSidePanelConfig, +} from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; +import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; +import { IListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; +import { AppState } from '../../../../../store/src/app-state'; +import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { BaseKubeGuid } from '../../kubernetes-page.types'; +import { + KubernetesResourceViewerComponent, + KubernetesResourceViewerConfig, +} from '../../kubernetes-resource-viewer/kubernetes-resource-viewer.component'; +import { defaultHelmKubeListPageSize } from '../../list-types/kube-helm-list-types'; +import { createKubeAgeColumn } from '../../list-types/kube-list.helper'; +import { KubernetesNamespaceService } from '../../services/kubernetes-namespace.service'; +import { KubeAPIResource, SimpleKubeListColumn } from './../../store/kube.types'; + + +export abstract class KubernetesBaseResourceListConfigService implements IListConfig { + + static namespaceColumnId = 'namespace'; + public showNamespaceLink = true; + + public catalogEntity; any; + + constructor(private kubeId: string) {} + + columns: Array> = [ + // Name + { + columnId: 'name', headerCell: () => 'Name', + cellComponent: TableCellSidePanelComponent, + sort: { + type: 'sort', + orderKey: 'name', + field: 'metadata.name' + }, + cellFlex: '3', + cellConfig: (resource): TableCellSidePanelConfig => { + return ({ + text: resource.metadata.name, + sidePanelComponent: KubernetesResourceViewerComponent, + sidePanelConfig: { + title: resource.metadata.name, + resourceKind: this.catalogEntity.definition.label, + resource$: of(resource) + } + }) + } + }, + // Namespace + { + columnId: KubernetesBaseResourceListConfigService.namespaceColumnId, headerCell: () => 'Namespace', + cellDefinition: { + valuePath: 'metadata.namespace', + getLink: row => this.showNamespaceLink ? `/kubernetes/${this.kubeId}/namespaces/${row.metadata.namespace}` : null + }, + sort: { + type: 'sort', + orderKey: KubernetesBaseResourceListConfigService.namespaceColumnId, + field: 'metadata.namespace' + }, + cellFlex: '2', + }, + ]; + + pageSizeOptions = defaultHelmKubeListPageSize; + viewType = ListViewTypes.TABLE_ONLY; + enableTextFilter = true; + text = { + filter: 'Filter by Name', + noEntries: 'There are no resources' + }; + abstract getDataSource: () => IListDataSource; + + getGlobalActions = () => null; + getMultiActions = () => []; + getSingleActions = () => []; + getColumns = () => this.columns; + getMultiFiltersConfigs = () => []; +} + +class KubernetesResourceDataSource extends ListDataSource { + + constructor( + store: Store, + listConfig: IListConfig, + action: any + ) { + super({ + store, + action, + schema: action.entity[0], + getRowUniqueId: (row) => action.entity[0].getId(row), + paginationKey: action.paginationKey, + isLocal: true, + listConfig, + transformEntities: [{ type: 'filter', field: 'metadata.name' }] + }); + } +} + + +@Injectable() +export class KubernetesResourceListConfigService extends KubernetesBaseResourceListConfigService { + private resourceDataSource: KubernetesResourceDataSource; + + getDataSource = () => this.resourceDataSource; + + constructor( + store: Store, + kubeId: BaseKubeGuid, + route: ActivatedRoute, + router: Router, + @Optional() kubeNamespaceService: KubernetesNamespaceService, + ) { + super(kubeId.guid); + + let entityCatalogKey = route.snapshot.data.entityCatalogKey; + if (!entityCatalogKey) { + // Default is to use the last part of the route + const routeParts = router.url.split('/'); + entityCatalogKey = routeParts[routeParts.length - 1]; + } + + this.catalogEntity = kubeEntityCatalog[entityCatalogKey]; + + let action; + if (!!kubeNamespaceService) { + action = this.catalogEntity.getInNamespace(kubeId.guid, kubeNamespaceService.namespaceName); + } else { + action = this.catalogEntity.actions.getMultiple(kubeId.guid); + } + + // We hide the namespace column if we are in a given namespace OR the resource is not namespaced + let hideNamespaceColumn = !!kubeNamespaceService; + if (this.catalogEntity && this.catalogEntity.definition && this.catalogEntity.definition.apiNamespaced === false) { + hideNamespaceColumn = true; + } + + if (hideNamespaceColumn) { + // Hide the namespace column + this.columns = this.columns.filter(column => column.columnId !== KubernetesBaseResourceListConfigService.namespaceColumnId); + } + + this.resourceDataSource = new KubernetesResourceDataSource(store, this, action); + + if (this.catalogEntity && this.catalogEntity.definition && this.catalogEntity.definition.listColumns) { + this.catalogEntity.definition.listColumns.forEach(c => this.columns.push(this.simpleCellToTableCell(c))); + } + + this.columns.push(createKubeAgeColumn()); + } + + + private simpleCellToTableCell(cell: SimpleKubeListColumn): ITableColumn { + + const tableCell: ITableColumn = { + columnId: cell.header.toLowerCase(), + headerCell: () => cell.header, + cellDefinition: { + valuePath: cell.field + }, + cellFlex: cell.flex || '1' + }; + + if (cell.sort) { + tableCell.sort = { + type: 'sort', + orderKey: tableCell.columnId, + field: cell.field + } + } + + return tableCell; + } +} + diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.html b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.html index ab204d0455..9e26fd3e85 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.html +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.html @@ -3,6 +3,7 @@

{{ (kubeEndpointService.endpoint$ | async)?.entity.name }}

+ \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts index c250a2de07..ab6f275965 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts @@ -9,6 +9,8 @@ import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; import { KubernetesAnalysisService } from '../services/kubernetes.analysis.service'; import { KubernetesService } from '../services/kubernetes.service'; +import { KubeResourceEntityDefinition } from '../store/kube.types'; +import { kubeEntityCatalog } from './../kubernetes-entity-catalog'; @Component({ selector: 'app-kubernetes-tab-base', @@ -43,6 +45,7 @@ export class KubernetesTabBaseComponent implements OnInit { public kubeEndpointService: KubernetesEndpointService, public favoritesConfigMapper: FavoritesConfigMapper, public analysisService: KubernetesAnalysisService, + private route: ActivatedRoute, ) { this.tabLinks = [ { link: 'summary', label: 'Summary', icon: 'kubernetes', iconFont: 'stratos-icons' }, @@ -50,11 +53,66 @@ export class KubernetesTabBaseComponent implements OnInit { { link: '-', label: 'Cluster' }, { link: 'nodes', label: 'Nodes', icon: 'node', iconFont: 'stratos-icons' }, { link: 'namespaces', label: 'Namespaces', icon: 'namespace', iconFont: 'stratos-icons' }, + ...this.getTabsFromEntityConfig(false), { link: '-', label: 'Resources' }, - { link: 'pods', label: 'Pods', icon: 'pod', iconFont: 'stratos-icons' }, + ...this.getTabsFromEntityConfig(true) ]; } + + private getTabsFromEntityConfig(namespaced: boolean = true) { + const entityNames = Object.getOwnPropertyNames(kubeEntityCatalog); + const tabsFromRouterConfig = []; + + // Get the tabs from the router configuration + entityNames.forEach(key => { + // See if we can find an entity for the key + const catalogEntity = kubeEntityCatalog[key]; + if (catalogEntity) { + const defn = catalogEntity.definition as KubeResourceEntityDefinition; + if (defn.apiNamespaced === namespaced) { + tabsFromRouterConfig.push({ + link: defn.route || `resource/${key}`, + label: defn.labelTab || defn.labelPlural, + icon: defn.icon, + iconFont: defn.iconFont, + }); + } + } + }) + + tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); + return tabsFromRouterConfig; + } + + private getTabsFromRouterConfig(namespaced: boolean = true) { + const childRoutes = this.route.snapshot.routeConfig.children; + const tabsFromRouterConfig = []; + + // Get the tabs from the router configuration + childRoutes.forEach( r => { + if (r.path.length > 0) { + // See if we can find an entity for the key + const key = r.data ? (r.data.entityCatalogKey ? r.data.entityCatalogKey : r.path) : r.path; + const catalogEntity = kubeEntityCatalog[key]; + if (catalogEntity) { + const defn = catalogEntity.definition as KubeResourceEntityDefinition; + if (defn.apiNamespaced === namespaced) { + tabsFromRouterConfig.push({ + link: defn.route ? defn.route: `resource/${r.path}`, + label: defn.labelTab || defn.labelPlural, + icon: defn.icon, + iconFont: defn.iconFont, + }); + } + } + } + }) + + tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); + return tabsFromRouterConfig; + } + ngOnInit() { this.isFetching$ = this.kubeEndpointService.endpoint$.pipe( map(endpoint => !endpoint), @@ -68,5 +126,4 @@ export class KubernetesTabBaseComponent implements OnInit { map(endpoint => [endpoint.entity.guid]) ); } - } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts index 35c15386f8..756df65701 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts @@ -1,8 +1,14 @@ -import { KubernetesNamespaceAnalysisReportComponent } from './kubernetes-namespace/kubernetes-namespace-analysis-report/kubernetes-namespace-analysis-report.component'; import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { KubeConsoleComponent } from './kube-terminal/kube-console.component'; +import { + KubedashConfigurationComponent, +} from './kubernetes-dashboard/kubedash-configuration/kubedash-configuration.component'; import { KubernetesDashboardTabComponent } from './kubernetes-dashboard/kubernetes-dashboard.component'; +import { + KubernetesNamespaceAnalysisReportComponent, +} from './kubernetes-namespace/kubernetes-namespace-analysis-report/kubernetes-namespace-analysis-report.component'; import { KubernetesNamespacePodsComponent, } from './kubernetes-namespace/kubernetes-namespace-pods/kubernetes-namespace-pods.component'; @@ -19,17 +25,17 @@ import { KubernetesNodeSummaryComponent, } from './list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-summary.component'; import { PodMetricsComponent } from './pod-metrics/pod-metrics.component'; +import { + KubernetesAnalysisInfoComponent, +} from './tabs/kubernetes-analysis-tab/kubernetes-analysis-info/kubernetes-analysis-info.component'; +import { + KubernetesAnalysisReportComponent, +} from './tabs/kubernetes-analysis-tab/kubernetes-analysis-report/kubernetes-analysis-report.component'; +import { KubernetesAnalysisTabComponent } from './tabs/kubernetes-analysis-tab/kubernetes-analysis-tab.component'; import { KubernetesNamespacesTabComponent } from './tabs/kubernetes-namespaces-tab/kubernetes-namespaces-tab.component'; import { KubernetesNodesTabComponent } from './tabs/kubernetes-nodes-tab/kubernetes-nodes-tab.component'; import { KubernetesPodsTabComponent } from './tabs/kubernetes-pods-tab/kubernetes-pods-tab.component'; import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kubernetes-summary.component'; -import { KubedashConfigurationComponent } from './kubernetes-dashboard/kubedash-configuration/kubedash-configuration.component'; -import { KubeConsoleComponent } from './kube-terminal/kube-console.component'; -import { KubernetesAnalysisTabComponent } from './tabs/kubernetes-analysis-tab/kubernetes-analysis-tab.component'; -import { KubernetesAnalysisReportComponent } from './tabs/kubernetes-analysis-tab/kubernetes-analysis-report/kubernetes-analysis-report.component'; -import { - KubernetesAnalysisInfoComponent -} from './tabs/kubernetes-analysis-tab/kubernetes-analysis-info/kubernetes-analysis-info.component'; const kubernetes: Routes = [{ path: '', @@ -90,7 +96,11 @@ const kubernetes: Routes = [{ { path: 'analysis', component: KubernetesNamespaceAnalysisReportComponent - } + }, + { + path: 'resource/:resource', + loadChildren: () => import('./kubernetes-resource/generic-resource.module').then(m => m.KubernetesGenericResourceModule), + }, ] }, { @@ -116,7 +126,8 @@ const kubernetes: Routes = [{ }, { path: 'pods', - component: KubernetesPodsTabComponent + component: KubernetesPodsTabComponent, + data: { entityCatalogKey: 'pod' } }, { path: 'analysis', @@ -130,6 +141,11 @@ const kubernetes: Routes = [{ path: 'analysis/info', component: KubernetesAnalysisInfoComponent }, + { + path: 'resource/:resource', + loadChildren: () => import('./kubernetes-resource/generic-resource.module').then(m => m.KubernetesGenericResourceModule), + }, + ] }, { diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts new file mode 100644 index 0000000000..e05e629d6c --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts @@ -0,0 +1,27 @@ +import { OrchestratedActionBuilders } from '../../../../../store/src/entity-catalog/action-orchestrator/action-orchestrator'; +import { GetKubernetesResource, GetKubernetesResources, GetKubernetesResourcesInNamespace } from '../kube-resource.actions'; + + +export interface KubeResourceActionBuilders extends OrchestratedActionBuilders { + get: ( + resourceName: string, + kubeGuid: string, + extraArgs: { namespace: string } + ) => GetKubernetesResource, + getMultiple: ( + kubeGuid: string, + paginationKey?: string, + ) => GetKubernetesResources, + getInNamespace: ( + kubeGuid: string, + namespace: string + ) => GetKubernetesResourcesInNamespace +} + +export function createKubeResourceActionBuilder(entityType: string): KubeResourceActionBuilders { + return { + get: (resName: string, kubeGuid: string, { namespace }) => new GetKubernetesResource(entityType, resName, namespace, kubeGuid), + getMultiple: (kubeGuid: string, paginationKey?: string) => new GetKubernetesResources(entityType, kubeGuid), + getInNamespace: (kubeGuid: string, namespace: string) => new GetKubernetesResourcesInNamespace(entityType, kubeGuid, namespace), + }; +} \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts new file mode 100644 index 0000000000..31bc183cfa --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts @@ -0,0 +1,80 @@ +import { SortDirection } from '@angular/material/sort'; + +import { getPaginationKey } from '../../../../store/src/actions/pagination.actions'; +import { PaginationParam } from '../../../../store/src/types/pagination.types'; +import { KUBERNETES_ENDPOINT_TYPE, kubernetesEntityFactory } from '../kubernetes-entity-factory'; +import { getGuidFromKubePod } from './kube.getIds'; +import { KubePaginationAction, KubeSingleEntityAction } from './kubernetes.actions'; + + +export const GET_KUBE_RESOURCES = '[KUBERNETES Endpoint] Get Resources'; +export const GET_KUBE_RESOURCES_SUCCESS = '[KUBERNETES Endpoint] Get Resources Success'; +export const GET_KUBE_RESOURCES_FAILURE = '[KUBERNETES Endpoint] Get Resources Failure'; + +export const GET_KUBE_RESOURCE = '[KUBERNETES Endpoint] Get Resource'; +export const GET_KUBE_RESOURCE_SUCCESS = '[KUBERNETES Endpoint] Get Resource Success'; +export const GET_KUBE_RESOURCE_FAILURE = '[KUBERNETES Endpoint] Get Resource Failure'; + +export const GET_KUBE_RESOURCES_IN_NAMESPACE = '[KUBERNETES Endpoint] Get Resources in namespace'; +export const GET_KUBE_RESOURCES_IN_NAMESPACE_SUCCESS = '[KUBERNETES Endpoint] Get Resources in namespace Success'; +export const GET_KUBE_RESOURCES_IN_NAMESPACE_FAILURE = '[KUBERNETES Endpoint] Get Resources in namespace Failure'; + + +const defaultSortParams = { + 'order-direction': 'desc' as SortDirection, + 'order-direction-field': 'name' +}; + +export class GetKubernetesResource implements KubeSingleEntityAction { + + public entity; + + constructor(public entityType: string, public podName: string, public namespaceName: string, public kubeGuid: string) { + this.guid = getGuidFromKubePod(kubeGuid, namespaceName, podName); + this.entity = [kubernetesEntityFactory(entityType)]; + } + type = GET_KUBE_RESOURCE; + endpointType = KUBERNETES_ENDPOINT_TYPE; + actions = [ + GET_KUBE_RESOURCE, + GET_KUBE_RESOURCE_SUCCESS, + GET_KUBE_RESOURCE_FAILURE + ]; + guid: string; +} + +export class GetKubernetesResources implements KubePaginationAction { + + public entity; + + constructor(public entityType: string, public kubeGuid: string) { + this.paginationKey = getPaginationKey(entityType, 'k8s', kubeGuid); + this.entity = [kubernetesEntityFactory(entityType)] + } + type = GET_KUBE_RESOURCES; + endpointType = KUBERNETES_ENDPOINT_TYPE; + actions = [ + GET_KUBE_RESOURCES, + GET_KUBE_RESOURCES_SUCCESS, + GET_KUBE_RESOURCES_FAILURE + ]; + paginationKey: string; + initialParams: PaginationParam = { + ...defaultSortParams + }; + flattenPagination = true; +} + + +export class GetKubernetesResourcesInNamespace extends GetKubernetesResources { + constructor(entityType: string, kubeGuid: string, public namespaceName: string) { + super(entityType, kubeGuid); + this.paginationKey = getPaginationKey(entityType, `ns-${namespaceName}`, kubeGuid); + } + type = GET_KUBE_RESOURCES_IN_NAMESPACE; + actions = [ + GET_KUBE_RESOURCES_IN_NAMESPACE, + GET_KUBE_RESOURCES_IN_NAMESPACE_SUCCESS, + GET_KUBE_RESOURCES_IN_NAMESPACE_FAILURE + ]; +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts index 256d39ca39..903d705f97 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts @@ -8,7 +8,6 @@ import { KubernetesStatefulSet, KubeService, } from './kube.types'; -import { KubeDashboardStatus } from './kubernetes.effects'; const deliminate = (...args: string[]) => args.join('_:_'); @@ -20,8 +19,35 @@ const debugMissingKubeId = (entity: BasicKubeAPIResource, func: (...args: string }; export const getGuidFromKubeNode = (kubeGuid: string, name: string): string => deliminate(name, kubeGuid); -export const getGuidFromKubeNodeObj = (entity: KubernetesNode): string => - debugMissingKubeId(entity, getGuidFromKubeNode, entity.metadata.kubeId, entity.metadata.name); + +export const getGuidForResource = (kubeGuid: string, name: string): string => deliminate(name, kubeGuid); +export const getGuidForNamespacedResource = (kubeGuid: string, namespace: string, name: string): string => + deliminate(name, namespace, kubeGuid); + +/** + * Get the ID for a Kubernetes Resource + */ +export const getGuidFromResource = (entity: BasicKubeAPIResource): string => { + + // Resource with namespace + if (entity.metadata.namespace) { + return deliminate(entity.metadata.kubeId, entity.metadata.namespace, entity.metadata.name) + } + + // Named resource (no namespace) + if (entity.metadata.name) { + return deliminate(entity.metadata.kubeId, entity.metadata.name); + } + + // Cluster-level resource (e.g. Kubernetes dashboard) + return entity.metadata.kubeId; +} + +// ====================================================================================================================================== +// LEGACY - Remove those not needed +// ====================================================================================================================================== + +export const getGuidFromKubeNodeObj = (entity: KubernetesNode): string => getGuidFromResource(entity); export const getGuidFromKubeNamespace = (kubeGuid: string, name: string): string => deliminate(name, kubeGuid); export const getGuidFromKubeNamespaceObj = (entity: KubernetesNamespace): string => @@ -44,6 +70,3 @@ export const getGuidFromKubeDeploymentObj = (entity: KubernetesDeployment): stri export const getGuidFromKubePod = (kubeGuid: string, namespace: string, name: string): string => deliminate(name, namespace, kubeGuid); export const getGuidFromKubePodObj = (entity: KubernetesPod): string => debugMissingKubeId(entity, getGuidFromKubePod, entity.metadata.kubeId, entity.metadata.namespace, entity.metadata.name); - -export const getGuidFromKubeDashboard = (kubeGuid: string): string => kubeGuid; -export const getGuidFromKubeDashboardObj = (entity: KubeDashboardStatus): string => getGuidFromKubeDashboard(entity.kubeGuid); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts index 9192f7014c..7dcf496af9 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts @@ -1,3 +1,5 @@ +import { StratosCatalogEntity } from '../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { IStratosEntityDefinition } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { KubernetesPodExpandedStatus } from '../services/kubernetes-expanded-state'; export interface KubernetesInfo { @@ -23,6 +25,28 @@ export interface KubeAPIResource extends BasicKubeAPIResource { spec: any; } +export interface IKubeResourceEntityDefinition extends IStratosEntityDefinition { + apiVersion: string; + apiName: string; + apiNamespaced: boolean; +} + +export interface KubeResourceEntityDefinition { + apiVersion: string; + apiName: string; + apiNamespaced?: boolean; + label: string; + labelPlural?: string; + labelTab?: string; + icon: string; + iconFont?: string; + type: string; + kubeCatalogEntity: string; + getKubeCatalogEntity?: (IStratosEntityDefinition) => StratosCatalogEntity, + route?: string; + listColumns?: SimpleKubeListColumn[]; +} + export interface KubeService extends BasicKubeAPIResource { metadata: KubeServiceMetadata; status: ServiceStatus; @@ -517,3 +541,15 @@ export interface AnalysisReport { report?: any; title?: string; } + + +export interface KubernetesConfigMap extends BasicKubeAPIResource { + test?: string; +} + +export interface SimpleKubeListColumn { + field: string; + header: string; + flex?: string; + sort?: boolean; +} \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts index ebba3d6dca..39e066e6e2 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts @@ -17,7 +17,7 @@ import { kubernetesServicesEntityType, kubernetesStatefulSetsEntityType, } from '../kubernetes-entity-factory'; -import { getGuidFromKubeDashboard, getGuidFromKubeNamespace, getGuidFromKubeNode, getGuidFromKubePod } from './kube.getIds'; +import { getGuidFromKubeNamespace, getGuidFromKubeNode, getGuidFromKubePod } from './kube.getIds'; export const GET_RELEASE_POD_INFO = '[KUBERNETES Endpoint] Get Release Pods Info'; export const GET_RELEASE_POD_INFO_SUCCESS = '[KUBERNETES Endpoint] Get Release Pods Info Success'; @@ -325,7 +325,7 @@ export class GeKubernetesDeployments implements KubePaginationAction { export class GetKubernetesDashboard implements KubeSingleEntityAction { constructor(public kubeGuid: string) { - this.guid = getGuidFromKubeDashboard(kubeGuid); + this.guid = kubeGuid; } type = GET_KUBE_DASHBOARD; entityType = kubernetesDashboardEntityType; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts index a430bc9bb1..491f2dd5ad 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts @@ -18,8 +18,16 @@ import { kubernetesPodsEntityType, } from '../kubernetes-entity-factory'; import { KubernetesPodExpandedStatusHelper } from '../services/kubernetes-expanded-state'; +import { + GET_KUBE_RESOURCES, + GET_KUBE_RESOURCES_IN_NAMESPACE, + GetKubernetesResources, + GetKubernetesResourcesInNamespace, +} from './kube-resource.actions'; import { BasicKubeAPIResource, + IKubeResourceEntityDefinition, + KubeAPIResource, KubernetesDeployment, KubernetesNamespace, KubernetesNode, @@ -68,6 +76,9 @@ export interface KubeDashboardContainer { export interface KubeDashboardStatus { guid: string; kubeGuid: string; + metadata?: { + kubeId: string; + } installed: boolean; stratosInstalled: boolean; running: boolean; @@ -111,6 +122,9 @@ export class KubernetesEffects { } as NormalizedResponse; const status = response as KubeDashboardStatus; status.kubeGuid = action.kubeGuid; + status.metadata = { + kubeId: action.kubeGuid + }; result.entities[dashboardEntityConfig.entityKey][action.guid] = status; result.result.push(action.guid); return [ @@ -254,6 +268,50 @@ export class KubernetesEffects { )) ); + // ======================================================================================= + // Generic resource effects + // ======================================================================================= + + @Effect() + fetchKubeResources$ = this.actions$.pipe( + ofType(GET_KUBE_RESOURCES), + flatMap((action: GetKubernetesResources)=> { + const catalog = entityCatalog.getEntity(action.endpointType, action.entityType); + if (catalog && catalog.definition) { + const defn = catalog.definition as IKubeResourceEntityDefinition; + if (defn.apiVersion && defn.apiName) { + return this.processListAction( + action, + `/pp/${this.proxyAPIVersion}/proxy/${defn.apiVersion}/${defn.apiName}` + ); + } + } + + throw new Error('Kubernetes Resource request - but no API information is available'); + }) + ); + + @Effect() + fetchKubeResourcesInNamespace$ = this.actions$.pipe( + ofType(GET_KUBE_RESOURCES_IN_NAMESPACE), + flatMap((action: GetKubernetesResourcesInNamespace)=> { + const catalog = entityCatalog.getEntity(action.endpointType, action.entityType); + if (catalog && catalog.definition) { + const defn = catalog.definition as IKubeResourceEntityDefinition; + if (defn.apiVersion && defn.apiName) { + return this.processListAction( + action, + `/pp/${this.proxyAPIVersion}/proxy/${defn.apiVersion}/namespaces/${action.namespaceName}/${defn.apiName}` + ); + } + } + + throw new Error('Kubernetes Resource request - but no API information is available'); + }) + ); + + // ======================================================================================= + private processNodeAction(action: GetKubernetesNodes) { return this.processListAction( action, From 08dee986ba113518f8d66f578a40cc697467c58d Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 11 Nov 2020 14:01:41 +0000 Subject: [PATCH 02/16] Unit test fix --- ...kubernetes-resource-list.component.spec.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts index 882339bb62..3f41a59cdf 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts @@ -1,4 +1,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { KubernetesResourceListComponent } from './kubernetes-resource-list.component'; @@ -8,7 +10,24 @@ describe('KubernetesResourceListComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ KubernetesResourceListComponent ] + declarations: [ KubernetesResourceListComponent ], + imports: [ RouterTestingModule ], + providers: [ + { + provide: ActivatedRoute, + useValue: { + snapshot: { + data: { + entityCatalogKey: 'test' + }, + params: { + endpointId: 'anything' + }, + queryParams: {} + } + } + } +] }) .compileComponents(); })); From 3ab1796b5759acfff42d1ae7597653aa067c1051 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Tue, 17 Nov 2020 13:08:46 +0000 Subject: [PATCH 03/16] WIP --- .../list-view/list-view.component.ts | 30 +-- .../kubernetes/kubernetes-entity-generator.ts | 33 ++- .../src/kubernetes/kubernetes-list-service.ts | 27 +++ .../generic-resource.module.ts | 2 + .../kubernetes-resource-list.component.html | 16 +- .../kubernetes-resource-list.component.scss | 36 +++ .../kubernetes-resource-list.component.ts | 207 +++++++++++++++++- .../kubernetes-tab-base.component.ts | 10 +- .../src/kubernetes/kubernetes.module.ts | 9 +- .../src/kubernetes/kubernetes.setup.module.ts | 2 + .../src/kubernetes/kubernetes.store.module.ts | 4 +- ...etes-namespace-pods-list-config.service.ts | 4 +- ...ubernetes-node-pods-list-config.service.ts | 4 +- .../kubernetes-pods-list-config.service.ts | 21 +- .../src/kubernetes/store/kube.types.ts | 11 +- .../kubernetes/store/kubernetes.actions.ts | 8 + .../kubernetes/store/kubernetes.reducers.ts | 26 +++ .../helm-release-pods-list-config.service.ts | 5 +- 18 files changed, 403 insertions(+), 52 deletions(-) create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts create mode 100644 src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.reducers.ts diff --git a/src/frontend/packages/core/src/shared/components/list/list-generics/list-view/list-view.component.ts b/src/frontend/packages/core/src/shared/components/list/list-generics/list-view/list-view.component.ts index 9438e7ad30..fea74610ae 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-generics/list-view/list-view.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-generics/list-view/list-view.component.ts @@ -1,4 +1,4 @@ -import { Component, ComponentFactoryResolver, ComponentRef, Injector, Input, OnInit, ViewChild } from '@angular/core'; +import { Component, ComponentFactoryResolver, ComponentRef, Injector, Input, OnDestroy, ViewChild } from '@angular/core'; import { ListComponent } from '../../list.component'; import { IListConfig, ListConfig } from '../../list.component.types'; @@ -13,9 +13,13 @@ import { ListConfigProvider } from '../list-config-provider.types'; ListComponent ] }) -export class ListViewComponent implements OnInit { +export class ListViewComponent implements OnDestroy { - @Input() config: ListConfigProvider; + @Input() set config(config: ListConfigProvider) { + if (config) { + this.create(config); + } + } @ViewChild(ListHostDirective, { static: true }) public listHost: ListHostDirective; @@ -27,15 +31,22 @@ export class ListViewComponent implements OnInit { private injector: Injector ) { } - ngOnInit() { + ngOnDestroy() { + if (this.componentRef) { + this.componentRef.destroy(); + } + } - const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ListComponent); + create(listConfig: ListConfigProvider) { + // Clean up old component + this.ngOnDestroy(); + const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ListComponent); const viewContainerRef = this.listHost.viewContainerRef; this.componentRef = viewContainerRef.createComponent( componentFactory, null, - this.makeCustomConfigInjector(this.config.getListConfig()) + this.makeCustomConfigInjector(listConfig.getListConfig()) ); } @@ -45,11 +56,4 @@ export class ListViewComponent implements OnInit { parent: this.injector }); } - - ngDestroy() { - if (this.componentRef) { - this.componentRef.destroy(); - } - } - } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index cb8da9018a..2bebceb515 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -197,7 +197,7 @@ class KubeResourceEntityHelper { schema: kubernetesEntityFactory(defn.type), iconFont: defn.iconFont || 'stratos-icons', labelPlural: defn.labelPlural || `${defn.label}s` - } + }; if (defn.getKubeCatalogEntity) { console.log(defn); @@ -292,7 +292,7 @@ export function generateKubernetesEntities(): StratosBaseCatalogEntity[] { ...generateKubeResourceEntities(endpointDefinition), generateDeploymentsEntity(endpointDefinition), generateNodesEntity(endpointDefinition), - generateNamespacesEntity(endpointDefinition), + // generateNamespacesEntity(endpointDefinition), generateServicesEntity(endpointDefinition), generateDashboardEntity(endpointDefinition), generateAnalysisReportsEntity(endpointDefinition), @@ -368,7 +368,7 @@ function generateNamespacesEntity(endpointDefinition: StratosEndpointExtensionDe name: namespace.metadata.name, }; }, - getLink: metadata => `/kubernetes/${metadata.kubeGuid}/namespaces/${metadata.name}y`, + getLink: metadata => `/kubernetes/${metadata.kubeGuid}/namespaces/${metadata.name}`, getGuid: metadata => metadata.guid, } }); @@ -433,7 +433,9 @@ function getFavoriteFromKubeEntity( entity.kubeGuid, entity ); - +} + + // ============================================================================================================= // Kubernetes Resources using generic resource pattern // ============================================================================================================= @@ -442,6 +444,27 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi const entities = new KubeResourceEntityHelper(endpointDefinition); + entities.add({ + type: kubernetesNamespacesEntityType, + icon: 'namespace', + label: 'Namespace', + apiVersion: '/api/v1', + apiName: 'namespaces', + apiNamespaced: false, + kubeCatalogEntity: 'namespace', + hidden: true, + getKubeCatalogEntity: (definition) => new StratosCatalogEntity( + definition, { actionBuilders: kubeNamespaceActionBuilders } + ), + listColumns: [ + { + header: 'Status', + field: 'status.phase', + sort: true + } + ] + }); + entities.add({ type: kubernetesPodsEntityType, icon: 'pod', @@ -450,7 +473,7 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi apiName: 'pods', apiNamespaced: true, kubeCatalogEntity: 'pod', - route: 'pods', + // route: 'pods', getKubeCatalogEntity: (definition) => new StratosCatalogEntity( definition, { actionBuilders: kubePodActionBuilders } ) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts new file mode 100644 index 0000000000..e18e6b1257 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; + +import { IListConfig } from '../../../core/src/shared/components/list/list.component.types'; + +interface KubernetesListConfig { + [name: string]: IListConfig; +} + +// Holder for list configurations +// This allows us to reference them by name and lazy-load the configs yet reference them +// in an entity defintion that may not have been laz-loaded + +@Injectable({ + providedIn: 'root', +}) +export class KubernetesListConfigService { + + private configs: KubernetesListConfig = {}; + + set(name: string, config: IListConfig) { + this.configs[name] = config; + } + + get(name: string): IListConfig { + return this.configs[name]; + } +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts index 7015ffd273..6f1a7d5297 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/generic-resource.module.ts @@ -6,12 +6,14 @@ import { SharedModule } from '../../../../core/src/public-api'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; import { KubernetesService } from '../services/kubernetes.service'; +import { MDAppModule } from './../../../../core/src/core/md.module'; import { KubernetesResourceRoutingModule } from './generic-resource.routing'; import { KubernetesResourceListComponent } from './kubernetes-resource-list/kubernetes-resource-list.component'; @NgModule({ imports: [ CoreModule, + MDAppModule, CommonModule, SharedModule, KubernetesResourceRoutingModule, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html index dd2b6cb351..86e4d2f939 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.html @@ -1 +1,15 @@ - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss index e69de29bb2..a5fd29f8ad 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.scss @@ -0,0 +1,36 @@ +.sub-nav-menu-button { + border: 1px solid #777; + border-radius: 5px; + margin-left: 20px; + width: 200px; + + &__btn { + line-height: 28px; + padding: 0 8px 0 12px; + width: 100%; + + .mat-button-wrapper { + display: flex; + justify-content: flex-start; + } + } + &__label { + flex: 1; + overflow: hidden; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; + } + &__arrow { + margin: 0; + margin-Left: 10px; + } + &__not-allowed { + opacity: 0.5 + } +} + +.menu { + max-height: 400px; + width: 180px; +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index 068616f7a0..b64d757c59 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -1,23 +1,64 @@ -import { Component } from '@angular/core'; +import { Component, OnDestroy } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { Observable, of, Subscription } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; -import { ListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; -import { KubernetesResourceListConfigService } from './kubernetes-resource-list'; +import { + ActionListConfigProvider, +} from '../../../../../core/src/shared/components/list/list-generics/list-providers/action-list-config-provider'; +import { + TableCellSidePanelComponent, + TableCellSidePanelConfig, +} from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; +import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; +import { ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; +import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { KubernetesListConfigService } from '../../kubernetes-list-service'; +import { BaseKubeGuid } from '../../kubernetes-page.types'; +import { + KubernetesResourceViewerComponent, + KubernetesResourceViewerConfig, +} from '../../kubernetes-resource-viewer/kubernetes-resource-viewer.component'; +import { defaultHelmKubeListPageSize } from '../../list-types/kube-helm-list-types'; +import { createKubeAgeColumn } from '../../list-types/kube-list.helper'; +import { + KubeAPIResource, + KubeResourceEntityDefinition, + KubernetesCurrentNamespace, + SimpleKubeListColumn, +} from '../../store/kube.types'; +import { SetCurrentNamespaceAction } from './../../store/kubernetes.actions'; +import { KubernetesBaseResourceListConfigService } from './kubernetes-resource-list'; @Component({ selector: 'app-kubernetes-resource-list', - template: '', + templateUrl: './kubernetes-resource-list.component.html', styleUrls: ['./kubernetes-resource-list.component.scss'], - providers: [{ - provide: ListConfig, - useClass: KubernetesResourceListConfigService, - }] }) -export class KubernetesResourceListComponent { +export class KubernetesResourceListComponent implements OnDestroy { public entityCatalogKey: string; - constructor(route: ActivatedRoute, router: Router) { + public namespaces$: Observable; + + selectedNamespace: string; + + public showNamespaceLink = true; + + public provider: ActionListConfigProvider; + + public isNamespacedView = true; + + private sub: Subscription; + + constructor( + private store: Store, + route: ActivatedRoute, + router: Router, + private kubeId: BaseKubeGuid, + private listConfigService: KubernetesListConfigService + ) { // Entity Catalog Key can be specified in the route config this.entityCatalogKey = route.snapshot.data.entityCatalogKey; if (!this.entityCatalogKey) { @@ -25,5 +66,151 @@ export class KubernetesResourceListComponent { const routeParts = router.url.split('/'); this.entityCatalogKey = routeParts[routeParts.length - 1]; } + + const namespacesObs = kubeEntityCatalog.namespace.store.getPaginationService(kubeId.guid); + this.namespaces$ = namespacesObs.entities$.pipe(map(ns => ns.map(n => n.metadata.name))); + + this.createProvider(); + + // Watch for namespace changes + this.sub = this.store.select(state => state.k8sCurrentNamespace).pipe( + map(data => data[this.kubeId.guid]), + filter(data => !!data) + ).subscribe(ns => { + this.selectedNamespace = ns === '*' ? undefined : ns; + if (this.isNamespacedView) { + this.createProvider(); + } + }); + } + + ngOnDestroy() { + if (this.sub) { + this.sub.unsubscribe(); + } + } + + private createProvider() { + const catalogEntity = kubeEntityCatalog[this.entityCatalogKey]; + if (!catalogEntity) { + console.error(`Can not find catalog entity for Kubernetes entity ${this.entityCatalogKey}`); + return; + } + this.isNamespacedView = !!catalogEntity.definition.apiNamespaced; + let action; + if (this.selectedNamespace && this.isNamespacedView) { + action = catalogEntity.actions.getInNamespace(this.kubeId.guid, this.selectedNamespace); + } else { + action = catalogEntity.actions.getMultiple(this.kubeId.guid); + } + const provider = new ActionListConfigProvider(this.store, action); + + console.log(this.entityCatalogKey); + let listConfig: any = this.listConfigService.get(this.entityCatalogKey); + console.log(listConfig); + if (!listConfig) { + listConfig = { + pageSizeOptions: defaultHelmKubeListPageSize, + viewType: ListViewTypes.TABLE_ONLY, + enableTextFilter: true, + text: { + title: null, + filter: 'Filter by Name', + noEntries: 'There are no resources' + }, + getColumns: () => this.getColumns(catalogEntity.definition) + }; + } + + provider.updateListConfig(listConfig); + + this.provider = provider; + } + + select(item?: string) { + this.store.dispatch(new SetCurrentNamespaceAction(this.kubeId.guid, item)); + } + + private getColumns(definition: KubeResourceEntityDefinition): ITableColumn[] { + let columns: Array> = [ + // Name + { + columnId: 'name', headerCell: () => 'Name', + cellComponent: TableCellSidePanelComponent, + sort: { + type: 'sort', + orderKey: 'name', + field: 'metadata.name' + }, + cellFlex: '3', + cellConfig: (resource): TableCellSidePanelConfig => { + return ({ + text: resource.metadata.name, + sidePanelComponent: KubernetesResourceViewerComponent, + sidePanelConfig: { + title: resource.metadata.name, + resourceKind: definition.label, + resource$: of(resource) + } + }); + } + }, + // Namespace + { + columnId: KubernetesBaseResourceListConfigService.namespaceColumnId, headerCell: () => 'Namespace', + cellDefinition: { + valuePath: 'metadata.namespace', + getLink: row => this.showNamespaceLink ? `/kubernetes/${this.kubeId}/namespaces/${row.metadata.namespace}` : null + }, + sort: { + type: 'sort', + orderKey: KubernetesBaseResourceListConfigService.namespaceColumnId, + field: 'metadata.namespace' + }, + cellFlex: '2', + }, + ]; + + // We hide the namespace column if we are in a given namespace OR the resource is not namespaced + // let hideNamespaceColumn = !!this.selectedNamespace; + let hideNamespaceColumn = false; + if (definition && definition.apiNamespaced === false) { + hideNamespaceColumn = true; + } + + if (hideNamespaceColumn) { + // Hide the namespace column + columns = columns.filter(column => column.columnId !== KubernetesBaseResourceListConfigService.namespaceColumnId); + } + + if (definition && definition.listColumns) { + definition.listColumns.forEach(c => columns.push(this.simpleCellToTableCell(c))); + } + + columns.push(createKubeAgeColumn()); + + return columns; + } + + private simpleCellToTableCell(cell: SimpleKubeListColumn): ITableColumn { + + const tableCell: ITableColumn = { + columnId: cell.header.toLowerCase(), + headerCell: () => cell.header, + cellDefinition: { + valuePath: cell.field + }, + cellFlex: cell.flex || '1' + }; + + if (cell.sort) { + tableCell.sort = { + type: 'sort', + orderKey: tableCell.columnId, + field: cell.field + }; + } + + return tableCell; } } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts index ab6f275965..d53ef4cd36 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts @@ -52,7 +52,7 @@ export class KubernetesTabBaseComponent implements OnInit { { link: 'analysis', label: 'Analysis', icon: 'assignment', hidden$: this.analysisService.hideAnalysis$ }, { link: '-', label: 'Cluster' }, { link: 'nodes', label: 'Nodes', icon: 'node', iconFont: 'stratos-icons' }, - { link: 'namespaces', label: 'Namespaces', icon: 'namespace', iconFont: 'stratos-icons' }, + { link: 'resource/namespace', label: 'Namespaces', icon: 'namespace', iconFont: 'stratos-icons' }, ...this.getTabsFromEntityConfig(false), { link: '-', label: 'Resources' }, ...this.getTabsFromEntityConfig(true) @@ -70,7 +70,7 @@ export class KubernetesTabBaseComponent implements OnInit { const catalogEntity = kubeEntityCatalog[key]; if (catalogEntity) { const defn = catalogEntity.definition as KubeResourceEntityDefinition; - if (defn.apiNamespaced === namespaced) { + if (defn.apiNamespaced === namespaced && !defn.hidden) { tabsFromRouterConfig.push({ link: defn.route || `resource/${key}`, label: defn.labelTab || defn.labelPlural, @@ -79,7 +79,7 @@ export class KubernetesTabBaseComponent implements OnInit { }); } } - }) + }); tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); return tabsFromRouterConfig; @@ -99,7 +99,7 @@ export class KubernetesTabBaseComponent implements OnInit { const defn = catalogEntity.definition as KubeResourceEntityDefinition; if (defn.apiNamespaced === namespaced) { tabsFromRouterConfig.push({ - link: defn.route ? defn.route: `resource/${r.path}`, + link: defn.route ? defn.route : `resource/${r.path}`, label: defn.labelTab || defn.labelPlural, icon: defn.icon, iconFont: defn.iconFont, @@ -107,7 +107,7 @@ export class KubernetesTabBaseComponent implements OnInit { } } } - }) + }); tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); return tabsFromRouterConfig; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts index 2ee5760928..06e953f636 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts @@ -26,6 +26,7 @@ import { KubedashConfigurationComponent, } from './kubernetes-dashboard/kubedash-configuration/kubedash-configuration.component'; import { KubernetesDashboardTabComponent } from './kubernetes-dashboard/kubernetes-dashboard.component'; +import { KubernetesListConfigService } from './kubernetes-list-service'; import { KubernetesNamespaceAnalysisReportComponent, } from './kubernetes-namespace/kubernetes-namespace-analysis-report/kubernetes-namespace-analysis-report.component'; @@ -101,6 +102,7 @@ import { KubernetesPodStatusComponent, } from './list-types/kubernetes-pods/kubernetes-pod-status/kubernetes-pod-status.component'; import { KubernetesPodTagsComponent } from './list-types/kubernetes-pods/kubernetes-pod-tags/kubernetes-pod-tags.component'; +import { KubernetesPodsListConfig } from './list-types/kubernetes-pods/kubernetes-pods-list-config.service'; import { KubernetesServicePortsComponent } from './list-types/kubernetes-service-ports/kubernetes-service-ports.component'; import { KubeServiceCardComponent, @@ -234,5 +236,10 @@ import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kub AnalysisStatusCellComponent, ] }) -export class KubernetesModule { } +export class KubernetesModule { + + constructor(listConfigService: KubernetesListConfigService) { + listConfigService.set('pods', new KubernetesPodsListConfig()); + } +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts index ab0a527eec..5945118c8f 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts @@ -43,6 +43,7 @@ import { import { kubeEntityCatalog } from './kubernetes-entity-catalog'; import { KUBERNETES_ENDPOINT_TYPE } from './kubernetes-entity-factory'; import { generateKubernetesEntities } from './kubernetes-entity-generator'; +import { KubernetesListConfigService } from './kubernetes-list-service'; import { BaseKubeGuid } from './kubernetes-page.types'; import { KubernetesStoreModule } from './kubernetes.store.module'; import { KubernetesEndpointService } from './services/kubernetes-endpoint.service'; @@ -74,6 +75,7 @@ import { KubernetesEndpointService } from './services/kubernetes-endpoint.servic providers: [ BaseKubeGuid, KubernetesEndpointService, + KubernetesListConfigService, ], entryComponents: [ KubernetesCertsAuthFormComponent, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.store.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.store.module.ts index 4b37169198..906b6ee457 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.store.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.store.module.ts @@ -3,13 +3,15 @@ import { EffectsModule } from '@ngrx/effects'; import { AnalysisEffects } from './store/analysis.effects'; import { KubernetesEffects } from './store/kubernetes.effects'; +import { KubernetesReducersModule } from './store/kubernetes.reducers'; @NgModule({ imports: [ EffectsModule.forFeature([ AnalysisEffects, KubernetesEffects, - ]) + ]), + KubernetesReducersModule, ] }) export class KubernetesStoreModule { } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-list-config.service.ts index c5e48a4935..adb90ee069 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-list-config.service.ts @@ -17,9 +17,7 @@ export class KubernetesNamespacePodsListConfigService extends BaseKubernetesPods kubeId: BaseKubeGuid, public kubeNamespaceService: KubernetesNamespaceService, ) { - super(kubeId.guid, [ - BaseKubernetesPodsListConfigService.namespaceColumnId, - ]); + super([BaseKubernetesPodsListConfigService.namespaceColumnId]); this.podsDataSource = new KubernetesNamespacePodsDataSource(store, kubeId, this, kubeNamespaceService); } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-list-config.service.ts index 4f93ff213b..b204ccea12 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-list-config.service.ts @@ -19,9 +19,7 @@ export class KubernetesNodePodsListConfigService extends BaseKubernetesPodsListC kubeId: BaseKubeGuid, public kubeNodeService: KubernetesNodeService, ) { - super(kubeId.guid, [ - BaseKubernetesPodsListConfigService.nodeColumnId - ]); + super([BaseKubernetesPodsListConfigService.nodeColumnId]); this.podsDataSource = new KubernetesNodePodsDataSource(store, kubeId, this, kubeNodeService); } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts index 6534cf9b8a..19dd8572bb 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts @@ -31,7 +31,6 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig public showNamespaceLink = true; constructor( - private kubeId: string, hideColumns: string[] = [ BaseKubernetesPodsListConfigService.namespaceColumnId, BaseKubernetesPodsListConfigService.nodeColumnId @@ -74,7 +73,7 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig columnId: BaseKubernetesPodsListConfigService.namespaceColumnId, headerCell: () => 'Namespace', cellDefinition: { valuePath: 'metadata.namespace', - getLink: row => this.showNamespaceLink ? `/kubernetes/${this.kubeId}/namespaces/${row.metadata.namespace}` : null + getLink: row => this.showNamespaceLink ? `/kubernetes/${row.metadata.kubeId}/namespaces/${row.metadata.namespace}` : null }, sort: { type: 'sort', @@ -88,7 +87,7 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig columnId: BaseKubernetesPodsListConfigService.nodeColumnId, headerCell: () => 'Node', cellDefinition: { valuePath: 'spec.nodeName', - getLink: pod => `/kubernetes/${this.kubeId}/nodes/${pod.spec.nodeName}/summary` + getLink: pod => `/kubernetes/${pod.metadata.kubeId}/nodes/${pod.spec.nodeName}/summary` }, sort: { type: 'sort', @@ -159,9 +158,23 @@ export class KubernetesPodsListConfigService extends BaseKubernetesPodsListConfi store: Store, kubeId: BaseKubeGuid, ) { - super(kubeId.guid, []); + super([]); this.podsDataSource = new KubernetesPodsDataSource(store, kubeId, this); } } + +export class KubernetesPodsListConfig extends BaseKubernetesPodsListConfigService { + private podsDataSource: KubernetesPodsDataSource; + + constructor() { + super([]); + delete(this.getDataSource); + console.log(this); + } + + getDataSource = () => this.podsDataSource; + +} + diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts index bab026fa50..37b03af736 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts @@ -2,6 +2,11 @@ import { StratosCatalogEntity } from '../../../../store/src/entity-catalog/entit import { IStratosEntityDefinition } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { KubernetesPodExpandedStatus } from '../services/kubernetes-expanded-state'; +// Map of endpoint ID to current namespace for that endpoint +export interface KubernetesCurrentNamespace { + [endpoint: string]: string; +} + export interface KubernetesInfo { nodes: {}; pods: {}; @@ -42,9 +47,11 @@ export interface KubeResourceEntityDefinition { iconFont?: string; type: string; kubeCatalogEntity: string; - getKubeCatalogEntity?: (IStratosEntityDefinition) => StratosCatalogEntity, + getKubeCatalogEntity?: (IStratosEntityDefinition) => StratosCatalogEntity; route?: string; listColumns?: SimpleKubeListColumn[]; + // Should this entity be hidden in the auto-generated navigation? + hidden?: boolean; } export interface KubeService extends BasicKubeAPIResource { @@ -552,4 +559,4 @@ export interface SimpleKubeListColumn { header: string; flex?: string; sort?: boolean; -} \ No newline at end of file +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts index 39e066e6e2..f808c25fb9 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.actions.ts @@ -1,4 +1,5 @@ import { SortDirection } from '@angular/material/sort'; +import { Action } from '@ngrx/store'; import { getActions } from 'frontend/packages/store/src/actions/action.helper'; import { ApiRequestTypes } from 'frontend/packages/store/src/reducers/api-request-reducer/request-helpers'; @@ -81,11 +82,18 @@ export const GET_KUBE_DASHBOARD = '[KUBERNETES Endpoint] Get K8S Dashboard Info' export const GET_KUBE_DASHBOARD_SUCCESS = '[KUBERNETES Endpoint] Get Dashboard Success'; export const GET_KUBE_DASHBOARD_FAILURE = '[KUBERNETES Endpoint] Get Dashboard Failure'; +export const SET_CURRENT_NAMESPACE = '[Kubernetes] Set Current Namespace'; + const defaultSortParams = { 'order-direction': 'desc' as SortDirection, 'order-direction-field': 'name' }; +// Set the current namespace fo the given endpoint +export class SetCurrentNamespaceAction implements Action { + constructor(public endpoint, public namespace: string) { } + type = SET_CURRENT_NAMESPACE; +} export interface KubeAction extends EntityRequestAction { kubeGuid: string; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.reducers.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.reducers.ts new file mode 100644 index 0000000000..116c7eb3b1 --- /dev/null +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.reducers.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { StoreModule } from '@ngrx/store'; import { KubernetesCurrentNamespace } from './kube.types'; +import { SET_CURRENT_NAMESPACE } from './kubernetes.actions'; + +export const KUBERNETES_CURRENT_NAMESPACE = 'k8sCurrentNamespace'; + +const defaultState: KubernetesCurrentNamespace = {}; + +function createCurrentNamespaceReducer(state: KubernetesCurrentNamespace = defaultState, action) { + switch (action.type) { + case SET_CURRENT_NAMESPACE: + return { + ...state, + [action.endpoint]: action.namespace + }; + default: + return state; + } +} + +@NgModule({ + imports: [ + StoreModule.forFeature(KUBERNETES_CURRENT_NAMESPACE, createCurrentNamespaceReducer), + ] +}) +export class KubernetesReducersModule { } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-config.service.ts index ba0c1ddd4c..c9a0d9d714 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-config.service.ts @@ -14,10 +14,7 @@ export class HelmReleasePodsListConfig extends BaseKubernetesPodsListConfigServi store: Store, helmReleaseHelper: HelmReleaseHelperService ) { - super( - helmReleaseHelper.endpointGuid, - [BaseKubernetesPodsListConfigService.namespaceColumnId] - ); + super([BaseKubernetesPodsListConfigService.namespaceColumnId]); this.podsDataSource = new HelmReleasePodsDataSource(store, this, helmReleaseHelper.endpointGuid, helmReleaseHelper.releaseTitle); } From a228cd616e4e75a06855a60a306c10c92c15b136 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Tue, 17 Nov 2020 13:41:08 +0000 Subject: [PATCH 04/16] Fixes for pods view --- .../components/list/list.component.types.ts | 3 ++ .../kubernetes/kubernetes-entity-generator.ts | 3 +- .../src/kubernetes/kubernetes-list-service.ts | 11 +++---- .../kubernetes-resource-list.component.ts | 7 ++--- .../src/kubernetes/kubernetes.module.ts | 2 +- .../kubernetes-pods-list-config.service.ts | 31 +++++-------------- .../src/kubernetes/store/kube.types.ts | 2 ++ 7 files changed, 21 insertions(+), 38 deletions(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list.component.types.ts b/src/frontend/packages/core/src/shared/components/list/list.component.types.ts index 4602379d29..e5a673e44c 100644 --- a/src/frontend/packages/core/src/shared/components/list/list.component.types.ts +++ b/src/frontend/packages/core/src/shared/components/list/list.component.types.ts @@ -126,6 +126,9 @@ export interface IListConfig { customTimeInitialValue?: string; } +// Simple list config does not need getDataSource +export type ISimpleListConfig = Omit, 'getDataSource'>; + export interface IListMultiFilterConfig { key: string; label: string; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index 2bebceb515..32b550ef52 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -200,7 +200,6 @@ class KubeResourceEntityHelper { }; if (defn.getKubeCatalogEntity) { - console.log(defn); kubeEntityCatalog[defn.kubeCatalogEntity] = defn.getKubeCatalogEntity(d); } else { kubeEntityCatalog[defn.kubeCatalogEntity] = new StratosCatalogEntity(d, { @@ -473,7 +472,7 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi apiName: 'pods', apiNamespaced: true, kubeCatalogEntity: 'pod', - // route: 'pods', + listConfig: 'k8s-pods', getKubeCatalogEntity: (definition) => new StratosCatalogEntity( definition, { actionBuilders: kubePodActionBuilders } ) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts index e18e6b1257..4cede8e981 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-list-service.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; - -import { IListConfig } from '../../../core/src/shared/components/list/list.component.types'; +import { ISimpleListConfig } from 'frontend/packages/core/src/shared/components/list/list.component.types'; interface KubernetesListConfig { - [name: string]: IListConfig; + [name: string]: ISimpleListConfig; } // Holder for list configurations @@ -17,11 +16,11 @@ export class KubernetesListConfigService { private configs: KubernetesListConfig = {}; - set(name: string, config: IListConfig) { + set(name: string, config: ISimpleListConfig) { this.configs[name] = config; } - get(name: string): IListConfig { - return this.configs[name]; + get(name: string): ISimpleListConfig { + return name ? this.configs[name] : undefined; } } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index b64d757c59..cfb143ce7d 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -104,10 +104,8 @@ export class KubernetesResourceListComponent implements OnDestroy { action = catalogEntity.actions.getMultiple(this.kubeId.guid); } const provider = new ActionListConfigProvider(this.store, action); - - console.log(this.entityCatalogKey); - let listConfig: any = this.listConfigService.get(this.entityCatalogKey); - console.log(listConfig); + const listConfigName = catalogEntity.definition ? catalogEntity.definition.listConfig : null; + let listConfig: any = this.listConfigService.get(listConfigName); if (!listConfig) { listConfig = { pageSizeOptions: defaultHelmKubeListPageSize, @@ -123,7 +121,6 @@ export class KubernetesResourceListComponent implements OnDestroy { } provider.updateListConfig(listConfig); - this.provider = provider; } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts index 06e953f636..4037b820cf 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts @@ -239,7 +239,7 @@ import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kub export class KubernetesModule { constructor(listConfigService: KubernetesListConfigService) { - listConfigService.set('pods', new KubernetesPodsListConfig()); + listConfigService.set('k8s-pods', new KubernetesPodsListConfig()); } } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts index 19dd8572bb..0f2986f2ab 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts @@ -1,8 +1,5 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { - IListDataSource, -} from 'frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types'; import { of } from 'rxjs'; import { @@ -10,7 +7,11 @@ import { TableCellSidePanelConfig, } from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; -import { IListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; +import { + IListConfig, + ISimpleListConfig, + ListViewTypes, +} from '../../../../../core/src/shared/components/list/list.component.types'; import { AppState } from '../../../../../store/src/public-api'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { @@ -24,7 +25,7 @@ import { KubernetesPodContainersComponent } from './kubernetes-pod-containers/ku import { KubernetesPodStatusComponent } from './kubernetes-pod-status/kubernetes-pod-status.component'; import { KubernetesPodsDataSource } from './kubernetes-pods-data-source'; -export abstract class BaseKubernetesPodsListConfigService implements IListConfig { +export abstract class BaseKubernetesPodsListConfigService implements ISimpleListConfig { static namespaceColumnId = 'namespace'; static nodeColumnId = 'node'; @@ -96,14 +97,6 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig }, cellFlex: '2', }, - { - columnId: 'ready', - headerCell: () => 'Ready', - cellDefinition: { - getValue: pod => `${pod.expandedStatus.readyContainers}/${pod.expandedStatus.totalContainers}` - }, - cellFlex: '1' - }, { columnId: 'expandedStatus', headerCell: () => 'Status', @@ -138,7 +131,6 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig filter: 'Filter by Name', noEntries: 'There are no pods' }; - abstract getDataSource: () => IListDataSource; expandComponent = KubernetesPodContainersComponent; getGlobalActions = () => null; @@ -149,7 +141,7 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig } @Injectable() -export class KubernetesPodsListConfigService extends BaseKubernetesPodsListConfigService { +export class KubernetesPodsListConfigService extends BaseKubernetesPodsListConfigService implements IListConfig { private podsDataSource: KubernetesPodsDataSource; getDataSource = () => this.podsDataSource; @@ -164,17 +156,8 @@ export class KubernetesPodsListConfigService extends BaseKubernetesPodsListConfi } - export class KubernetesPodsListConfig extends BaseKubernetesPodsListConfigService { - private podsDataSource: KubernetesPodsDataSource; - constructor() { super([]); - delete(this.getDataSource); - console.log(this); } - - getDataSource = () => this.podsDataSource; - } - diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts index 37b03af736..190dab5808 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts @@ -52,6 +52,8 @@ export interface KubeResourceEntityDefinition { listColumns?: SimpleKubeListColumn[]; // Should this entity be hidden in the auto-generated navigation? hidden?: boolean; + // Name fo a list config that can be obtained from the list config service + listConfig?: string; } export interface KubeService extends BasicKubeAPIResource { From 47de835e556023216c85ae1d2c5b89dce05d2100 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Tue, 17 Nov 2020 15:14:45 +0000 Subject: [PATCH 05/16] Tidy ups --- .../src/kubernetes/kubernetes.module.ts | 2 -- .../src/kubernetes/kubernetes.routing.ts | 6 ---- .../kubernetes-pods-tab.component.html | 1 - .../kubernetes-pods-tab.component.scss | 0 .../kubernetes-pods-tab.component.spec.ts | 30 ------------------- .../kubernetes-pods-tab.component.ts | 15 ---------- 6 files changed, 54 deletions(-) delete mode 100644 src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.html delete mode 100644 src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.scss delete mode 100644 src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.spec.ts delete mode 100644 src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.ts diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts index 4037b820cf..7a175c968c 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts @@ -123,7 +123,6 @@ import { import { KubernetesAnalysisTabComponent } from './tabs/kubernetes-analysis-tab/kubernetes-analysis-tab.component'; import { KubernetesNamespacesTabComponent } from './tabs/kubernetes-namespaces-tab/kubernetes-namespaces-tab.component'; import { KubernetesNodesTabComponent } from './tabs/kubernetes-nodes-tab/kubernetes-nodes-tab.component'; -import { KubernetesPodsTabComponent } from './tabs/kubernetes-pods-tab/kubernetes-pods-tab.component'; import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kubernetes-summary.component'; /* tslint:disable:max-line-length */ @@ -142,7 +141,6 @@ import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kub KubernetesNodesTabComponent, KubernetesTabBaseComponent, KubernetesNodeCapacityComponent, - KubernetesPodsTabComponent, KubernetesPodTagsComponent, KubernetesNamespacesTabComponent, KubernetesDashboardTabComponent, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts index 756df65701..7f89503e8b 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts @@ -34,7 +34,6 @@ import { import { KubernetesAnalysisTabComponent } from './tabs/kubernetes-analysis-tab/kubernetes-analysis-tab.component'; import { KubernetesNamespacesTabComponent } from './tabs/kubernetes-namespaces-tab/kubernetes-namespaces-tab.component'; import { KubernetesNodesTabComponent } from './tabs/kubernetes-nodes-tab/kubernetes-nodes-tab.component'; -import { KubernetesPodsTabComponent } from './tabs/kubernetes-pods-tab/kubernetes-pods-tab.component'; import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kubernetes-summary.component'; const kubernetes: Routes = [{ @@ -124,11 +123,6 @@ const kubernetes: Routes = [{ path: 'namespaces', component: KubernetesNamespacesTabComponent }, - { - path: 'pods', - component: KubernetesPodsTabComponent, - data: { entityCatalogKey: 'pod' } - }, { path: 'analysis', component: KubernetesAnalysisTabComponent diff --git a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.html b/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.html deleted file mode 100644 index dd2b6cb351..0000000000 --- a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.scss b/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.spec.ts b/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.spec.ts deleted file mode 100644 index b046e6a850..0000000000 --- a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { BaseKubeGuid } from '../../kubernetes-page.types'; -import { KubernetesBaseTestModules } from '../../kubernetes.testing.module'; -import { KubernetesEndpointService } from '../../services/kubernetes-endpoint.service'; -import { KubernetesPodsTabComponent } from './kubernetes-pods-tab.component'; - -describe('KubernetesPodsTabComponent', () => { - let component: KubernetesPodsTabComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [KubernetesPodsTabComponent], - imports: KubernetesBaseTestModules, - providers: [BaseKubeGuid, KubernetesEndpointService] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(KubernetesPodsTabComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.ts deleted file mode 100644 index 3315248a53..0000000000 --- a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-pods-tab/kubernetes-pods-tab.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; - -import { ListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; -import { KubernetesPodsListConfigService } from '../../list-types/kubernetes-pods/kubernetes-pods-list-config.service'; - -@Component({ - selector: 'app-kubernetes-pods-tab', - templateUrl: './kubernetes-pods-tab.component.html', - styleUrls: ['./kubernetes-pods-tab.component.scss'], - providers: [{ - provide: ListConfig, - useClass: KubernetesPodsListConfigService, - }] -}) -export class KubernetesPodsTabComponent { } From e09e02604188c307741cf2193ea96a8c8ad2abbf Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Tue, 17 Nov 2020 16:37:42 +0000 Subject: [PATCH 06/16] Add more resource types --- .../app-table-cell-default.component.html | 4 +- .../kubernetes/kubernetes-entity-generator.ts | 56 +++++++++++++++++-- .../kubernetes-resource-list.component.ts | 15 +++-- .../src/kubernetes/kubernetes.module.ts | 2 + ...-namespace-services-list-config.service.ts | 6 +- .../kubernetes-service-list-config.service.ts | 13 +++-- .../src/kubernetes/store/kube.types.ts | 8 ++- ...lm-release-services-list-config.service.ts | 4 +- 8 files changed, 86 insertions(+), 22 deletions(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.html b/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.html index c66ecb63b2..eeff6b4e62 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.html +++ b/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.html @@ -24,6 +24,6 @@ - {{ value }} - - + {{ value }} + - \ No newline at end of file diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index 32b550ef52..daf9713c3f 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -44,6 +44,7 @@ import { kubernetesServicesEntityType, kubernetesStatefulSetsEntityType, } from './kubernetes-entity-factory'; +import { KubernetesService } from './services/kubernetes.service'; import { createKubeResourceActionBuilder, KubeResourceActionBuilders, @@ -292,7 +293,7 @@ export function generateKubernetesEntities(): StratosBaseCatalogEntity[] { generateDeploymentsEntity(endpointDefinition), generateNodesEntity(endpointDefinition), // generateNamespacesEntity(endpointDefinition), - generateServicesEntity(endpointDefinition), + //generateServicesEntity(endpointDefinition), generateDashboardEntity(endpointDefinition), generateAnalysisReportsEntity(endpointDefinition), generateMetricEntity(endpointDefinition), @@ -478,13 +479,33 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi ) }); + entities.add({ + type: kubernetesServicesEntityType, + icon: 'service', + label: 'Service', + apiVersion: '/api/v1', + apiName: 'service', + apiNamespaced: true, + kubeCatalogEntity: 'service', + listConfig: 'k8s-services', + getKubeCatalogEntity: (definition) => new StratosCatalogEntity( + definition, { actionBuilders: kubeServiceActionBuilders } + ) + }); + entities.add({ type: kubernetesConfigMapEntityType, icon: 'config_maps', label: 'Config Map', apiVersion: '/api/v1', apiName: 'configmaps', - kubeCatalogEntity: 'configMap' + kubeCatalogEntity: 'configMap', + listColumns: [ + { + header: 'Data Keys', + field: (row: KubernetesConfigMap) => `${Object.keys(row.data).length}` + }, + ] }); entities.add({ @@ -493,7 +514,13 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi label: 'Secret', apiVersion: '/api/v1', apiName: 'secrets', - kubeCatalogEntity: 'secrets' + kubeCatalogEntity: 'secrets', + listColumns: [ + { + header: 'Data Keys', + field: (row: KubernetesConfigMap) => `${Object.keys(row.data).length}` + }, + ] }); entities.add({ @@ -505,6 +532,11 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi apiName: 'persistentvolumeclaims', kubeCatalogEntity: 'pvcs', listColumns: [ + { + header: 'Storage Class', + field: 'spec.storageClassName', + sort: true + }, { header: 'Phase', field: 'status.phase', @@ -561,7 +593,14 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi label: 'Replica Set', apiVersion: '/apis/apps/v1', apiName: 'replicasets', - kubeCatalogEntity: 'replicaSets' + kubeCatalogEntity: 'replicaSets', + listColumns: [ + { + header: 'Replicas', + field: 'spec.replicas', + sort: true + }, + ] }); entities.add({ @@ -592,5 +631,14 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi kubeCatalogEntity: 'role' }); + entities.add({ + type: 'kubernetesJob', + icon: 'job', + label: 'Job', + apiVersion: '/apis/batch/v1', + apiName: 'jobs', + kubeCatalogEntity: 'job' + }); + return entities.entities; } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index cfb143ce7d..8ca2d1d6e6 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -26,6 +26,7 @@ import { KubeAPIResource, KubeResourceEntityDefinition, KubernetesCurrentNamespace, + SimpleColumnValueGetter, SimpleKubeListColumn, } from '../../store/kube.types'; import { SetCurrentNamespaceAction } from './../../store/kubernetes.actions'; @@ -194,17 +195,21 @@ export class KubernetesResourceListComponent implements OnDestroy { const tableCell: ITableColumn = { columnId: cell.header.toLowerCase(), headerCell: () => cell.header, - cellDefinition: { - valuePath: cell.field - }, + cellDefinition: {}, cellFlex: cell.flex || '1' }; - if (cell.sort) { + if (typeof(cell.field) === 'string') { + tableCell.cellDefinition.valuePath = cell.field as string; + } else { + tableCell.cellDefinition.getValue = cell.field as SimpleColumnValueGetter; + } + + if (cell.sort && typeof(cell.field) === 'string') { tableCell.sort = { type: 'sort', orderKey: tableCell.columnId, - field: cell.field + field: cell.field as string }; } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts index 7a175c968c..c453d11135 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.module.ts @@ -107,6 +107,7 @@ import { KubernetesServicePortsComponent } from './list-types/kubernetes-service import { KubeServiceCardComponent, } from './list-types/kubernetes-services/kubernetes-service-card/kubernetes-service-card.component'; +import { KubernetesServicesListConfig } from './list-types/kubernetes-services/kubernetes-service-list-config.service'; import { PodMetricsComponent } from './pod-metrics/pod-metrics.component'; import { KubernetesEndpointService } from './services/kubernetes-endpoint.service'; import { KubernetesNodeService } from './services/kubernetes-node.service'; @@ -238,6 +239,7 @@ export class KubernetesModule { constructor(listConfigService: KubernetesListConfigService) { listConfigService.set('k8s-pods', new KubernetesPodsListConfig()); + listConfigService.set('k8s-services', new KubernetesServicesListConfig()); } } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-list-config.service.ts index ebf6103361..e42423e571 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-list-config.service.ts @@ -1,14 +1,16 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { AppState } from '../../../../../store/src/public-api'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubernetesNamespaceService } from '../../services/kubernetes-namespace.service'; +import { KubeService } from '../../store/kube.types'; import { BaseKubernetesServicesListConfig } from '../kubernetes-services/kubernetes-service-list-config.service'; import { KubernetesNamespaceServicesDataSource } from './kubernetes-namespace-services-data-source'; @Injectable() -export class KubernetesNamespaceServicesListConfig extends BaseKubernetesServicesListConfig { +export class KubernetesNamespaceServicesListConfig extends BaseKubernetesServicesListConfig implements IListConfig { dataSource: KubernetesNamespaceServicesDataSource; constructor( @@ -20,6 +22,4 @@ export class KubernetesNamespaceServicesListConfig extends BaseKubernetesService this.dataSource = new KubernetesNamespaceServicesDataSource(store, kubeId, this, kubeNamespaceService.namespaceName); } getDataSource = () => this.dataSource; - - } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-services/kubernetes-service-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-services/kubernetes-service-list-config.service.ts index 6c861ff29c..d650f64276 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-services/kubernetes-service-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-services/kubernetes-service-list-config.service.ts @@ -1,12 +1,11 @@ import { of } from 'rxjs'; -import { ListDataSource } from '../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; import { TableCellSidePanelComponent, TableCellSidePanelConfig, } from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; -import { IListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; +import { ISimpleListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; import { KubernetesResourceViewerComponent, KubernetesResourceViewerConfig, @@ -17,7 +16,7 @@ import { createKubeAgeColumn } from '../kube-list.helper'; import { KubernetesServicePortsComponent } from '../kubernetes-service-ports/kubernetes-service-ports.component'; import { KubeServiceCardComponent } from './kubernetes-service-card/kubernetes-service-card.component'; -export abstract class BaseKubernetesServicesListConfig implements IListConfig { +export abstract class BaseKubernetesServicesListConfig implements ISimpleListConfig { columns: Array> = [ { columnId: 'name', headerCell: () => 'Name', @@ -71,11 +70,15 @@ export abstract class BaseKubernetesServicesListConfig implements IListConfig ListDataSource; - getGlobalActions = () => null; getMultiActions = () => []; getSingleActions = () => []; getColumns = () => this.columns; getMultiFiltersConfigs = () => []; } + +export class KubernetesServicesListConfig extends BaseKubernetesServicesListConfig { + constructor() { + super(); + } +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts index 190dab5808..5ffda836e5 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts @@ -1,3 +1,5 @@ +import { Observable } from 'rxjs'; + import { StratosCatalogEntity } from '../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { IStratosEntityDefinition } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { KubernetesPodExpandedStatus } from '../services/kubernetes-expanded-state'; @@ -556,8 +558,10 @@ export interface KubernetesConfigMap extends BasicKubeAPIResource { test?: string; } -export interface SimpleKubeListColumn { - field: string; +export type SimpleColumnValueGetter = (row: T) => string | Observable; + +export interface SimpleKubeListColumn { + field: string | SimpleColumnValueGetter; header: string; flex?: string; sort?: boolean; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-services-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-services-list-config.service.ts index d9d31a7505..aa2fa53e8f 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-services-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-services-list-config.service.ts @@ -3,14 +3,16 @@ import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { AppState } from 'frontend/packages/store/src/app-state'; +import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { BaseKubernetesServicesListConfig, } from '../../list-types/kubernetes-services/kubernetes-service-list-config.service'; +import { KubeService } from '../../store/kube.types'; import { HelmReleaseHelperService } from '../release/tabs/helm-release-helper.service'; import { HelmReleaseServicesDataSource } from './helm-release-services-list-source'; @Injectable() -export class HelmReleaseServicesListConfig extends BaseKubernetesServicesListConfig { +export class HelmReleaseServicesListConfig extends BaseKubernetesServicesListConfig implements IListConfig { constructor( private store: Store, From 1fc9c137f0d1283abdab59db7b69ea5126f83bfa Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 18 Nov 2020 08:17:55 +0000 Subject: [PATCH 07/16] Fix lint issues --- .../kubernetes/kubernetes-entity-generator.ts | 2 +- .../kubernetes-namespace.component.ts | 6 +- .../kubernetes-resource-list.ts | 188 ------------------ .../kube-resource.action-builder.ts | 8 +- .../kubernetes/store/kube-resource.actions.ts | 2 +- .../src/kubernetes/store/kube.getIds.ts | 4 +- .../kubernetes/store/kubernetes.effects.ts | 6 +- 7 files changed, 14 insertions(+), 202 deletions(-) delete mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index daf9713c3f..f7f7221d49 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -293,7 +293,7 @@ export function generateKubernetesEntities(): StratosBaseCatalogEntity[] { generateDeploymentsEntity(endpointDefinition), generateNodesEntity(endpointDefinition), // generateNamespacesEntity(endpointDefinition), - //generateServicesEntity(endpointDefinition), + // generateServicesEntity(endpointDefinition), generateDashboardEntity(endpointDefinition), generateAnalysisReportsEntity(endpointDefinition), generateMetricEntity(endpointDefinition), diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts index 40c31a6bf1..6d6bc675ac 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts @@ -6,16 +6,16 @@ import { filter, map } from 'rxjs/operators'; import { IAppFavMetadata } from '../../../../cloud-foundry/src/cf-metadata-types'; import { IHeaderBreadcrumb } from '../../../../core/src/shared/components/page-header/page-header.types'; import { FavoritesConfigMapper } from '../../../../store/src/favorite-config-mapper'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; import { getFavoriteFromEntity } from '../../../../store/src/user-favorite-helpers'; +import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; import { kubernetesNamespacesEntityType } from '../kubernetes-entity-factory'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; import { KubernetesNamespaceService } from '../services/kubernetes-namespace.service'; import { KubernetesAnalysisService } from '../services/kubernetes.analysis.service'; import { KubernetesService } from '../services/kubernetes.service'; -import { KUBERNETES_ENDPOINT_TYPE } from './../kubernetes-entity-factory'; import { KubeResourceEntityDefinition } from '../store/kube.types'; +import { KUBERNETES_ENDPOINT_TYPE } from './../kubernetes-entity-factory'; @Component({ selector: 'app-kubernetes-namespace', @@ -101,7 +101,7 @@ export class KubernetesNamespaceComponent { }); } } - }) + }); tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); return tabsFromRouterConfig; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts deleted file mode 100644 index 1f29469f91..0000000000 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { Injectable, Optional } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Store } from '@ngrx/store'; -import { - IListDataSource, -} from 'frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types'; -import { of } from 'rxjs'; - -import { ListDataSource } from '../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; -import { - TableCellSidePanelComponent, - TableCellSidePanelConfig, -} from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; -import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; -import { IListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; -import { AppState } from '../../../../../store/src/app-state'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; -import { BaseKubeGuid } from '../../kubernetes-page.types'; -import { - KubernetesResourceViewerComponent, - KubernetesResourceViewerConfig, -} from '../../kubernetes-resource-viewer/kubernetes-resource-viewer.component'; -import { defaultHelmKubeListPageSize } from '../../list-types/kube-helm-list-types'; -import { createKubeAgeColumn } from '../../list-types/kube-list.helper'; -import { KubernetesNamespaceService } from '../../services/kubernetes-namespace.service'; -import { KubeAPIResource, SimpleKubeListColumn } from './../../store/kube.types'; - - -export abstract class KubernetesBaseResourceListConfigService implements IListConfig { - - static namespaceColumnId = 'namespace'; - public showNamespaceLink = true; - - public catalogEntity; any; - - constructor(private kubeId: string) {} - - columns: Array> = [ - // Name - { - columnId: 'name', headerCell: () => 'Name', - cellComponent: TableCellSidePanelComponent, - sort: { - type: 'sort', - orderKey: 'name', - field: 'metadata.name' - }, - cellFlex: '3', - cellConfig: (resource): TableCellSidePanelConfig => { - return ({ - text: resource.metadata.name, - sidePanelComponent: KubernetesResourceViewerComponent, - sidePanelConfig: { - title: resource.metadata.name, - resourceKind: this.catalogEntity.definition.label, - resource$: of(resource) - } - }) - } - }, - // Namespace - { - columnId: KubernetesBaseResourceListConfigService.namespaceColumnId, headerCell: () => 'Namespace', - cellDefinition: { - valuePath: 'metadata.namespace', - getLink: row => this.showNamespaceLink ? `/kubernetes/${this.kubeId}/namespaces/${row.metadata.namespace}` : null - }, - sort: { - type: 'sort', - orderKey: KubernetesBaseResourceListConfigService.namespaceColumnId, - field: 'metadata.namespace' - }, - cellFlex: '2', - }, - ]; - - pageSizeOptions = defaultHelmKubeListPageSize; - viewType = ListViewTypes.TABLE_ONLY; - enableTextFilter = true; - text = { - filter: 'Filter by Name', - noEntries: 'There are no resources' - }; - abstract getDataSource: () => IListDataSource; - - getGlobalActions = () => null; - getMultiActions = () => []; - getSingleActions = () => []; - getColumns = () => this.columns; - getMultiFiltersConfigs = () => []; -} - -class KubernetesResourceDataSource extends ListDataSource { - - constructor( - store: Store, - listConfig: IListConfig, - action: any - ) { - super({ - store, - action, - schema: action.entity[0], - getRowUniqueId: (row) => action.entity[0].getId(row), - paginationKey: action.paginationKey, - isLocal: true, - listConfig, - transformEntities: [{ type: 'filter', field: 'metadata.name' }] - }); - } -} - - -@Injectable() -export class KubernetesResourceListConfigService extends KubernetesBaseResourceListConfigService { - private resourceDataSource: KubernetesResourceDataSource; - - getDataSource = () => this.resourceDataSource; - - constructor( - store: Store, - kubeId: BaseKubeGuid, - route: ActivatedRoute, - router: Router, - @Optional() kubeNamespaceService: KubernetesNamespaceService, - ) { - super(kubeId.guid); - - let entityCatalogKey = route.snapshot.data.entityCatalogKey; - if (!entityCatalogKey) { - // Default is to use the last part of the route - const routeParts = router.url.split('/'); - entityCatalogKey = routeParts[routeParts.length - 1]; - } - - this.catalogEntity = kubeEntityCatalog[entityCatalogKey]; - - let action; - if (!!kubeNamespaceService) { - action = this.catalogEntity.getInNamespace(kubeId.guid, kubeNamespaceService.namespaceName); - } else { - action = this.catalogEntity.actions.getMultiple(kubeId.guid); - } - - // We hide the namespace column if we are in a given namespace OR the resource is not namespaced - let hideNamespaceColumn = !!kubeNamespaceService; - if (this.catalogEntity && this.catalogEntity.definition && this.catalogEntity.definition.apiNamespaced === false) { - hideNamespaceColumn = true; - } - - if (hideNamespaceColumn) { - // Hide the namespace column - this.columns = this.columns.filter(column => column.columnId !== KubernetesBaseResourceListConfigService.namespaceColumnId); - } - - this.resourceDataSource = new KubernetesResourceDataSource(store, this, action); - - if (this.catalogEntity && this.catalogEntity.definition && this.catalogEntity.definition.listColumns) { - this.catalogEntity.definition.listColumns.forEach(c => this.columns.push(this.simpleCellToTableCell(c))); - } - - this.columns.push(createKubeAgeColumn()); - } - - - private simpleCellToTableCell(cell: SimpleKubeListColumn): ITableColumn { - - const tableCell: ITableColumn = { - columnId: cell.header.toLowerCase(), - headerCell: () => cell.header, - cellDefinition: { - valuePath: cell.field - }, - cellFlex: cell.flex || '1' - }; - - if (cell.sort) { - tableCell.sort = { - type: 'sort', - orderKey: tableCell.columnId, - field: cell.field - } - } - - return tableCell; - } -} - diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts index e05e629d6c..a072d7fcdf 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts @@ -7,15 +7,15 @@ export interface KubeResourceActionBuilders extends OrchestratedActionBuilders { resourceName: string, kubeGuid: string, extraArgs: { namespace: string } - ) => GetKubernetesResource, + ) => GetKubernetesResource; getMultiple: ( kubeGuid: string, paginationKey?: string, - ) => GetKubernetesResources, + ) => GetKubernetesResources; getInNamespace: ( kubeGuid: string, namespace: string - ) => GetKubernetesResourcesInNamespace + ) => GetKubernetesResourcesInNamespace; } export function createKubeResourceActionBuilder(entityType: string): KubeResourceActionBuilders { @@ -24,4 +24,4 @@ export function createKubeResourceActionBuilder(entityType: string): KubeResourc getMultiple: (kubeGuid: string, paginationKey?: string) => new GetKubernetesResources(entityType, kubeGuid), getInNamespace: (kubeGuid: string, namespace: string) => new GetKubernetesResourcesInNamespace(entityType, kubeGuid, namespace), }; -} \ No newline at end of file +} diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts index 31bc183cfa..c9a350270d 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube-resource.actions.ts @@ -49,7 +49,7 @@ export class GetKubernetesResources implements KubePaginationAction { constructor(public entityType: string, public kubeGuid: string) { this.paginationKey = getPaginationKey(entityType, 'k8s', kubeGuid); - this.entity = [kubernetesEntityFactory(entityType)] + this.entity = [kubernetesEntityFactory(entityType)]; } type = GET_KUBE_RESOURCES; endpointType = KUBERNETES_ENDPOINT_TYPE; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts index 903d705f97..0dac96b99d 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.getIds.ts @@ -31,7 +31,7 @@ export const getGuidFromResource = (entity: BasicKubeAPIResource): string => { // Resource with namespace if (entity.metadata.namespace) { - return deliminate(entity.metadata.kubeId, entity.metadata.namespace, entity.metadata.name) + return deliminate(entity.metadata.kubeId, entity.metadata.namespace, entity.metadata.name); } // Named resource (no namespace) @@ -41,7 +41,7 @@ export const getGuidFromResource = (entity: BasicKubeAPIResource): string => { // Cluster-level resource (e.g. Kubernetes dashboard) return entity.metadata.kubeId; -} +}; // ====================================================================================================================================== // LEGACY - Remove those not needed diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts index 491f2dd5ad..b112159622 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kubernetes.effects.ts @@ -78,7 +78,7 @@ export interface KubeDashboardStatus { kubeGuid: string; metadata?: { kubeId: string; - } + }; installed: boolean; stratosInstalled: boolean; running: boolean; @@ -275,7 +275,7 @@ export class KubernetesEffects { @Effect() fetchKubeResources$ = this.actions$.pipe( ofType(GET_KUBE_RESOURCES), - flatMap((action: GetKubernetesResources)=> { + flatMap((action: GetKubernetesResources) => { const catalog = entityCatalog.getEntity(action.endpointType, action.entityType); if (catalog && catalog.definition) { const defn = catalog.definition as IKubeResourceEntityDefinition; @@ -294,7 +294,7 @@ export class KubernetesEffects { @Effect() fetchKubeResourcesInNamespace$ = this.actions$.pipe( ofType(GET_KUBE_RESOURCES_IN_NAMESPACE), - flatMap((action: GetKubernetesResourcesInNamespace)=> { + flatMap((action: GetKubernetesResourcesInNamespace) => { const catalog = entityCatalog.getEntity(action.endpointType, action.entityType); if (catalog && catalog.definition) { const defn = catalog.definition as IKubeResourceEntityDefinition; From 80dc68b85a9c5cecb4156cefe57730629a35e739 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 18 Nov 2020 08:39:58 +0000 Subject: [PATCH 08/16] Fix build issue --- .../kubernetes-resource-list.component.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index 8ca2d1d6e6..0d1e9ee5d7 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -30,7 +30,9 @@ import { SimpleKubeListColumn, } from '../../store/kube.types'; import { SetCurrentNamespaceAction } from './../../store/kubernetes.actions'; -import { KubernetesBaseResourceListConfigService } from './kubernetes-resource-list'; + +const namespaceColumnId = 'namespace'; + @Component({ selector: 'app-kubernetes-resource-list', @@ -155,14 +157,14 @@ export class KubernetesResourceListComponent implements OnDestroy { }, // Namespace { - columnId: KubernetesBaseResourceListConfigService.namespaceColumnId, headerCell: () => 'Namespace', + columnId: namespaceColumnId, headerCell: () => 'Namespace', cellDefinition: { valuePath: 'metadata.namespace', getLink: row => this.showNamespaceLink ? `/kubernetes/${this.kubeId}/namespaces/${row.metadata.namespace}` : null }, sort: { type: 'sort', - orderKey: KubernetesBaseResourceListConfigService.namespaceColumnId, + orderKey: namespaceColumnId, field: 'metadata.namespace' }, cellFlex: '2', @@ -178,7 +180,7 @@ export class KubernetesResourceListComponent implements OnDestroy { if (hideNamespaceColumn) { // Hide the namespace column - columns = columns.filter(column => column.columnId !== KubernetesBaseResourceListConfigService.namespaceColumnId); + columns = columns.filter(column => column.columnId !== namespaceColumnId); } if (definition && definition.listColumns) { @@ -186,7 +188,6 @@ export class KubernetesResourceListComponent implements OnDestroy { } columns.push(createKubeAgeColumn()); - return columns; } From eb9c96d9e8f2a6c13a2734936da68b55899ef68f Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 18 Nov 2020 14:51:55 +0000 Subject: [PATCH 09/16] Fix unit test --- .../kubernetes-resource-list.component.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts index 3f41a59cdf..a5cd999a55 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts @@ -1,7 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { KubernetesBaseTestModules } from '../../kubernetes.testing.module'; import { KubernetesResourceListComponent } from './kubernetes-resource-list.component'; describe('KubernetesResourceListComponent', () => { @@ -11,7 +11,7 @@ describe('KubernetesResourceListComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ KubernetesResourceListComponent ], - imports: [ RouterTestingModule ], + imports: [ KubernetesBaseTestModules ], providers: [ { provide: ActivatedRoute, From fb286948f1452d0c1402b014cbead8f78a34fea9 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 18 Nov 2020 14:55:11 +0000 Subject: [PATCH 10/16] Unit test fix --- ...kubernetes-resource-list.component.spec.ts | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts index a5cd999a55..15063168bc 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts @@ -1,7 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; -import { KubernetesBaseTestModules } from '../../kubernetes.testing.module'; +import { KubeBaseGuidMock, KubernetesBaseTestModules } from '../../kubernetes.testing.module'; import { KubernetesResourceListComponent } from './kubernetes-resource-list.component'; describe('KubernetesResourceListComponent', () => { @@ -13,21 +13,22 @@ describe('KubernetesResourceListComponent', () => { declarations: [ KubernetesResourceListComponent ], imports: [ KubernetesBaseTestModules ], providers: [ - { - provide: ActivatedRoute, - useValue: { - snapshot: { - data: { - entityCatalogKey: 'test' - }, - params: { - endpointId: 'anything' - }, - queryParams: {} + KubeBaseGuidMock, + { + provide: ActivatedRoute, + useValue: { + snapshot: { + data: { + entityCatalogKey: 'test' + }, + params: { + endpointId: 'anything' + }, + queryParams: {} + } } } - } -] + ] }) .compileComponents(); })); From 9e7d04202263c1643b97f3e341000d602574b60f Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 18 Nov 2020 16:55:13 +0000 Subject: [PATCH 11/16] Fix unit tests --- ...kubernetes-resource-list.component.spec.ts | 3 ++- .../kubernetes-resource-list.component.ts | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts index 15063168bc..e1538f6d1f 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.spec.ts @@ -1,6 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; +import { TabNavService } from '../../../../../core/src/tab-nav.service'; import { KubeBaseGuidMock, KubernetesBaseTestModules } from '../../kubernetes.testing.module'; import { KubernetesResourceListComponent } from './kubernetes-resource-list.component'; @@ -14,6 +15,7 @@ describe('KubernetesResourceListComponent', () => { imports: [ KubernetesBaseTestModules ], providers: [ KubeBaseGuidMock, + TabNavService, { provide: ActivatedRoute, useValue: { @@ -22,7 +24,6 @@ describe('KubernetesResourceListComponent', () => { entityCatalogKey: 'test' }, params: { - endpointId: 'anything' }, queryParams: {} } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index 0d1e9ee5d7..e7e0d5a261 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -33,7 +33,6 @@ import { SetCurrentNamespaceAction } from './../../store/kubernetes.actions'; const namespaceColumnId = 'namespace'; - @Component({ selector: 'app-kubernetes-resource-list', templateUrl: './kubernetes-resource-list.component.html', @@ -70,10 +69,16 @@ export class KubernetesResourceListComponent implements OnDestroy { this.entityCatalogKey = routeParts[routeParts.length - 1]; } + const catalogEntity = kubeEntityCatalog[this.entityCatalogKey]; + if (!catalogEntity) { + console.error(`Can not find catalog entity for Kubernetes entity ${this.entityCatalogKey}`); + return; + } + const namespacesObs = kubeEntityCatalog.namespace.store.getPaginationService(kubeId.guid); this.namespaces$ = namespacesObs.entities$.pipe(map(ns => ns.map(n => n.metadata.name))); - this.createProvider(); + this.createProvider(catalogEntity); // Watch for namespace changes this.sub = this.store.select(state => state.k8sCurrentNamespace).pipe( @@ -82,7 +87,7 @@ export class KubernetesResourceListComponent implements OnDestroy { ).subscribe(ns => { this.selectedNamespace = ns === '*' ? undefined : ns; if (this.isNamespacedView) { - this.createProvider(); + this.createProvider(catalogEntity); } }); } @@ -93,12 +98,7 @@ export class KubernetesResourceListComponent implements OnDestroy { } } - private createProvider() { - const catalogEntity = kubeEntityCatalog[this.entityCatalogKey]; - if (!catalogEntity) { - console.error(`Can not find catalog entity for Kubernetes entity ${this.entityCatalogKey}`); - return; - } + private createProvider(catalogEntity: any) { this.isNamespacedView = !!catalogEntity.definition.apiNamespaced; let action; if (this.selectedNamespace && this.isNamespacedView) { @@ -106,6 +106,7 @@ export class KubernetesResourceListComponent implements OnDestroy { } else { action = catalogEntity.actions.getMultiple(this.kubeId.guid); } + const provider = new ActionListConfigProvider(this.store, action); const listConfigName = catalogEntity.definition ? catalogEntity.definition.listConfig : null; let listConfig: any = this.listConfigService.get(listConfigName); From 2265a49537bf1b77282324b0c2a1129c9006b9cf Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 3 Dec 2020 12:01:43 +0000 Subject: [PATCH 12/16] Fix lint issue --- .../src/kubernetes/kubernetes-entity-generator.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index c8241236fe..a67bc47352 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -16,7 +16,6 @@ import { import { EndpointAuthTypeConfig, EndpointType } from '../../../store/src/extension-types'; import { metricEntityType } from '../../../store/src/helpers/stratos-entity-factory'; import { IFavoriteMetadata } from '../../../store/src/types/user-favorites.types'; -import { UserFavoriteManager } from '../../../store/src/user-favorite-manager'; import { KubernetesAWSAuthFormComponent } from './auth-forms/kubernetes-aws-auth-form/kubernetes-aws-auth-form.component'; import { KubernetesCertsAuthFormComponent, @@ -406,9 +405,6 @@ function generateMetricEntity(endpointDefinition: StratosEndpointExtensionDefini return new StratosCatalogEntity(definition); } -} - - // ============================================================================================================= // Kubernetes Resources using generic resource pattern // ============================================================================================================= @@ -613,4 +609,5 @@ function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensi kubeCatalogEntity: 'job' }); - return entities.entities; \ No newline at end of file + return entities.entities; +} From 4a0a9a2df0514ce2781b810a11f94c82ebcf4158 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 3 Dec 2020 18:14:42 +0000 Subject: [PATCH 13/16] RE-arrange kube entity creation - now assign directly to kube entity catalog - to access custom kube generator resources have to do some funnies in kubernetes-tab-base.component.ts --- .../home/kubernetes-home-card.component.ts | 4 +- .../kubernetes/kubernetes-entity-catalog.ts | 50 -- .../kubernetes/kubernetes-entity-factory.ts | 18 +- .../kubernetes/kubernetes-entity-generator.ts | 817 +++++++++--------- .../kubernetes-namespace.component.ts | 41 +- .../kubernetes-resource-list.component.ts | 26 +- .../kubernetes-tab-base.component.ts | 65 +- .../src/kubernetes/kubernetes.setup.module.ts | 5 +- .../analysis-reports-list-source.ts | 2 +- .../kubernetes-namespace-pods-data-source.ts | 2 +- ...bernetes-namespace-services-data-source.ts | 2 +- .../kubernetes-namespaces-data-source.ts | 2 +- .../kubernetes-node-pods-data-source.ts | 2 +- .../kubernetes-nodes-data-source.ts | 2 +- .../kubernetes-pod-containers.component.ts | 2 +- .../kubernetes-pods-data-source.ts | 2 +- .../pod-metrics/pod-metrics.component.ts | 2 +- .../services/kubernetes-endpoint.service.ts | 2 +- .../services/kubernetes-namespace.service.ts | 2 +- .../services/kubernetes-node.service.ts | 2 +- .../services/kubernetes.analysis.service.ts | 2 +- .../kube-resource.action-builder.ts | 2 +- .../src/kubernetes/store/kube.types.ts | 16 +- .../kubernetes-summary.component.ts | 2 +- .../create-release.component.ts | 2 +- .../helm-release-pods-list-source.ts | 2 +- .../kube-namespaces-filter-config.service.ts | 2 +- .../helm-release-socket-service.ts | 2 +- .../tabs/helm-release-helper.service.ts | 2 +- .../entity-catalog/entity-catalog.types.ts | 3 + 30 files changed, 507 insertions(+), 578 deletions(-) delete mode 100644 src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts diff --git a/src/frontend/packages/kubernetes/src/kubernetes/home/kubernetes-home-card.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/home/kubernetes-home-card.component.ts index bf615dad5e..35262b20c9 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/home/kubernetes-home-card.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/home/kubernetes-home-card.component.ts @@ -7,7 +7,7 @@ import { first, map } from 'rxjs/operators'; import { HomePageCardLayout } from '../../../../core/src/features/home/home.types'; import { HomeCardShortcut } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { EndpointModel } from '../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; @Component({ @@ -37,7 +37,7 @@ export class KubernetesHomeCardComponent implements OnInit { public nodeCount$: Observable; public namespaceCount$: Observable; - constructor(private store: Store) { } + constructor(private store: Store) { } ngOnInit() { const guid = this.endpoint.guid; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts deleted file mode 100644 index 62aab202de..0000000000 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-catalog.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - StratosCatalogEndpointEntity, - StratosCatalogEntity, -} from '../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; -import { IFavoriteMetadata } from '../../../store/src/types/user-favorites.types'; -import { KubeResourceActionBuilders } from './store/action-builders/kube-resource.action-builder'; -import { - AnalysisReportsActionBuilders, - KubeDashboardActionBuilders, - KubeDeploymentActionBuilders, - KubeNamespaceActionBuilders, - KubeNodeActionBuilders, - KubePodActionBuilders, - KubeServiceActionBuilders, - KubeStatefulSetsActionBuilders, -} from './store/action-builders/kube.action-builders'; -import { - AnalysisReport, - KubernetesConfigMap, - KubernetesDeployment, - KubernetesNamespace, - KubernetesNode, - KubernetesPod, - KubernetesStatefulSet, - KubeService, -} from './store/kube.types'; -import { KubeDashboardStatus } from './store/kubernetes.effects'; - -/** - * A strongly typed collection of Kube Catalog Entities. - * This can be used to access functionality exposed by each specific type, such as get, update, delete, etc - */ -export class KubeEntityCatalog { - public endpoint: StratosCatalogEndpointEntity; - public statefulSet: StratosCatalogEntity; - public pod: StratosCatalogEntity; - public deployment: StratosCatalogEntity; - public node: StratosCatalogEntity; - public namespace: StratosCatalogEntity; - public service: StratosCatalogEntity; - public dashboard: StratosCatalogEntity; - public analysisReport: StratosCatalogEntity; - public configMap: StratosCatalogEntity; -} - -/** - * A strongly typed collection of Kube Catalog Entities. - * This can be used to access functionality exposed by each specific type, such as get, update, delete, etc - */ -export const kubeEntityCatalog: KubeEntityCatalog = new KubeEntityCatalog(); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts index 05f6848ba5..d2ea966654 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-factory.ts @@ -14,16 +14,16 @@ import { } from './store/kube.getIds'; import { KubernetesApp } from './store/kube.types'; -export const kubernetesEntityType = 'kubernetesInfo'; -export const kubernetesNodesEntityType = 'kubernetesNode'; -export const kubernetesPodsEntityType = 'kubernetesPod'; -export const kubernetesNamespacesEntityType = 'kubernetesNamespace'; -export const kubernetesServicesEntityType = 'kubernetesService'; -export const kubernetesStatefulSetsEntityType = 'kubernetesStatefulSet'; -export const kubernetesDeploymentsEntityType = 'kubernetesDeployment'; -export const kubernetesDashboardEntityType = 'kubernetesDashboard'; +export const kubernetesEntityType = 'info'; +export const kubernetesNodesEntityType = 'node'; +export const kubernetesPodsEntityType = 'pod'; +export const kubernetesNamespacesEntityType = 'namespace'; +export const kubernetesServicesEntityType = 'service'; +export const kubernetesStatefulSetsEntityType = 'statefulSet'; +export const kubernetesDeploymentsEntityType = 'deployment'; +export const kubernetesDashboardEntityType = 'dashboard'; export const analysisReportEntityType = 'analysisReport'; -export const kubernetesConfigMapEntityType = 'kubernetesConfigMap'; +export const kubernetesConfigMapEntityType = 'configMap'; export const getKubeAppId = (object: KubernetesApp) => object.name; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index a67bc47352..84b66f1da4 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -1,9 +1,12 @@ import { Compiler, Injector } from '@angular/core'; import { Validators } from '@angular/forms'; -import { entityFetchedWithoutError } from '@stratosui/store'; import { BaseEndpointAuth } from '../../../core/src/core/endpoint-auth'; import { urlValidationExpression } from '../../../core/src/core/utils.service'; +import { + OrchestratedActionBuilderConfig, + OrchestratedActionBuilders, +} from '../../../store/src/entity-catalog/action-orchestrator/action-orchestrator'; import { StratosBaseCatalogEntity, StratosCatalogEndpointEntity, @@ -28,7 +31,6 @@ import { KubernetesSATokenAuthFormComponent, } from './auth-forms/kubernetes-serviceaccount-auth-form/kubernetes-serviceaccount-auth-form.component'; import { KubeConfigRegistrationComponent } from './kube-config-registration/kube-config-registration.component'; -import { kubeEntityCatalog } from './kubernetes-entity-catalog'; import { addKubernetesEntitySchema, analysisReportEntityType, @@ -44,7 +46,6 @@ import { kubernetesServicesEntityType, kubernetesStatefulSetsEntityType, } from './kubernetes-entity-factory'; -import { KubernetesService } from './services/kubernetes.service'; import { createKubeResourceActionBuilder, KubeResourceActionBuilders, @@ -69,6 +70,7 @@ import { } from './store/action-builders/kube.action-builders'; import { getGuidFromKubePodObj } from './store/kube.getIds'; import { + AnalysisReport, KubeAPIResource, KubeResourceEntityDefinition, KubernetesConfigMap, @@ -79,6 +81,7 @@ import { KubernetesStatefulSet, KubeService, } from './store/kube.types'; +import { KubeDashboardStatus } from './store/kubernetes.effects'; import { generateWorkloadsEntities } from './workloads/store/workloads-entity-generator'; @@ -160,13 +163,14 @@ const kubeAuthTypeMap: { [type: string]: EndpointAuthTypeConfig, } = { class KubeResourceEntityHelper { - constructor(private endpointDefinition: StratosEndpointExtensionDefinition) { } - - public entities: any[] = []; - - public add(defn: KubeResourceEntityDefinition): KubeResourceEntityHelper { - - // Simplify registration by registrtering the schema in the entity cache + public static generate< + B = any, + C extends OrchestratedActionBuilderConfig = OrchestratedActionBuilders + >( + endpointDefinition: StratosEndpointExtensionDefinition, + defn: KubeResourceEntityDefinition + ): StratosCatalogEntity { + // Simplify registration by registering the schema in the entity cache addKubernetesEntitySchema(defn.type, new KubernetesEntitySchema(defn.type, {}, { idAttribute: getGuidFromKubePodObj })); defn.labelTab = defn.labelTab || defn.labelPlural || `${defn.label}s`; @@ -177,437 +181,408 @@ class KubeResourceEntityHelper { const d: IStratosEntityDefinition = { ...defn, - endpoint: this.endpointDefinition, + endpoint: endpointDefinition, schema: kubernetesEntityFactory(defn.type), iconFont: defn.iconFont || 'stratos-icons', labelPlural: defn.labelPlural || `${defn.label}s` }; if (defn.getKubeCatalogEntity) { - kubeEntityCatalog[defn.kubeCatalogEntity] = defn.getKubeCatalogEntity(d); + return defn.getKubeCatalogEntity(d); } else { - kubeEntityCatalog[defn.kubeCatalogEntity] = new StratosCatalogEntity(d, { - actionBuilders: createKubeResourceActionBuilder(d.type) + return new StratosCatalogEntity(d, { + actionBuilders: createKubeResourceActionBuilder(d.type) as unknown as C }); } - - this.entities.push(kubeEntityCatalog[defn.kubeCatalogEntity]); - return this; } } -export function generateKubernetesEntities(): StratosBaseCatalogEntity[] { - const endpointDefinition: StratosEndpointExtensionDefinition = { - type: KUBERNETES_ENDPOINT_TYPE, - label: 'Kubernetes', - labelPlural: 'Kubernetes', - icon: 'kubernetes', - iconFont: 'stratos-icons', - logoUrl: '/core/assets/custom/kubernetes.svg', - authTypes: [ - kubeAuthTypeMap[KubeEndpointAuthTypes.CERT_AUTH], - kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG], - BaseEndpointAuth.UsernamePassword, - kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN], - ], - getEndpointIdFromEntity: (entity) => entity.kubeGuid, - renderPriority: 4, - urlValidationRegexString: urlValidationExpression, - subTypes: [ - { - type: 'config', - label: 'Import Kubeconfig', - authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG]], - logoUrl: '/core/assets/custom/kube_import.png', - renderPriority: 3, - registrationComponent: KubeConfigRegistrationComponent, - }, - { - type: 'caasp', - label: 'SUSE CaaS Platform', - labelShort: 'CaaSP', - authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], - logoUrl: '/core/assets/custom/caasp.png', - renderPriority: 5, - }, { - type: 'aks', - label: 'Azure AKS', - labelShort: 'AKS', - authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG_AZ], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], - logoUrl: '/core/assets/custom/aks.svg', - renderPriority: 6 - }, { - type: 'eks', - label: 'Amazon EKS', - labelShort: 'EKS', - authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.AWS_IAM], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], - logoUrl: '/core/assets/custom/eks.svg', - renderPriority: 6 - }, { - type: 'gke', - label: 'Google Kubernetes Engine', - labelShort: 'GKE', - authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.GKE], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], - logoUrl: '/core/assets/custom/gke.svg', - renderPriority: 6 - }, { - type: 'k3s', - label: 'K3S', - labelShort: 'K3S', - authTypes: [BaseEndpointAuth.UsernamePassword, kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], - logoUrl: '/core/assets/custom/k3s.svg', - renderPriority: 6 - }], - homeCard: { - component: (compiler: Compiler, injector: Injector) => import('./home/kubernetes-home-card.module').then((m) => { - return compiler.compileModuleAndAllComponentsAsync(m.KubernetesHomeCardModule).then(cm => { - const mod = cm.ngModuleFactory.create(injector); - return mod.instance.createHomeCard(mod.componentFactoryResolver); - }); - }), - fullView: false - } - }; - return [ - generateEndpointEntity(endpointDefinition), - generateStatefulSetsEntity(endpointDefinition), - ...generateKubeResourceEntities(endpointDefinition), - generateDeploymentsEntity(endpointDefinition), - generateNodesEntity(endpointDefinition), - // generateNamespacesEntity(endpointDefinition), - // generateServicesEntity(endpointDefinition), - generateDashboardEntity(endpointDefinition), - generateAnalysisReportsEntity(endpointDefinition), - generateMetricEntity(endpointDefinition), - ...generateWorkloadsEntities(endpointDefinition) - ]; -} -function generateEndpointEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - kubeEntityCatalog.endpoint = new StratosCatalogEndpointEntity( - endpointDefinition, - favorite => `/kubernetes/${favorite.endpointId}` - ); - return kubeEntityCatalog.endpoint; -} +/** + * A strongly typed collection of Kube Catalog Entities. + * This can be used to access functionality exposed by each specific type, such as get, update, delete, etc + */ +export class KubeEntityCatalog { + + public endpoint: StratosCatalogEndpointEntity; + public statefulSet: StratosCatalogEntity; + public pod: StratosCatalogEntity; + public deployment: StratosCatalogEntity; + public node: StratosCatalogEntity; + public namespace: StratosCatalogEntity; + public service: StratosCatalogEntity; + public dashboard: StratosCatalogEntity; + public analysisReport: StratosCatalogEntity; + public configMap: StratosCatalogEntity; + public metrics: StratosCatalogEntity; + + public secrets: StratosCatalogEntity; + public pvc: StratosCatalogEntity; + public storage: StratosCatalogEntity; + public pv: StratosCatalogEntity; + public replicaSet: StratosCatalogEntity; + public clusterRole: StratosCatalogEntity; + public serviceAccount: StratosCatalogEntity; + public role: StratosCatalogEntity; + public job: StratosCatalogEntity; + + private workloadEntities: StratosBaseCatalogEntity[]; + + constructor() { + const endpointDef: StratosEndpointExtensionDefinition = { + type: KUBERNETES_ENDPOINT_TYPE, + label: 'Kubernetes', + labelPlural: 'Kubernetes', + icon: 'kubernetes', + iconFont: 'stratos-icons', + logoUrl: '/core/assets/custom/kubernetes.svg', + authTypes: [ + kubeAuthTypeMap[KubeEndpointAuthTypes.CERT_AUTH], + kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG], + BaseEndpointAuth.UsernamePassword, + kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN], + ], + getEndpointIdFromEntity: (entity) => entity.kubeGuid, + renderPriority: 4, + urlValidationRegexString: urlValidationExpression, + subTypes: [ + { + type: 'config', + label: 'Import Kubeconfig', + authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG]], + logoUrl: '/core/assets/custom/kube_import.png', + renderPriority: 3, + registrationComponent: KubeConfigRegistrationComponent, + }, + { + type: 'caasp', + label: 'SUSE CaaS Platform', + labelShort: 'CaaSP', + authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], + logoUrl: '/core/assets/custom/caasp.png', + renderPriority: 5, + }, { + type: 'aks', + label: 'Azure AKS', + labelShort: 'AKS', + authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.CONFIG_AZ], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], + logoUrl: '/core/assets/custom/aks.svg', + renderPriority: 6 + }, { + type: 'eks', + label: 'Amazon EKS', + labelShort: 'EKS', + authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.AWS_IAM], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], + logoUrl: '/core/assets/custom/eks.svg', + renderPriority: 6 + }, { + type: 'gke', + label: 'Google Kubernetes Engine', + labelShort: 'GKE', + authTypes: [kubeAuthTypeMap[KubeEndpointAuthTypes.GKE], kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], + logoUrl: '/core/assets/custom/gke.svg', + renderPriority: 6 + }, { + type: 'k3s', + label: 'K3S', + labelShort: 'K3S', + authTypes: [BaseEndpointAuth.UsernamePassword, kubeAuthTypeMap[KubeEndpointAuthTypes.TOKEN]], + logoUrl: '/core/assets/custom/k3s.svg', + renderPriority: 6 + }], + homeCard: { + component: (compiler: Compiler, injector: Injector) => import('./home/kubernetes-home-card.module').then((m) => { + return compiler.compileModuleAndAllComponentsAsync(m.KubernetesHomeCardModule).then(cm => { + const mod = cm.ngModuleFactory.create(injector); + return mod.instance.createHomeCard(mod.componentFactoryResolver); + }); + }), + fullView: false + } + }; -function generateStatefulSetsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesStatefulSetsEntityType, - schema: kubernetesEntityFactory(kubernetesStatefulSetsEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.statefulSet = new StratosCatalogEntity( - definition, { - actionBuilders: kubeStatefulSetsActionBuilders - }); - return kubeEntityCatalog.statefulSet; -} + this.endpoint = new StratosCatalogEndpointEntity( + endpointDef, + favorite => `/kubernetes/${favorite.endpointId}` + ); + + this.statefulSet = this.generateStatefulSetsEntity(endpointDef); + this.pod = KubeResourceEntityHelper.generate(endpointDef, { + type: kubernetesPodsEntityType, + icon: 'pod', + label: 'Pod', + apiVersion: '/api/v1', + apiName: 'pods', + apiNamespaced: true, + listConfig: 'k8s-pods', + getKubeCatalogEntity: (definition) => new StratosCatalogEntity( + definition, { actionBuilders: kubePodActionBuilders } + ) + }); + this.deployment = this.generateDeploymentsEntity(endpointDef); + this.node = this.generateNodesEntity(endpointDef); + this.namespace = KubeResourceEntityHelper.generate(endpointDef, { + type: kubernetesNamespacesEntityType, + icon: 'namespace', + label: 'Namespace', + apiVersion: '/api/v1', + apiName: 'namespaces', + apiNamespaced: false, + hidden: true, + getKubeCatalogEntity: (definition) => new StratosCatalogEntity( + definition, { actionBuilders: kubeNamespaceActionBuilders } + ), + listColumns: [ + { + header: 'Status', + field: 'status.phase', + sort: true + } + ] + }); + this.service = KubeResourceEntityHelper.generate(endpointDef, { + type: kubernetesServicesEntityType, + icon: 'service', + label: 'Service', + apiVersion: '/api/v1', + apiName: 'service', + apiNamespaced: true, + listConfig: 'k8s-services', + getKubeCatalogEntity: (definition) => new StratosCatalogEntity( + definition, { + actionBuilders: kubeServiceActionBuilders + } + ) + }); + this.dashboard = this.generateDashboardEntity(endpointDef); + this.analysisReport = this.generateAnalysisReportsEntity(endpointDef); + this.configMap = KubeResourceEntityHelper.generate(endpointDef, { + type: kubernetesConfigMapEntityType, + icon: 'config_maps', + label: 'Config Map', + apiVersion: '/api/v1', + apiName: 'configmaps', + listColumns: [ + { + header: 'Data Keys', + field: (row: KubernetesConfigMap) => `${Object.keys(row.data).length}` + }, + ] + }); + this.metrics = this.generateMetricEntity(endpointDef); + + + this.secrets = KubeResourceEntityHelper.generate(endpointDef, { + type: 'secrets', + icon: 'config_maps', + label: 'Secret', + apiVersion: '/api/v1', + apiName: 'secrets', + listColumns: [ + { + header: 'Data Keys', + field: (row: KubernetesConfigMap) => `${Object.keys(row.data).length}` + }, + ], + }); + this.pvc = KubeResourceEntityHelper.generate(endpointDef, { + type: 'persistentVolumeClaims', + icon: 'job', + label: 'Persistent Volume Claim', + labelTab: 'PVCs', + apiVersion: '/api/v1', + apiName: 'persistentvolumeclaims', + listColumns: [ + { + header: 'Storage Class', + field: 'spec.storageClassName', + sort: true + }, + { + header: 'Phase', + field: 'status.phase', + sort: true + }, + { + header: 'Capacity', + field: 'status.capacity.storage', + } + ] + }); + this.storage = KubeResourceEntityHelper.generate(endpointDef, { + type: 'storageClass', + icon: 'storage_class', + label: 'Storage Class', + labelPlural: 'Storage Classes', + apiVersion: '/apis/storage.k8s.io/v1', + apiName: 'storageclasses', + apiNamespaced: false, + listColumns: [ + { + header: 'Provisioner', + field: 'provisioner', + sort: true + }, + { + header: 'Reclaim Policy', + field: 'reclaimPolicy', + sort: true + }, + { + header: 'Binding Mode', + field: 'volumeBindingMode', + sort: true + } + ] + }); + this.pv = KubeResourceEntityHelper.generate(endpointDef, { + type: 'persistentVolume', + icon: 'persistent_volume', + label: 'Persistent Volume', + apiVersion: '/api/v1', + apiName: 'persistentvolumes', + apiNamespaced: false, + }); + this.replicaSet = KubeResourceEntityHelper.generate(endpointDef, { + type: 'replicaSet', + icon: 'replica_set', + label: 'Replica Set', + apiVersion: '/apis/apps/v1', + apiName: 'replicasets', + listColumns: [ + { + header: 'Replicas', + field: 'spec.replicas', + sort: true + }, + ] + }); + this.clusterRole = KubeResourceEntityHelper.generate(endpointDef, { + type: 'clusterRole', + icon: 'cluster_role', + label: 'Cluster Role', + apiVersion: '/apis/rbac.authorization.k8s.io/v1', + apiName: 'clusterroles', + apiNamespaced: false, + }); + this.serviceAccount = KubeResourceEntityHelper.generate(endpointDef, { + type: 'serviceAccount', + icon: 'replica_set', + label: 'Service Account', + apiVersion: '/api/v1', + apiName: 'serviceaccounts', + }); + this.role = KubeResourceEntityHelper.generate(endpointDef, { + type: 'role', + icon: 'role_binding', + label: 'Role', + apiVersion: '/apis/rbac.authorization.k8s.io/v1', + apiName: 'roles', + }); + this.job = KubeResourceEntityHelper.generate(endpointDef, { + type: 'job', + icon: 'job', + label: 'Job', + apiVersion: '/apis/batch/v1', + apiName: 'jobs', + }); + + this.workloadEntities = generateWorkloadsEntities(endpointDef); + } -function generateDeploymentsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesDeploymentsEntityType, - schema: kubernetesEntityFactory(kubernetesDeploymentsEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.deployment = new StratosCatalogEntity( - definition, { - actionBuilders: kubeDeploymentActionBuilders - }); - return kubeEntityCatalog.deployment; -} + public allKubeEntities(): StratosBaseCatalogEntity[] { + return [ + this.endpoint, + this.statefulSet, + this.pod, + this.deployment, + this.node, + this.namespace, + this.service, + this.dashboard, + this.analysisReport, + this.configMap, + this.metrics, + this.secrets, + this.pvc, + this.storage, + this.pv, + this.replicaSet, + this.clusterRole, + this.serviceAccount, + this.role, + this.job, + ...this.workloadEntities + ]; + } -function generateNodesEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesNodesEntityType, - schema: kubernetesEntityFactory(kubernetesNodesEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.node = new StratosCatalogEntity(definition, { - actionBuilders: kubeNodeActionBuilders - }); - return kubeEntityCatalog.node; -} + private generateStatefulSetsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { + return new StratosCatalogEntity( + { + type: kubernetesStatefulSetsEntityType, + schema: kubernetesEntityFactory(kubernetesStatefulSetsEntityType), + endpoint: endpointDefinition + }, { + actionBuilders: kubeStatefulSetsActionBuilders + }); + } -function generateNamespacesEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesNamespacesEntityType, - schema: kubernetesEntityFactory(kubernetesNamespacesEntityType), - endpoint: endpointDefinition, - label: 'Namespace', - icon: 'namespace', - iconFont: 'stratos-icons', - }; - kubeEntityCatalog.namespace = new StratosCatalogEntity( - definition, { - actionBuilders: kubeNamespaceActionBuilders, - entityBuilder: { - getIsValid: (fav) => kubeEntityCatalog.namespace.api.get(fav.metadata.name, fav.endpointId).pipe(entityFetchedWithoutError()), - getMetadata: (namespace: any) => { - return { - endpointId: namespace.kubeGuid, - guid: namespace.metadata.uid, - kubeGuid: namespace.kubeGuid, - name: namespace.metadata.name, - }; - }, - getLink: favorite => `/kubernetes/${favorite.endpointId}/namespaces/${favorite.metadata.name}`, - getGuid: namespace => namespace.metadata.uid, - } - }); - return kubeEntityCatalog.namespace; -} + private generateDeploymentsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { + return new StratosCatalogEntity( + { + type: kubernetesDeploymentsEntityType, + schema: kubernetesEntityFactory(kubernetesDeploymentsEntityType), + endpoint: endpointDefinition + }, { + actionBuilders: kubeDeploymentActionBuilders + }); + } -function generateServicesEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesServicesEntityType, - schema: kubernetesEntityFactory(kubernetesServicesEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.service = new StratosCatalogEntity(definition, { - actionBuilders: kubeServiceActionBuilders - }); - return kubeEntityCatalog.service; -} + private generateNodesEntity(endpointDefinition: StratosEndpointExtensionDefinition) { + return new StratosCatalogEntity({ + type: kubernetesNodesEntityType, + schema: kubernetesEntityFactory(kubernetesNodesEntityType), + endpoint: endpointDefinition + }, { + actionBuilders: kubeNodeActionBuilders + }); + } -function generateDashboardEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: kubernetesDashboardEntityType, - schema: kubernetesEntityFactory(kubernetesDashboardEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.dashboard = new StratosCatalogEntity(definition, { - actionBuilders: kubeDashboardActionBuilders - }); - return kubeEntityCatalog.dashboard; -} + private generateDashboardEntity(endpointDefinition: StratosEndpointExtensionDefinition) { + return new StratosCatalogEntity({ + type: kubernetesDashboardEntityType, + schema: kubernetesEntityFactory(kubernetesDashboardEntityType), + endpoint: endpointDefinition + }, { + actionBuilders: kubeDashboardActionBuilders + }); + } -function generateAnalysisReportsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition = { - type: analysisReportEntityType, - schema: kubernetesEntityFactory(analysisReportEntityType), - endpoint: endpointDefinition - }; - kubeEntityCatalog.analysisReport = new StratosCatalogEntity(definition, { - actionBuilders: analysisReportsActionBuilders - }); - return kubeEntityCatalog.analysisReport; -} + private generateAnalysisReportsEntity(endpointDefinition: StratosEndpointExtensionDefinition) { + return new StratosCatalogEntity({ + type: analysisReportEntityType, + schema: kubernetesEntityFactory(analysisReportEntityType), + endpoint: endpointDefinition + }, { + actionBuilders: analysisReportsActionBuilders + }); + } + + private generateMetricEntity(endpointDefinition: StratosEndpointExtensionDefinition) { + return new StratosCatalogEntity({ + type: metricEntityType, + schema: kubernetesEntityFactory(metricEntityType), + label: 'Kubernetes Metric', + labelPlural: 'Kubernetes Metrics', + endpoint: endpointDefinition, + }); + } -function generateMetricEntity(endpointDefinition: StratosEndpointExtensionDefinition) { - const definition: IStratosEntityDefinition = { - type: metricEntityType, - schema: kubernetesEntityFactory(metricEntityType), - label: 'Kubernetes Metric', - labelPlural: 'Kubernetes Metrics', - endpoint: endpointDefinition, - }; - return new StratosCatalogEntity(definition); -} -// ============================================================================================================= -// Kubernetes Resources using generic resource pattern -// ============================================================================================================= - -function generateKubeResourceEntities(endpointDefinition: StratosEndpointExtensionDefinition) { - - const entities = new KubeResourceEntityHelper(endpointDefinition); - - entities.add({ - type: kubernetesNamespacesEntityType, - icon: 'namespace', - label: 'Namespace', - apiVersion: '/api/v1', - apiName: 'namespaces', - apiNamespaced: false, - kubeCatalogEntity: 'namespace', - hidden: true, - getKubeCatalogEntity: (definition) => new StratosCatalogEntity( - definition, { actionBuilders: kubeNamespaceActionBuilders } - ), - listColumns: [ - { - header: 'Status', - field: 'status.phase', - sort: true - } - ] - }); - - entities.add({ - type: kubernetesPodsEntityType, - icon: 'pod', - label: 'Pod', - apiVersion: '/api/v1', - apiName: 'pods', - apiNamespaced: true, - kubeCatalogEntity: 'pod', - listConfig: 'k8s-pods', - getKubeCatalogEntity: (definition) => new StratosCatalogEntity( - definition, { actionBuilders: kubePodActionBuilders } - ) - }); - - entities.add({ - type: kubernetesServicesEntityType, - icon: 'service', - label: 'Service', - apiVersion: '/api/v1', - apiName: 'service', - apiNamespaced: true, - kubeCatalogEntity: 'service', - listConfig: 'k8s-services', - getKubeCatalogEntity: (definition) => new StratosCatalogEntity( - definition, { actionBuilders: kubeServiceActionBuilders } - ) - }); - - entities.add({ - type: kubernetesConfigMapEntityType, - icon: 'config_maps', - label: 'Config Map', - apiVersion: '/api/v1', - apiName: 'configmaps', - kubeCatalogEntity: 'configMap', - listColumns: [ - { - header: 'Data Keys', - field: (row: KubernetesConfigMap) => `${Object.keys(row.data).length}` - }, - ] - }); - - entities.add({ - type: 'kubernetesSecrets', - icon: 'config_maps', - label: 'Secret', - apiVersion: '/api/v1', - apiName: 'secrets', - kubeCatalogEntity: 'secrets', - listColumns: [ - { - header: 'Data Keys', - field: (row: KubernetesConfigMap) => `${Object.keys(row.data).length}` - }, - ] - }); - - entities.add({ - type: 'kubernetesPersistentVolumeClaims', - icon: 'job', - label: 'Persistent Volume Claim', - labelTab: 'PVCs', - apiVersion: '/api/v1', - apiName: 'persistentvolumeclaims', - kubeCatalogEntity: 'pvcs', - listColumns: [ - { - header: 'Storage Class', - field: 'spec.storageClassName', - sort: true - }, - { - header: 'Phase', - field: 'status.phase', - sort: true - }, - { - header: 'Capacity', - field: 'status.capacity.storage', - } - ] - }); - - entities.add({ - type: 'kubernetesStorageClass', - icon: 'storage_class', - label: 'Storage Class', - labelPlural: 'Storage Classes', - apiVersion: '/apis/storage.k8s.io/v1', - apiName: 'storageclasses', - apiNamespaced: false, - kubeCatalogEntity: 'storageClass', - listColumns: [ - { - header: 'Provisioner', - field: 'provisioner', - sort: true - }, - { - header: 'Reclaim Policy', - field: 'reclaimPolicy', - sort: true - }, - { - header: 'Binding Mode', - field: 'volumeBindingMode', - sort: true - } - ] - }); - - entities.add({ - type: 'kubernetesPersistentVolume', - icon: 'persistent_volume', - label: 'Persistent Volume', - apiVersion: '/api/v1', - apiName: 'persistentvolumes', - apiNamespaced: false, - kubeCatalogEntity: 'persistentVolumes' - }); - - entities.add({ - type: 'kubernetesReplicaSet', - icon: 'replica_set', - label: 'Replica Set', - apiVersion: '/apis/apps/v1', - apiName: 'replicasets', - kubeCatalogEntity: 'replicaSets', - listColumns: [ - { - header: 'Replicas', - field: 'spec.replicas', - sort: true - }, - ] - }); - - entities.add({ - type: 'kubernetesClusterRole', - icon: 'cluster_role', - label: 'Cluster Role', - apiVersion: '/apis/rbac.authorization.k8s.io/v1', - apiName: 'clusterroles', - apiNamespaced: false, - kubeCatalogEntity: 'clusterroles' - }); - - entities.add({ - type: 'kubernetesServiceAccount', - icon: 'replica_set', - label: 'Service Account', - apiVersion: '/api/v1', - apiName: 'serviceaccounts', - kubeCatalogEntity: 'serviceaccounts' - }); - - entities.add({ - type: 'kubernetesRole', - icon: 'role_binding', - label: 'Role', - apiVersion: '/apis/rbac.authorization.k8s.io/v1', - apiName: 'roles', - kubeCatalogEntity: 'role' - }); - - entities.add({ - type: 'kubernetesJob', - icon: 'job', - label: 'Job', - apiVersion: '/apis/batch/v1', - apiName: 'jobs', - kubeCatalogEntity: 'job' - }); - - return entities.entities; } + +/** + * A strongly typed collection of Kube Catalog Entities. + * This can be used to access functionality exposed by each specific type, such as get, update, delete, etc + */ +export const kubeEntityCatalog: KubeEntityCatalog = new KubeEntityCatalog(); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts index cf7c8648f5..044a84b05b 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-namespace/kubernetes-namespace.component.ts @@ -5,7 +5,6 @@ import { filter, map } from 'rxjs/operators'; import { IHeaderBreadcrumb } from '../../../../core/src/shared/components/page-header/page-header.types'; import { UserFavoriteManager } from '../../../../store/src/user-favorite-manager'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; import { kubernetesNamespacesEntityType } from '../kubernetes-entity-factory'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; @@ -13,7 +12,6 @@ import { KubernetesNamespaceService } from '../services/kubernetes-namespace.ser import { KubernetesAnalysisService } from '../services/kubernetes.analysis.service'; import { KubernetesService } from '../services/kubernetes.service'; import { IFavoriteMetadata } from './../../../../store/src/types/user-favorites.types'; -import { KubeResourceEntityDefinition } from '../store/kube.types'; import { KUBERNETES_ENDPOINT_TYPE } from './../kubernetes-entity-factory'; @Component({ @@ -81,28 +79,27 @@ export class KubernetesNamespaceComponent { ); private getTabsFromEntityConfig(namespaced: boolean = true) { - const entityNames = Object.getOwnPropertyNames(kubeEntityCatalog); - const tabsFromRouterConfig = []; + return []; + // const entityNames = Object.getOwnPropertyNames(kubeEntityCatalog); + // const tabsFromRouterConfig = []; - // Get the tabs from the router configuration - entityNames.forEach(key => { - // See if we can find an entity for the key - const catalogEntity = kubeEntityCatalog[key]; - if (catalogEntity) { - const defn = catalogEntity.definition as KubeResourceEntityDefinition; - if (defn.apiNamespaced === namespaced) { - tabsFromRouterConfig.push({ - link: defn.route || `resource/${key}`, - label: defn.labelTab || defn.labelPlural, - icon: defn.icon, - iconFont: defn.iconFont, - }); - } - } - }); + // // Get the tabs from the router configuration + // kubeEntityCatalog.allKubeEntities().forEach(catalogEntity => { + // if (catalogEntity) { + // const defn = catalogEntity.definition as KubeResourceEntityDefinition; + // if (defn.apiNamespaced === namespaced) { + // tabsFromRouterConfig.push({ + // link: defn.route || `resource/${key}`, + // label: defn.labelTab || defn.labelPlural, + // icon: defn.icon, + // iconFont: defn.iconFont, + // }); + // } + // } + // }); - tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); - return tabsFromRouterConfig; + // tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); + // return tabsFromRouterConfig; } } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index e7e0d5a261..361fbf74ac 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -13,7 +13,9 @@ import { } from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; import { ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { entityCatalog } from '../../../../../store/src/public-api'; +import { KUBERNETES_ENDPOINT_TYPE } from '../../kubernetes-entity-factory'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { KubernetesListConfigService } from '../../kubernetes-list-service'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { @@ -69,7 +71,7 @@ export class KubernetesResourceListComponent implements OnDestroy { this.entityCatalogKey = routeParts[routeParts.length - 1]; } - const catalogEntity = kubeEntityCatalog[this.entityCatalogKey]; + const catalogEntity = entityCatalog.getEntityFromKey(entityCatalog.getEntityKey(KUBERNETES_ENDPOINT_TYPE, this.entityCatalogKey)); if (!catalogEntity) { console.error(`Can not find catalog entity for Kubernetes entity ${this.entityCatalogKey}`); return; @@ -146,14 +148,14 @@ export class KubernetesResourceListComponent implements OnDestroy { cellFlex: '3', cellConfig: (resource): TableCellSidePanelConfig => { return ({ - text: resource.metadata.name, - sidePanelComponent: KubernetesResourceViewerComponent, - sidePanelConfig: { - title: resource.metadata.name, - resourceKind: definition.label, - resource$: of(resource) - } - }); + text: resource.metadata.name, + sidePanelComponent: KubernetesResourceViewerComponent, + sidePanelConfig: { + title: resource.metadata.name, + resourceKind: definition.label, + resource$: of(resource) + } + }); } }, // Namespace @@ -201,13 +203,13 @@ export class KubernetesResourceListComponent implements OnDestroy { cellFlex: cell.flex || '1' }; - if (typeof(cell.field) === 'string') { + if (typeof (cell.field) === 'string') { tableCell.cellDefinition.valuePath = cell.field as string; } else { tableCell.cellDefinition.getValue = cell.field as SimpleColumnValueGetter; } - if (cell.sort && typeof(cell.field) === 'string') { + if (cell.sort && typeof (cell.field) === 'string') { tableCell.sort = { type: 'sort', orderKey: tableCell.columnId, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts index 0d21ec458f..786015275c 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts @@ -10,7 +10,7 @@ import { KubernetesEndpointService } from '../services/kubernetes-endpoint.servi import { KubernetesAnalysisService } from '../services/kubernetes.analysis.service'; import { KubernetesService } from '../services/kubernetes.service'; import { KubeResourceEntityDefinition } from '../store/kube.types'; -import { kubeEntityCatalog } from './../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from './../kubernetes-entity-generator'; @Component({ selector: 'app-kubernetes-tab-base', @@ -52,7 +52,6 @@ export class KubernetesTabBaseComponent implements OnInit { { link: 'analysis', label: 'Analysis', icon: 'assignment', hidden$: this.analysisService.hideAnalysis$ }, { link: '-', label: 'Cluster' }, { link: 'nodes', label: 'Nodes', icon: 'node', iconFont: 'stratos-icons' }, - { link: 'resource/namespace', label: 'Namespaces', icon: 'namespace', iconFont: 'stratos-icons' }, ...this.getTabsFromEntityConfig(false), { link: '-', label: 'Resources' }, ...this.getTabsFromEntityConfig(true) @@ -61,18 +60,15 @@ export class KubernetesTabBaseComponent implements OnInit { private getTabsFromEntityConfig(namespaced: boolean = true) { - const entityNames = Object.getOwnPropertyNames(kubeEntityCatalog); const tabsFromRouterConfig = []; // Get the tabs from the router configuration - entityNames.forEach(key => { - // See if we can find an entity for the key - const catalogEntity = kubeEntityCatalog[key]; + kubeEntityCatalog.allKubeEntities().forEach(catalogEntity => { if (catalogEntity) { - const defn = catalogEntity.definition as KubeResourceEntityDefinition; - if (defn.apiNamespaced === namespaced && !defn.hidden) { + const defn = catalogEntity.definition as unknown as KubeResourceEntityDefinition; + if (defn.apiNamespaced === namespaced) { tabsFromRouterConfig.push({ - link: defn.route || `resource/${key}`, + link: `resource/${catalogEntity.type}`, label: defn.labelTab || defn.labelPlural, icon: defn.icon, iconFont: defn.iconFont, @@ -85,33 +81,34 @@ export class KubernetesTabBaseComponent implements OnInit { return tabsFromRouterConfig; } - private getTabsFromRouterConfig(namespaced: boolean = true) { - const childRoutes = this.route.snapshot.routeConfig.children; - const tabsFromRouterConfig = []; + // TODO: RC Q This is unused + // private getTabsFromRouterConfig(namespaced: boolean = true) { + // const childRoutes = this.route.snapshot.routeConfig.children; + // const tabsFromRouterConfig = []; - // Get the tabs from the router configuration - childRoutes.forEach( r => { - if (r.path.length > 0) { - // See if we can find an entity for the key - const key = r.data ? (r.data.entityCatalogKey ? r.data.entityCatalogKey : r.path) : r.path; - const catalogEntity = kubeEntityCatalog[key]; - if (catalogEntity) { - const defn = catalogEntity.definition as KubeResourceEntityDefinition; - if (defn.apiNamespaced === namespaced) { - tabsFromRouterConfig.push({ - link: defn.route ? defn.route : `resource/${r.path}`, - label: defn.labelTab || defn.labelPlural, - icon: defn.icon, - iconFont: defn.iconFont, - }); - } - } - } - }); + // // Get the tabs from the router configuration + // childRoutes.forEach(r => { + // if (r.path.length > 0) { + // // See if we can find an entity for the key + // const key = r.data ? (r.data.entityCatalogKey ? r.data.entityCatalogKey : r.path) : r.path; + // const catalogEntity = kubeEntityCatalog[key]; + // if (catalogEntity) { + // const defn = catalogEntity.definition as KubeResourceEntityDefinition; + // if (defn.apiNamespaced === namespaced) { + // tabsFromRouterConfig.push({ + // link: defn.route ? defn.route : `resource/${r.path}`, + // label: defn.labelTab || defn.labelPlural, + // icon: defn.icon, + // iconFont: defn.iconFont, + // }); + // } + // } + // } + // }); - tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); - return tabsFromRouterConfig; - } + // tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); + // return tabsFromRouterConfig; + // } ngOnInit() { this.isFetching$ = this.kubeEndpointService.endpoint$.pipe( diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts index 5945118c8f..55f487759c 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.setup.module.ts @@ -40,9 +40,8 @@ import { import { KubeConfigTableUserSelectComponent, } from './kube-config-registration/kube-config-selection/kube-config-table-user-select/kube-config-table-user-select.component'; -import { kubeEntityCatalog } from './kubernetes-entity-catalog'; import { KUBERNETES_ENDPOINT_TYPE } from './kubernetes-entity-factory'; -import { generateKubernetesEntities } from './kubernetes-entity-generator'; +import { kubeEntityCatalog } from './kubernetes-entity-generator'; import { KubernetesListConfigService } from './kubernetes-list-service'; import { BaseKubeGuid } from './kubernetes-page.types'; import { KubernetesStoreModule } from './kubernetes.store.module'; @@ -50,7 +49,7 @@ import { KubernetesEndpointService } from './services/kubernetes-endpoint.servic @NgModule({ imports: [ - EntityCatalogModule.forFeature(generateKubernetesEntities), + EntityCatalogModule.forFeature(() => kubeEntityCatalog.allKubeEntities()), CoreModule, CommonModule, SharedModule, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/analysis-reports-list-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/analysis-reports-list-source.ts index 0b1cccec2f..2e3b1e14b6 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/analysis-reports-list-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/analysis-reports-list-source.ts @@ -8,7 +8,7 @@ import { first, map } from 'rxjs/operators'; import { AppState } from '../../../../store/src/public-api'; import { isFetchingPage } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; import { GetAnalysisReports } from '../store/analysis.actions'; import { AnalysisReport } from '../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-data-source.ts index 8ed8c1128c..8d994ac5c5 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-pods/kubernetes-namespace-pods-data-source.ts @@ -3,8 +3,8 @@ import { Store } from '@ngrx/store'; import { ListDataSource } from '../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { AppState } from '../../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; import { kubernetesEntityFactory, kubernetesPodsEntityType } from '../../kubernetes-entity-factory'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubernetesNamespaceService } from '../../services/kubernetes-namespace.service'; import { KubernetesPod } from '../../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts index bf533daf17..a86463c08b 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts @@ -2,7 +2,7 @@ import { Store } from '@ngrx/store'; import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { AppState } from '../../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubeService } from '../../store/kube.types'; import { BaseKubernetesServicesDataSource } from '../kubernetes-services/kubernetes-services-data-source'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespaces/kubernetes-namespaces-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespaces/kubernetes-namespaces-data-source.ts index c95efb1f23..118afa09ff 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespaces/kubernetes-namespaces-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespaces/kubernetes-namespaces-data-source.ts @@ -4,8 +4,8 @@ import { ListDataSource } from '../../../../../core/src/shared/components/list/d import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { getPaginationKey } from '../../../../../store/src/actions/pagination.actions'; import { AppState } from '../../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; import { kubernetesNamespacesEntityType } from '../../kubernetes-entity-factory'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubernetesNamespace } from '../../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-data-source.ts index 6ff5893190..426a6861d8 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-node-pods/kubernetes-node-pods-data-source.ts @@ -3,7 +3,7 @@ import { Store } from '@ngrx/store'; import { ListDataSource } from '../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { AppState } from '../../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubernetesNodeService } from '../../services/kubernetes-node.service'; import { KubernetesPod } from '../../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-nodes/kubernetes-nodes-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-nodes/kubernetes-nodes-data-source.ts index 2550ea4e65..5e48788fe0 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-nodes/kubernetes-nodes-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-nodes/kubernetes-nodes-data-source.ts @@ -8,8 +8,8 @@ import { import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { getPaginationKey } from '../../../../../store/src/actions/pagination.actions'; import { AppState } from '../../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; import { kubernetesNodesEntityType } from '../../kubernetes-entity-factory'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubernetesNode } from '../../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pod-containers/kubernetes-pod-containers.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pod-containers/kubernetes-pod-containers.component.ts index c460e8aa4b..0463f79322 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pod-containers/kubernetes-pod-containers.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pod-containers/kubernetes-pod-containers.component.ts @@ -5,7 +5,7 @@ import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; import { CardCell } from '../../../../../../core/src/shared/components/list/list.types'; -import { kubeEntityCatalog } from '../../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../../kubernetes-entity-generator'; import { Container, ContainerState, ContainerStatus, InitContainer, KubernetesPod } from '../../../store/kube.types'; export interface ContainerForTable { diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-data-source.ts index dd6b22afcb..096f5a79c6 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-data-source.ts @@ -3,7 +3,7 @@ import { Store } from '@ngrx/store'; import { ListDataSource } from '../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; import { IListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { AppState } from '../../../../../store/src/public-api'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { BaseKubeGuid } from '../../kubernetes-page.types'; import { KubernetesPod } from '../../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/pod-metrics/pod-metrics.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/pod-metrics/pod-metrics.component.ts index 6d0801f813..752b2e4e93 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/pod-metrics/pod-metrics.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/pod-metrics/pod-metrics.component.ts @@ -14,7 +14,7 @@ import { IHeaderBreadcrumb } from '../../../../core/src/shared/components/page-h import { EntityInfo } from '../../../../store/src/types/api.types'; import { ChartSeries, IMetricMatrixResult } from '../../../../store/src/types/base-metric.types'; import { IMetricApplication } from '../../../../store/src/types/metric.types'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { formatAxisCPUTime, formatCPUTime } from '../kubernetes-metrics.helpers'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-endpoint.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-endpoint.service.ts index 8ca622e099..034233dae7 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-endpoint.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-endpoint.service.ts @@ -11,7 +11,7 @@ import { EndpointModel } from '../../../../store/src/public-api'; import { PaginationObservables } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.types'; import { EntityInfo } from '../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../store/src/types/endpoint.types'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { KubernetesDeployment, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-namespace.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-namespace.service.ts index ef31dc8889..dbc66755fd 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-namespace.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-namespace.service.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { getIdFromRoute } from '../../../../core/src/core/utils.service'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { KubernetesNamespace } from '../store/kube.types'; import { KubernetesEndpointService } from './kubernetes-endpoint.service'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-node.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-node.service.ts index 951a50de18..b51cd6d1a3 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-node.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes-node.service.ts @@ -10,7 +10,7 @@ import { EntityMonitorFactory } from '../../../../store/src/monitors/entity-moni import { AppState } from '../../../../store/src/public-api'; import { EntityInfo } from '../../../../store/src/types/api.types'; import { MetricQueryType } from '../../../../store/src/types/metric.types'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { KubernetesNode, MetricStatistic } from '../store/kube.types'; import { FetchKubernetesMetricsAction } from '../store/kubernetes.actions'; import { KubernetesEndpointService } from './kubernetes-endpoint.service'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes.analysis.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes.analysis.service.ts index 160d92e53c..1261e859ae 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes.analysis.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/services/kubernetes.analysis.service.ts @@ -8,7 +8,7 @@ import { SnackBarService } from '../../../../core/src/shared/services/snackbar.s import { ResetPaginationOfType } from '../../../../store/src/actions/pagination.actions'; import { AppState } from '../../../../store/src/app-state'; import { ListActionState, RequestInfoState } from '../../../../store/src/reducers/api-request-reducer/types'; -import { kubeEntityCatalog } from '../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; import { GetAnalysisReports } from '../store/analysis.actions'; import { AnalysisReport } from '../store/kube.types'; import { getHelmReleaseDetailsFromGuid } from '../workloads/store/workloads-entity-factory'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts index a072d7fcdf..1f3b036239 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts @@ -6,7 +6,7 @@ export interface KubeResourceActionBuilders extends OrchestratedActionBuilders { get: ( resourceName: string, kubeGuid: string, - extraArgs: { namespace: string } + extraArgs: { namespace: string; } ) => GetKubernetesResource; getMultiple: ( kubeGuid: string, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts index 5ffda836e5..708264ec46 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/kube.types.ts @@ -1,7 +1,11 @@ import { Observable } from 'rxjs'; +import { + OrchestratedActionBuilderConfig, + OrchestratedActionBuilders, +} from '../../../../store/src/entity-catalog/action-orchestrator/action-orchestrator'; import { StratosCatalogEntity } from '../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; -import { IStratosEntityDefinition } from '../../../../store/src/entity-catalog/entity-catalog.types'; +import { IEntityMetadata, IStratosEntityDefinition } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { KubernetesPodExpandedStatus } from '../services/kubernetes-expanded-state'; // Map of endpoint ID to current namespace for that endpoint @@ -38,7 +42,11 @@ export interface IKubeResourceEntityDefinition extends IStratosEntityDefinition apiNamespaced: boolean; } -export interface KubeResourceEntityDefinition { +export interface KubeResourceEntityDefinition< + A extends IEntityMetadata = IEntityMetadata, + B = any, + C extends OrchestratedActionBuilderConfig = OrchestratedActionBuilders + > { apiVersion: string; apiName: string; apiNamespaced?: boolean; @@ -48,9 +56,7 @@ export interface KubeResourceEntityDefinition { icon: string; iconFont?: string; type: string; - kubeCatalogEntity: string; - getKubeCatalogEntity?: (IStratosEntityDefinition) => StratosCatalogEntity; - route?: string; + getKubeCatalogEntity?: (IStratosEntityDefinition) => StratosCatalogEntity; listColumns?: SimpleKubeListColumn[]; // Should this entity be hidden in the auto-generated navigation? hidden?: boolean; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-summary-tab/kubernetes-summary.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-summary-tab/kubernetes-summary.component.ts index efe1eeab7c..6405ed2558 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-summary-tab/kubernetes-summary.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/tabs/kubernetes-summary-tab/kubernetes-summary.component.ts @@ -15,7 +15,7 @@ import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagi import { AppState, entityCatalog } from '../../../../../store/src/public-api'; import { getCurrentPageRequestInfo } from '../../../../../store/src/reducers/pagination-reducer/pagination-reducer.types'; import { PaginatedAction, PaginationEntityState } from '../../../../../store/src/types/pagination.types'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { CaaspNodesData, KubernetesEndpointService } from '../../services/kubernetes-endpoint.service'; interface IValueLabels { diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/create-release/create-release.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/create-release/create-release.component.ts index a126fe31f5..a5c7ebdb45 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/create-release/create-release.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/create-release/create-release.component.ts @@ -13,8 +13,8 @@ import { ChartsService } from '../../../helm/monocular/shared/services/charts.se import { createMonocularProviders } from '../../../helm/monocular/stratos-monocular-providers.helpers'; import { getMonocularEndpoint, stratosMonocularEndpointGuid } from '../../../helm/monocular/stratos-monocular.helper'; import { HelmChartReference, HelmInstallValues } from '../../../helm/store/helm.types'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; import { KUBERNETES_ENDPOINT_TYPE } from '../../kubernetes-entity-factory'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { KubernetesNamespace } from '../../store/kube.types'; import { ChartValuesConfig, ChartValuesEditorComponent } from './../chart-values-editor/chart-values-editor.component'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-source.ts index 6726c3ef26..786a1c1859 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/helm-release-pods-list-source.ts @@ -3,7 +3,7 @@ import { ListDataSource } from 'frontend/packages/core/src/shared/components/lis import { IListConfig } from 'frontend/packages/core/src/shared/components/list/list.component.types'; import { AppState } from 'frontend/packages/store/src/app-state'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { KubernetesPod } from '../../store/kube.types'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/kube-namespaces-filter-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/kube-namespaces-filter-config.service.ts index ca476270ce..e5564c3df3 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/kube-namespaces-filter-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/list-types/kube-namespaces-filter-config.service.ts @@ -18,8 +18,8 @@ import { } from 'rxjs/operators'; import { getCurrentPageRequestInfo } from '../../../../../store/src/reducers/pagination-reducer/pagination-reducer.types'; -import { kubeEntityCatalog } from '../../kubernetes-entity-catalog'; import { KUBERNETES_ENDPOINT_TYPE } from '../../kubernetes-entity-factory'; +import { kubeEntityCatalog } from '../../kubernetes-entity-generator'; import { KubernetesNamespace } from '../../store/kube.types'; export interface KubernetesNamespacesFilterItem { diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/helm-release-tab-base/helm-release-socket-service.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/helm-release-tab-base/helm-release-socket-service.ts index a3164755b9..b8e5be696d 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/helm-release-tab-base/helm-release-socket-service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/helm-release-tab-base/helm-release-socket-service.ts @@ -7,7 +7,7 @@ import { catchError, map, share, switchMap } from 'rxjs/operators'; import { SnackBarService } from '../../../../../../core/src/shared/services/snackbar.service'; import { AppState, entityCatalog, WrapperRequestActionSuccess } from '../../../../../../store/src/public-api'; import { EntityRequestAction } from '../../../../../../store/src/types/request.types'; -import { kubeEntityCatalog } from '../../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../../kubernetes-entity-generator'; import { KubernetesPodExpandedStatusHelper } from '../../../services/kubernetes-expanded-state'; import { KubernetesPod, KubeService } from '../../../store/kube.types'; import { KubePaginationAction } from '../../../store/kubernetes.actions'; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/tabs/helm-release-helper.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/tabs/helm-release-helper.service.ts index 07cc4dd957..7888e51906 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/tabs/helm-release-helper.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/release/tabs/helm-release-helper.service.ts @@ -5,7 +5,7 @@ import { filter, map } from 'rxjs/operators'; import { helmEntityCatalog } from '../../../../helm/helm-entity-catalog'; import { ChartAttributes } from '../../../../helm/monocular/shared/models/chart'; import { ChartMetadata } from '../../../../helm/store/helm.types'; -import { kubeEntityCatalog } from '../../../kubernetes-entity-catalog'; +import { kubeEntityCatalog } from '../../../kubernetes-entity-generator'; import { ContainerStateCollection, KubernetesPod } from '../../../store/kube.types'; import { getHelmReleaseDetailsFromGuid } from '../../store/workloads-entity-factory'; import { diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index cf36c94e80..c3fb2b1dfe 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -86,7 +86,10 @@ export interface IStratosBaseEntityDefinition From 90e4af2c25593b663da6aa4df6216ad3b55f9e34 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 3 Dec 2020 18:43:18 +0000 Subject: [PATCH 14/16] Fix services in namespace view - kube guid and namespace was mixed up - now follow standard pattern of kube guid then namespace in ctor --- .../kubernetes-resource-list.component.ts | 2 ++ .../packages/kubernetes/src/kubernetes/kubernetes.routing.ts | 1 + .../kubernetes-namespace-services-data-source.ts | 2 +- .../kubernetes-pods/kubernetes-pods-list-config.service.ts | 1 + .../kubernetes/store/action-builders/kube.action-builders.ts | 4 ++-- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index 361fbf74ac..b13fb8dd64 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -83,6 +83,7 @@ export class KubernetesResourceListComponent implements OnDestroy { this.createProvider(catalogEntity); // Watch for namespace changes + // TODO: RC k8sCurrentNamespace should go into dashboard state... so it's sticky this.sub = this.store.select(state => state.k8sCurrentNamespace).pipe( map(data => data[this.kubeId.guid]), filter(data => !!data) @@ -104,6 +105,7 @@ export class KubernetesResourceListComponent implements OnDestroy { this.isNamespacedView = !!catalogEntity.definition.apiNamespaced; let action; if (this.selectedNamespace && this.isNamespacedView) { + // TODO: RC There should be a nicer way of accessing these action = catalogEntity.actions.getInNamespace(this.kubeId.guid, this.selectedNamespace); } else { action = catalogEntity.actions.getMultiple(this.kubeId.guid); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts index 7f89503e8b..ff1ec60dcd 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts @@ -75,6 +75,7 @@ const kubernetes: Routes = [{ } ] }, +// TODO: RC these can be removed? { path: ':endpointId/namespaces/:namespaceName', component: KubernetesNamespaceComponent, diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts index a86463c08b..a21b07430c 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-namespace-services/kubernetes-namespace-services-data-source.ts @@ -18,7 +18,7 @@ export class KubernetesNamespaceServicesDataSource extends BaseKubernetesService ) { super( store, - kubeEntityCatalog.service.actions.getInNamespace(namespace, kubeGuid.guid), + kubeEntityCatalog.service.actions.getInNamespace(kubeGuid.guid, namespace), listConfig ); } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts index 0f2986f2ab..cff0adec9b 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts @@ -140,6 +140,7 @@ export abstract class BaseKubernetesPodsListConfigService implements ISimpleList getMultiFiltersConfigs = () => []; } +// TODO: RC this isn't used now? @Injectable() export class KubernetesPodsListConfigService extends BaseKubernetesPodsListConfigService implements IListConfig { private podsDataSource: KubernetesPodsDataSource; diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube.action-builders.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube.action-builders.ts index c48bd2c580..c5362463fd 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube.action-builders.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube.action-builders.ts @@ -126,8 +126,8 @@ export interface KubeServiceActionBuilders extends OrchestratedActionBuilders { paginationKey?: string ) => GetKubernetesServices; getInNamespace: ( + kubeGuid: string, namespace: string, - kubeGuid: string ) => GetKubernetesServicesInNamespace; getInWorkload: ( releaseTitle: string, @@ -137,7 +137,7 @@ export interface KubeServiceActionBuilders extends OrchestratedActionBuilders { export const kubeServiceActionBuilders: KubeServiceActionBuilders = { getMultiple: (kubeGuid: string, paginationKey?: string) => new GetKubernetesServices(kubeGuid), - getInNamespace: (namespace: string, kubeGuid: string) => new GetKubernetesServicesInNamespace(kubeGuid, namespace), + getInNamespace: (kubeGuid: string, namespace: string) => new GetKubernetesServicesInNamespace(kubeGuid, namespace), getInWorkload: (releaseTitle: string, kubeGuid: string) => new GetHelmReleaseServices(kubeGuid, releaseTitle) }; From 33e675cbab47c3edaa5d3da3b7705ded6ff1c292 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 4 Dec 2020 11:54:45 +0000 Subject: [PATCH 15/16] Changes following review --- .../kubernetes/kubernetes-entity-generator.ts | 27 ++-------------- .../kubernetes-resource-list.component.ts | 2 -- .../kubernetes-tab-base.component.ts | 31 +------------------ .../src/kubernetes/kubernetes.routing.ts | 2 +- .../kubernetes-pods-list-config.service.ts | 28 +---------------- .../kube-resource.action-builder.ts | 2 +- .../entity-catalog/entity-catalog.types.ts | 3 -- 7 files changed, 6 insertions(+), 89 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts index 84b66f1da4..c87e5236a3 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-entity-generator.ts @@ -226,8 +226,6 @@ export class KubeEntityCatalog { public role: StratosCatalogEntity; public job: StratosCatalogEntity; - private workloadEntities: StratosBaseCatalogEntity[]; - constructor() { const endpointDef: StratosEndpointExtensionDefinition = { type: KUBERNETES_ENDPOINT_TYPE, @@ -328,7 +326,6 @@ export class KubeEntityCatalog { apiVersion: '/api/v1', apiName: 'namespaces', apiNamespaced: false, - hidden: true, getKubeCatalogEntity: (definition) => new StratosCatalogEntity( definition, { actionBuilders: kubeNamespaceActionBuilders } ), @@ -487,32 +484,12 @@ export class KubeEntityCatalog { apiName: 'jobs', }); - this.workloadEntities = generateWorkloadsEntities(endpointDef); } public allKubeEntities(): StratosBaseCatalogEntity[] { return [ - this.endpoint, - this.statefulSet, - this.pod, - this.deployment, - this.node, - this.namespace, - this.service, - this.dashboard, - this.analysisReport, - this.configMap, - this.metrics, - this.secrets, - this.pvc, - this.storage, - this.pv, - this.replicaSet, - this.clusterRole, - this.serviceAccount, - this.role, - this.job, - ...this.workloadEntities + ...Object.getOwnPropertyNames(this).map(s => this[s]), + ...generateWorkloadsEntities(this.endpoint.definition) ]; } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts index b13fb8dd64..361fbf74ac 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-resource/kubernetes-resource-list/kubernetes-resource-list.component.ts @@ -83,7 +83,6 @@ export class KubernetesResourceListComponent implements OnDestroy { this.createProvider(catalogEntity); // Watch for namespace changes - // TODO: RC k8sCurrentNamespace should go into dashboard state... so it's sticky this.sub = this.store.select(state => state.k8sCurrentNamespace).pipe( map(data => data[this.kubeId.guid]), filter(data => !!data) @@ -105,7 +104,6 @@ export class KubernetesResourceListComponent implements OnDestroy { this.isNamespacedView = !!catalogEntity.definition.apiNamespaced; let action; if (this.selectedNamespace && this.isNamespacedView) { - // TODO: RC There should be a nicer way of accessing these action = catalogEntity.actions.getInNamespace(this.kubeId.guid, this.selectedNamespace); } else { action = catalogEntity.actions.getMultiple(this.kubeId.guid); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts index 786015275c..61e4df51a9 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts @@ -66,7 +66,7 @@ export class KubernetesTabBaseComponent implements OnInit { kubeEntityCatalog.allKubeEntities().forEach(catalogEntity => { if (catalogEntity) { const defn = catalogEntity.definition as unknown as KubeResourceEntityDefinition; - if (defn.apiNamespaced === namespaced) { + if (defn.apiNamespaced === namespaced && !defn.hidden) { tabsFromRouterConfig.push({ link: `resource/${catalogEntity.type}`, label: defn.labelTab || defn.labelPlural, @@ -81,35 +81,6 @@ export class KubernetesTabBaseComponent implements OnInit { return tabsFromRouterConfig; } - // TODO: RC Q This is unused - // private getTabsFromRouterConfig(namespaced: boolean = true) { - // const childRoutes = this.route.snapshot.routeConfig.children; - // const tabsFromRouterConfig = []; - - // // Get the tabs from the router configuration - // childRoutes.forEach(r => { - // if (r.path.length > 0) { - // // See if we can find an entity for the key - // const key = r.data ? (r.data.entityCatalogKey ? r.data.entityCatalogKey : r.path) : r.path; - // const catalogEntity = kubeEntityCatalog[key]; - // if (catalogEntity) { - // const defn = catalogEntity.definition as KubeResourceEntityDefinition; - // if (defn.apiNamespaced === namespaced) { - // tabsFromRouterConfig.push({ - // link: defn.route ? defn.route : `resource/${r.path}`, - // label: defn.labelTab || defn.labelPlural, - // icon: defn.icon, - // iconFont: defn.iconFont, - // }); - // } - // } - // } - // }); - - // tabsFromRouterConfig.sort((a, b) => a.label.localeCompare(b.label)); - // return tabsFromRouterConfig; - // } - ngOnInit() { this.isFetching$ = this.kubeEndpointService.endpoint$.pipe( map(endpoint => !endpoint), diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts index ff1ec60dcd..db092316d9 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.routing.ts @@ -78,7 +78,7 @@ const kubernetes: Routes = [{ // TODO: RC these can be removed? { path: ':endpointId/namespaces/:namespaceName', - component: KubernetesNamespaceComponent, + component: KubernetesNamespaceComponent, // TODO: RC This component, and others in here, should be removed if route goes children: [ { path: '', diff --git a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts index cff0adec9b..d1595ace69 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts @@ -1,5 +1,3 @@ -import { Injectable } from '@angular/core'; -import { Store } from '@ngrx/store'; import { of } from 'rxjs'; import { @@ -7,13 +5,7 @@ import { TableCellSidePanelConfig, } from '../../../../../core/src/shared/components/list/list-table/table-cell-side-panel/table-cell-side-panel.component'; import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; -import { - IListConfig, - ISimpleListConfig, - ListViewTypes, -} from '../../../../../core/src/shared/components/list/list.component.types'; -import { AppState } from '../../../../../store/src/public-api'; -import { BaseKubeGuid } from '../../kubernetes-page.types'; +import { ISimpleListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; import { KubernetesResourceViewerComponent, KubernetesResourceViewerConfig, @@ -23,7 +15,6 @@ import { defaultHelmKubeListPageSize } from '../kube-helm-list-types'; import { createKubeAgeColumn } from '../kube-list.helper'; import { KubernetesPodContainersComponent } from './kubernetes-pod-containers/kubernetes-pod-containers.component'; import { KubernetesPodStatusComponent } from './kubernetes-pod-status/kubernetes-pod-status.component'; -import { KubernetesPodsDataSource } from './kubernetes-pods-data-source'; export abstract class BaseKubernetesPodsListConfigService implements ISimpleListConfig { @@ -140,23 +131,6 @@ export abstract class BaseKubernetesPodsListConfigService implements ISimpleList getMultiFiltersConfigs = () => []; } -// TODO: RC this isn't used now? -@Injectable() -export class KubernetesPodsListConfigService extends BaseKubernetesPodsListConfigService implements IListConfig { - private podsDataSource: KubernetesPodsDataSource; - - getDataSource = () => this.podsDataSource; - - constructor( - store: Store, - kubeId: BaseKubeGuid, - ) { - super([]); - this.podsDataSource = new KubernetesPodsDataSource(store, kubeId, this); - } - -} - export class KubernetesPodsListConfig extends BaseKubernetesPodsListConfigService { constructor() { super([]); diff --git a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts index 1f3b036239..0b136365ce 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/store/action-builders/kube-resource.action-builder.ts @@ -6,7 +6,7 @@ export interface KubeResourceActionBuilders extends OrchestratedActionBuilders { get: ( resourceName: string, kubeGuid: string, - extraArgs: { namespace: string; } + extraArgs: { namespace: string, } ) => GetKubernetesResource; getMultiple: ( kubeGuid: string, diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index c3fb2b1dfe..cf36c94e80 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -86,10 +86,7 @@ export interface IStratosBaseEntityDefinition From b1d4c0123dcb211d8be5276aa441771ba80f8bb8 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 4 Dec 2020 13:54:28 +0000 Subject: [PATCH 16/16] Fix unit tests --- .../kubernetes/src/kubernetes/kubernetes.testing.module.ts | 4 ++-- .../src/kubernetes/workloads/workloads.testing.module.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.testing.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.testing.module.ts index bffc35ba08..612024e973 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.testing.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/kubernetes.testing.module.ts @@ -15,7 +15,7 @@ import { import { generateStratosEntities } from '../../../store/src/stratos-entity-generator'; import { createBasicStoreModule } from '../../../store/testing/public-api'; import { HelmReleaseActivatedRouteMock, HelmReleaseGuidMock } from '../helm/helm-testing.module'; -import { generateKubernetesEntities } from './kubernetes-entity-generator'; +import { kubeEntityCatalog } from './kubernetes-entity-generator'; import { BaseKubeGuid } from './kubernetes-page.types'; import { HelmReleaseHelperService } from './workloads/release/tabs/helm-release-helper.service'; @@ -29,7 +29,7 @@ import { HelmReleaseHelperService } from './workloads/release/tabs/helm-release- testEntityCatalog.clear(); return [ ...generateStratosEntities(), - ...generateKubernetesEntities(), + ...kubeEntityCatalog.allKubeEntities(), ]; } } diff --git a/src/frontend/packages/kubernetes/src/kubernetes/workloads/workloads.testing.module.ts b/src/frontend/packages/kubernetes/src/kubernetes/workloads/workloads.testing.module.ts index 5d1b9d4b87..4e6b29d1d8 100644 --- a/src/frontend/packages/kubernetes/src/kubernetes/workloads/workloads.testing.module.ts +++ b/src/frontend/packages/kubernetes/src/kubernetes/workloads/workloads.testing.module.ts @@ -15,7 +15,7 @@ import { generateStratosEntities } from '../../../../store/src/stratos-entity-ge import { createBasicStoreModule } from '../../../../store/testing/public-api'; import { generateHelmEntities } from '../../helm/helm-entity-generator'; import { HelmTestingModule } from '../../helm/helm-testing.module'; -import { generateKubernetesEntities } from '../kubernetes-entity-generator'; +import { kubeEntityCatalog } from '../kubernetes-entity-generator'; @NgModule({ imports: [{ @@ -27,7 +27,7 @@ import { generateKubernetesEntities } from '../kubernetes-entity-generator'; testEntityCatalog.clear(); return [ ...generateStratosEntities(), - ...generateKubernetesEntities(), + ...kubeEntityCatalog.allKubeEntities(), ...generateHelmEntities(), ]; }