From 043cf88a63200553eb2233b6fc0d353e7d166094 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 10:41:29 -0500 Subject: [PATCH 01/15] add title field to ClusterDetails Signed-off-by: Jamie Klassen --- .changeset/sixty-bags-fry.md | 6 ++++++ plugins/kubernetes-node/api-report.md | 1 + plugins/kubernetes-node/src/types/types.ts | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 .changeset/sixty-bags-fry.md diff --git a/.changeset/sixty-bags-fry.md b/.changeset/sixty-bags-fry.md new file mode 100644 index 0000000000..139e31c6a4 --- /dev/null +++ b/.changeset/sixty-bags-fry.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-node': patch +--- + +The `ClusterDetails` type now has a `title` field, which should be a +human-readable name. diff --git a/plugins/kubernetes-node/api-report.md b/plugins/kubernetes-node/api-report.md index 0521ed72aa..509416fa4a 100644 --- a/plugins/kubernetes-node/api-report.md +++ b/plugins/kubernetes-node/api-report.md @@ -51,6 +51,7 @@ export interface ClusterDetails { skipMetricsLookup?: boolean; // (undocumented) skipTLSVerify?: boolean; + title?: string; // (undocumented) url: string; } diff --git a/plugins/kubernetes-node/src/types/types.ts b/plugins/kubernetes-node/src/types/types.ts index 2881338868..665b06178a 100644 --- a/plugins/kubernetes-node/src/types/types.ts +++ b/plugins/kubernetes-node/src/types/types.ts @@ -67,9 +67,13 @@ export type AuthMetadata = Record; */ export interface ClusterDetails { /** - * Specifies the name of the Kubernetes cluster. + * Name of the Kubernetes cluster; used as an internal identifier. */ name: string; + /** + * Human-readable name for the cluster, to be dispayed in UIs. + */ + title?: string; url: string; authMetadata: AuthMetadata; skipTLSVerify?: boolean; From 7ee5b30ba7c4be5e0a26c1f39734a36d2dbfd197 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 10:47:12 -0500 Subject: [PATCH 02/15] ConfigClusterLocator reads title Signed-off-by: Jamie Klassen --- .changeset/tidy-peaches-nail.md | 5 ++++ plugins/kubernetes-backend/config.d.ts | 2 ++ .../ConfigClusterLocator.test.ts | 24 ++++++++++++++++++- .../cluster-locator/ConfigClusterLocator.ts | 2 ++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 .changeset/tidy-peaches-nail.md diff --git a/.changeset/tidy-peaches-nail.md b/.changeset/tidy-peaches-nail.md new file mode 100644 index 0000000000..d044a6bfaa --- /dev/null +++ b/.changeset/tidy-peaches-nail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Clusters in the app-config can now specify a `title` property for human readability. diff --git a/plugins/kubernetes-backend/config.d.ts b/plugins/kubernetes-backend/config.d.ts index de7f79b66c..777a3392db 100644 --- a/plugins/kubernetes-backend/config.d.ts +++ b/plugins/kubernetes-backend/config.d.ts @@ -43,6 +43,8 @@ export interface Config { url: string; /** @visibility frontend */ name: string; + /** @visibility frontend */ + title?: string; /** @visibility secret */ serviceAccountToken?: string; /** @visibility frontend */ diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts index d36f10bb13..3f014b2869 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts @@ -21,8 +21,8 @@ import { ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE, ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID, } from '@backstage/plugin-kubernetes-common'; +import { ClusterDetails } from '@backstage/plugin-kubernetes-node'; import { ConfigClusterLocator } from './ConfigClusterLocator'; -import { ClusterDetails } from '../types/types'; import { AuthenticationStrategy } from '../auth'; describe('ConfigClusterLocator', () => { @@ -78,6 +78,28 @@ describe('ConfigClusterLocator', () => { ]); }); + it('reads `title` property', async () => { + const sut = ConfigClusterLocator.fromConfig( + new ConfigReader({ + clusters: [ + { + name: 'cluster-name', + title: 'cluster-title', + url: 'url', + authMetadata: { 'kubernetes.io/auth-provider': 'serviceAccount' }, + }, + ], + }), + authStrategy, + ); + + const result = await sut.getClusters(); + + expect(result).toEqual([ + expect.objectContaining({ title: 'cluster-title' }), + ]); + }); + it('two clusters returns two cluster details', async () => { const config: Config = new ConfigReader({ clusters: [ diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts index 6fd5f3b1cb..6403ec89a7 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts @@ -56,8 +56,10 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { `'authMetadata.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}' parameter`, ); } + const title = c.getOptionalString('title'); const clusterDetails: ClusterDetails = { name, + ...(title && { title }), url: c.getString('url'), skipTLSVerify: c.getOptionalBoolean('skipTLSVerify') ?? false, skipMetricsLookup: c.getOptionalBoolean('skipMetricsLookup') ?? false, From 6009d2aabcc96b5b4e8cbb5e8f857a61684fc00c Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 10:48:38 -0500 Subject: [PATCH 03/15] CatalogClusterLocator reads title Signed-off-by: Jamie Klassen --- .changeset/thin-turtles-float.md | 5 +++++ .../src/cluster-locator/CatalogClusterLocator.test.ts | 1 + .../src/cluster-locator/CatalogClusterLocator.ts | 1 + .../__snapshots__/CatalogClusterLocator.test.ts.snap | 2 ++ 4 files changed, 9 insertions(+) create mode 100644 .changeset/thin-turtles-float.md diff --git a/.changeset/thin-turtles-float.md b/.changeset/thin-turtles-float.md new file mode 100644 index 0000000000..7416093e17 --- /dev/null +++ b/.changeset/thin-turtles-float.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Clusters in the catalog can now specify a human-readable title via `metadata.title`. diff --git a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts index ad09f52f0a..d6bc64221d 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts @@ -43,6 +43,7 @@ const mockCatalogApi = { 'kubernetes.io/dashboard-app': 'my-app', }, name: 'owned', + title: 'title', namespace: 'default', }, }, diff --git a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts index 9be4cd39cc..a2c5f0376a 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts @@ -63,6 +63,7 @@ export class CatalogClusterLocator implements KubernetesClustersSupplier { const annotations = entity.metadata.annotations!; const clusterDetails: ClusterDetails = { name: entity.metadata.name, + title: entity.metadata.title, url: annotations[ANNOTATION_KUBERNETES_API_SERVER], authMetadata: annotations, caData: annotations[ANNOTATION_KUBERNETES_API_SERVER_CA], diff --git a/plugins/kubernetes-backend/src/cluster-locator/__snapshots__/CatalogClusterLocator.test.ts.snap b/plugins/kubernetes-backend/src/cluster-locator/__snapshots__/CatalogClusterLocator.test.ts.snap index b3731f1c08..f8b3e71515 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/__snapshots__/CatalogClusterLocator.test.ts.snap +++ b/plugins/kubernetes-backend/src/cluster-locator/__snapshots__/CatalogClusterLocator.test.ts.snap @@ -19,6 +19,7 @@ exports[`CatalogClusterLocator returns the aws cluster details provided by annot "name": "owned", "skipMetricsLookup": false, "skipTLSVerify": false, + "title": undefined, "url": "https://apiserver.com", } `; @@ -42,6 +43,7 @@ exports[`CatalogClusterLocator returns the cluster details provided by annotatio "name": "owned", "skipMetricsLookup": true, "skipTLSVerify": true, + "title": "title", "url": "https://apiserver.com", } `; From afe9473ea8ab8cb51da16cdc14ab1bb5a1f4a559 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 10:50:48 -0500 Subject: [PATCH 04/15] surface title in /clusters API Signed-off-by: Jamie Klassen --- .changeset/happy-peas-hunt.md | 5 ++++ .../src/service/KubernetesBuilder.test.ts | 26 +++++++++++++++++++ .../src/service/KubernetesBuilder.ts | 1 + 3 files changed, 32 insertions(+) create mode 100644 .changeset/happy-peas-hunt.md diff --git a/.changeset/happy-peas-hunt.md b/.changeset/happy-peas-hunt.md new file mode 100644 index 0000000000..8fbac9c33a --- /dev/null +++ b/.changeset/happy-peas-hunt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +The `/clusters` API now surfaces cluster titles. diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 5d19c6d94d..295d11570f 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -278,6 +278,32 @@ describe('API integration tests', () => { ], }); }); + + it('surfaces cluster title', async () => { + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ + { + name: 'cluster-name', + title: 'cluster-title', + url: 'url', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + }, + }, + ]), + ], + }); + app = server; + + const response = await request(app).get('/api/kubernetes/clusters'); + + expect(response.body).toEqual({ + items: [expect.objectContaining({ title: 'cluster-title' })], + }); + }); }); describe('post /services/:serviceId', () => { diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 8cc9b8a8b6..fec4bc5cc0 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -381,6 +381,7 @@ export class KubernetesBuilder { return { name: cd.name, + title: cd.title, dashboardUrl: cd.dashboardUrl, authProvider, ...(oidcTokenProvider && { oidcTokenProvider }), From a643af8082d6369147fabf886b471c52ed506fce Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 11:24:14 -0500 Subject: [PATCH 05/15] add title to ClusterAttributes Signed-off-by: Jamie Klassen --- .changeset/healthy-bees-deliver.md | 5 +++++ plugins/kubernetes-common/api-report.md | 1 + plugins/kubernetes-common/src/types.ts | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/healthy-bees-deliver.md diff --git a/.changeset/healthy-bees-deliver.md b/.changeset/healthy-bees-deliver.md new file mode 100644 index 0000000000..80da17dc0b --- /dev/null +++ b/.changeset/healthy-bees-deliver.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-common': patch +--- + +The `ClusterAttributes` type now includes the cluster title. diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index e4dbf79f4a..c1d399b196 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -112,6 +112,7 @@ export interface ClusterAttributes { dashboardParameters?: JsonObject; dashboardUrl?: string; name: string; + title?: string; } // @public (undocumented) diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index c9a4ce4c5a..cd316af089 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -67,9 +67,13 @@ export interface KubernetesRequestBody { /** @public */ export interface ClusterAttributes { /** - * Specifies the name of the Kubernetes cluster. + * Name of the Kubernetes cluster; used as an internal identifier. */ name: string; + /** + * Human-readable name for the cluster, to be dispayed in UIs. + */ + title?: string; /** * Specifies the link to the Kubernetes dashboard managing this cluster. * @remarks From 3b3d549a5f9fd563493b8c1470bf1f587358aee4 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 11:35:28 -0500 Subject: [PATCH 06/15] KubernetesFanOutHandler surfaces title Signed-off-by: Jamie Klassen --- .changeset/new-plants-rhyme.md | 5 ++++ .../service/KubernetesFanOutHandler.test.ts | 27 ++++++++++--------- .../src/service/KubernetesFanOutHandler.ts | 1 + 3 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 .changeset/new-plants-rhyme.md diff --git a/.changeset/new-plants-rhyme.md b/.changeset/new-plants-rhyme.md new file mode 100644 index 0000000000..c901754069 --- /dev/null +++ b/.changeset/new-plants-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Responses from the `/api/kubernetes/services/:serviceId` endpoint now include the cluster title. diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts index a50d0b37a2..5c4534d61b 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts @@ -29,6 +29,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { + FetchResponse, KubernetesRequestAuth, ObjectsByEntityResponse, } from '@backstage/plugin-kubernetes-common'; @@ -104,7 +105,7 @@ describe('KubernetesFanOutHandler', () => { ], }; - const mockClusterResourceMap = { + const mockClusterResourceMap: Record = { 'test-cluster': [ { resources: [ @@ -358,17 +359,16 @@ describe('KubernetesFanOutHandler', () => { describe('getKubernetesObjectsByEntity', () => { it('retrieve objects for one cluster', async () => { - getClustersByEntity.mockImplementation(() => - Promise.resolve({ - clusters: [ - { - name: 'test-cluster', - url: '', - authMetadata: {}, - }, - ], - }), - ); + getClustersByEntity.mockResolvedValue({ + clusters: [ + { + name: 'test-cluster', + title: 'cluster-title', + url: '', + authMetadata: {}, + }, + ], + }); sut = getKubernetesFanOutHandler([]); @@ -386,11 +386,12 @@ describe('KubernetesFanOutHandler', () => { new Set(['ns-test-component-test-cluster']), expect.anything(), ); - expect(result).toStrictEqual({ + expect(result).toStrictEqual({ items: [ { cluster: { name: 'test-cluster', + title: 'cluster-title', }, errors: [], podMetrics: [POD_METRICS_FIXTURE], diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts index 7a8ff1bf2d..4df60bc8da 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -335,6 +335,7 @@ export class KubernetesFanOutHandler { const objects: ClusterObjects = { cluster: { name: clusterDetails.name, + ...(clusterDetails.title && { title: clusterDetails.title }), }, podMetrics: toClientSafePodMetrics(metrics), resources: result.responses, From 2b305eb7f22382a41d840cb55bdc838ab2242f9f Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 11:50:12 -0500 Subject: [PATCH 07/15] Display title in Cluster accordion Signed-off-by: Jamie Klassen --- .changeset/quick-gifts-leave.md | 5 +++++ .../src/components/Cluster/Cluster.test.tsx | 21 +++++++++++++++++++ .../src/components/Cluster/Cluster.tsx | 4 +++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .changeset/quick-gifts-leave.md diff --git a/.changeset/quick-gifts-leave.md b/.changeset/quick-gifts-leave.md new file mode 100644 index 0000000000..2f5f2a4635 --- /dev/null +++ b/.changeset/quick-gifts-leave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +The `Cluster` component now renders the cluster's title, if specified. diff --git a/plugins/kubernetes-react/src/components/Cluster/Cluster.test.tsx b/plugins/kubernetes-react/src/components/Cluster/Cluster.test.tsx index 482a386efb..2814606dd6 100644 --- a/plugins/kubernetes-react/src/components/Cluster/Cluster.test.tsx +++ b/plugins/kubernetes-react/src/components/Cluster/Cluster.test.tsx @@ -56,4 +56,25 @@ describe('Cluster', () => { expect(screen.getByText('cluster-1')).toBeInTheDocument(); expect(screen.getByText('10 pods')).toBeInTheDocument(); }); + + it('renders title', async () => { + await renderInTestApp( + (), + } as any)} + />, + ); + + expect(screen.getByText('Cluster Number One')).toBeInTheDocument(); + }); }); diff --git a/plugins/kubernetes-react/src/components/Cluster/Cluster.tsx b/plugins/kubernetes-react/src/components/Cluster/Cluster.tsx index 42f1aca3a0..f2108ac1b7 100644 --- a/plugins/kubernetes-react/src/components/Cluster/Cluster.tsx +++ b/plugins/kubernetes-react/src/components/Cluster/Cluster.tsx @@ -132,7 +132,9 @@ export const Cluster = ({ clusterObjects, podsWithErrors }: ClusterProps) => { }> From 0dfc1858298c220b7c0b146bd3c0962d4160921e Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Mon, 22 Jan 2024 12:45:07 -0500 Subject: [PATCH 08/15] pass ClusterAttributes to pod components Signed-off-by: Jamie Klassen --- .changeset/eight-pumas-rule.md | 5 +++++ plugins/kubernetes-react/api-report.md | 2 +- .../src/components/Pods/ErrorList/ErrorList.test.tsx | 2 +- .../src/components/Pods/ErrorList/ErrorList.tsx | 2 +- .../src/components/Pods/PodDrawer/PodDrawer.test.tsx | 2 +- .../src/components/Pods/PodDrawer/PodDrawer.tsx | 4 ++-- .../kubernetes-react/src/components/Pods/PodsTable.tsx | 3 +-- plugins/kubernetes-react/src/components/Pods/types.ts | 9 ++++++--- 8 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 .changeset/eight-pumas-rule.md diff --git a/.changeset/eight-pumas-rule.md b/.changeset/eight-pumas-rule.md new file mode 100644 index 0000000000..57e6b4433b --- /dev/null +++ b/.changeset/eight-pumas-rule.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +The `PodAndErrors` type now includes the full `ClusterAttributes` rather than just the name. diff --git a/plugins/kubernetes-react/api-report.md b/plugins/kubernetes-react/api-report.md index 8a0ec4de8f..93086efde7 100644 --- a/plugins/kubernetes-react/api-report.md +++ b/plugins/kubernetes-react/api-report.md @@ -653,7 +653,7 @@ export interface PendingPodContentProps { // @public export interface PodAndErrors { // (undocumented) - clusterName: string; + cluster: ClusterAttributes; // (undocumented) errors: DetectedError[]; // (undocumented) diff --git a/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx b/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx index 2423654cc3..998ef4b4d0 100644 --- a/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx +++ b/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx @@ -26,7 +26,7 @@ describe('ErrorList', () => { { diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.test.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.test.tsx index 0822aeb060..066fa0f874 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.test.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.test.tsx @@ -37,7 +37,7 @@ describe('PodDrawer', () => { {...({ open: true, podAndErrors: { - clusterName: 'some-cluster-1', + cluster: { name: 'some-cluster-1' }, pod: { metadata: { name: 'some-pod', diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx index 1b98237d5a..8f52bb9a7f 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx @@ -79,7 +79,7 @@ export interface PodDrawerProps { */ export const PodDrawer = ({ podAndErrors, open }: PodDrawerProps) => { const classes = useDrawerContentStyles(); - const podMetrics = usePodMetrics(podAndErrors.clusterName, podAndErrors.pod); + const podMetrics = usePodMetrics(podAndErrors.cluster.name, podAndErrors.pod); return ( { podName: podAndErrors.pod.metadata?.name ?? 'unknown', podNamespace: podAndErrors.pod.metadata?.namespace ?? 'unknown', - clusterName: podAndErrors.clusterName, + clusterName: podAndErrors.cluster.name, }} containerSpec={containerSpec} containerStatus={containerStatus} diff --git a/plugins/kubernetes-react/src/components/Pods/PodsTable.tsx b/plugins/kubernetes-react/src/components/Pods/PodsTable.tsx index d83aebb210..d9a7657367 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodsTable.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodsTable.tsx @@ -80,7 +80,6 @@ const READY: TableColumn[] = [ ]; const PodDrawerTrigger = ({ pod }: { pod: Pod }) => { - const cluster = useContext(ClusterContext); const errors = useMatchingErrors({ kind: 'Pod', apiVersion: 'v1', @@ -90,7 +89,7 @@ const PodDrawerTrigger = ({ pod }: { pod: Pod }) => { diff --git a/plugins/kubernetes-react/src/components/Pods/types.ts b/plugins/kubernetes-react/src/components/Pods/types.ts index 847e6d63bc..ee3ab5153a 100644 --- a/plugins/kubernetes-react/src/components/Pods/types.ts +++ b/plugins/kubernetes-react/src/components/Pods/types.ts @@ -14,15 +14,18 @@ * limitations under the License. */ import { Pod } from 'kubernetes-models/v1'; -import { DetectedError } from '@backstage/plugin-kubernetes-common'; +import { + ClusterAttributes, + DetectedError, +} from '@backstage/plugin-kubernetes-common'; /** - * Wraps a pod with the associated detected errors and cluster name + * Wraps a pod with the associated detected errors and cluster * * @public */ export interface PodAndErrors { - clusterName: string; + cluster: ClusterAttributes; pod: Pod; errors: DetectedError[]; } From 74770c81ec78276c23ce14ea78e57029d90703d4 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Tue, 23 Jan 2024 10:33:19 -0500 Subject: [PATCH 09/15] ErrorPanel surfaces cluster title Signed-off-by: Jamie Klassen --- .changeset/fresh-paws-raise.md | 6 ++++++ .../src/components/ErrorPanel/ErrorPanel.test.tsx | 4 ++-- .../src/components/ErrorPanel/ErrorPanel.tsx | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 .changeset/fresh-paws-raise.md diff --git a/.changeset/fresh-paws-raise.md b/.changeset/fresh-paws-raise.md new file mode 100644 index 0000000000..61712db1e8 --- /dev/null +++ b/.changeset/fresh-paws-raise.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +The `ErrorPanel` component will display the `title` field (when specified) for +clusters with errors. diff --git a/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.test.tsx b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.test.tsx index 5c7b10697c..3917cf4513 100644 --- a/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.test.tsx +++ b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.test.tsx @@ -26,7 +26,7 @@ describe('ErrorPanel', () => { entityName="THIS_ENTITY" clustersWithErrors={[ { - cluster: { name: 'THIS_CLUSTER' }, + cluster: { name: 'THIS_CLUSTER', title: 'This Fine Cluster' }, resources: [], podMetrics: [], errors: [ @@ -50,7 +50,7 @@ describe('ErrorPanel', () => { // message expect(screen.getByText('Errors:')).toBeInTheDocument(); - expect(screen.getByText('Cluster: THIS_CLUSTER')).toBeInTheDocument(); + expect(screen.getByText('Cluster: This Fine Cluster')).toBeInTheDocument(); expect( screen.getByText( "Error fetching Kubernetes resource: 'some/resource', error: SYSTEM_ERROR, status code: 500", diff --git a/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx index b02f4c18dc..7109849b8e 100644 --- a/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx +++ b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx @@ -25,7 +25,9 @@ const clustersWithErrorsToErrorMessage = ( return clustersWithErrors.map((c, i) => { return (
- {`Cluster: ${c.cluster.name}`} + {`Cluster: ${ + c.cluster.title || c.cluster.name + }`} {c.errors.map((e, j) => { return ( From b01c86c2b5fb8b2c74ff87093e82f2bf5b1e0e3f Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Wed, 24 Jan 2024 10:46:42 -0500 Subject: [PATCH 10/15] surface cluster title in ErrorReporting table Signed-off-by: Jamie Klassen --- .changeset/healthy-goats-jump.md | 7 + plugins/kubernetes-react/api-report.md | 2 + .../ErrorReporting/ErrorReporting.test.tsx | 150 ++++++++++++++++++ .../ErrorReporting/ErrorReporting.tsx | 13 +- plugins/kubernetes/src/KubernetesContent.tsx | 7 +- 5 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 .changeset/healthy-goats-jump.md create mode 100644 plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.test.tsx diff --git a/.changeset/healthy-goats-jump.md b/.changeset/healthy-goats-jump.md new file mode 100644 index 0000000000..e5b43d3f8c --- /dev/null +++ b/.changeset/healthy-goats-jump.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-kubernetes-react': patch +--- + +The `ErrorReporting` component's cluster column now displays cluster titles when +specified. diff --git a/plugins/kubernetes-react/api-report.md b/plugins/kubernetes-react/api-report.md index 93086efde7..e02cb97992 100644 --- a/plugins/kubernetes-react/api-report.md +++ b/plugins/kubernetes-react/api-report.md @@ -176,11 +176,13 @@ export type ErrorPanelProps = { // @public (undocumented) export const ErrorReporting: ({ detectedErrors, + clusters, }: ErrorReportingProps) => React_3.JSX.Element; // @public (undocumented) export type ErrorReportingProps = { detectedErrors: DetectedErrorsByCluster; + clusters: ClusterAttributes[]; }; // @public diff --git a/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.test.tsx b/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.test.tsx new file mode 100644 index 0000000000..6da259d7fa --- /dev/null +++ b/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.test.tsx @@ -0,0 +1,150 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { DetectedError } from '@backstage/plugin-kubernetes-common'; +import { renderInTestApp } from '@backstage/test-utils'; +import { MatcherFunction, screen } from '@testing-library/react'; +import { ErrorReporting } from './ErrorReporting'; + +describe('ErrorReporting', () => { + const matchTextContent = + (text: string): MatcherFunction => + (_, node) => + node?.textContent?.includes(text) ?? false; + + it('sorts errors by severity', async () => { + await renderInTestApp( + ([ + [ + 'cluster', + [ + { + type: 'readiness-probe-taking-too-long', + message: + 'The container my-container failed to start properly, but is not crashing', + severity: 4, + proposedFix: undefined, + sourceRef: { + name: 'my-pod', + namespace: 'default', + kind: 'Pod', + apiGroup: 'v1', + }, + occurrenceCount: 1, + }, + { + type: 'condition-message-present', + message: 'some condition message', + severity: 6, + sourceRef: { + name: 'my-deployment', + namespace: 'default', + kind: 'Deployment', + apiGroup: 'apps/v1', + }, + occurrenceCount: 1, + }, + ], + ], + ]) + } + clusters={[{ name: 'cluster' }]} + />, + ); + + expect(screen.getAllByRole('row')).toEqual([ + expect.anything(), + screen.getByText(matchTextContent('some condition message'), { + selector: 'tr', + }), + screen.getByText( + matchTextContent( + 'The container my-container failed to start properly, but is not crashing', + ), + { selector: 'tr' }, + ), + expect.anything(), + ]); + }); + + it('displays cluster name', async () => { + await renderInTestApp( + ([ + [ + 'my-cluster', + [ + { + type: 'condition-message-present', + message: 'some condition message', + severity: 6, + sourceRef: { + name: 'my-deployment', + namespace: 'default', + kind: 'Deployment', + apiGroup: 'apps/v1', + }, + occurrenceCount: 1, + }, + ], + ], + ]) + } + clusters={[{ name: 'my-cluster' }]} + />, + ); + + expect( + screen.getByRole('cell', { name: 'my-cluster' }), + ).toBeInTheDocument(); + }); + + it('displays cluster title when specified', async () => { + await renderInTestApp( + ([ + [ + 'my-cluster', + [ + { + type: 'condition-message-present', + message: 'some condition message', + severity: 6, + sourceRef: { + name: 'my-deployment', + namespace: 'default', + kind: 'Deployment', + apiGroup: 'apps/v1', + }, + occurrenceCount: 1, + }, + ], + ], + ]) + } + clusters={[{ name: 'my-cluster', title: 'cluster-title' }]} + />, + ); + + expect( + screen.getByRole('cell', { name: 'cluster-title' }), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx b/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx index 64345662ed..5bf6cff50e 100644 --- a/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx +++ b/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx @@ -15,6 +15,7 @@ */ import * as React from 'react'; import { + ClusterAttributes, DetectedError, DetectedErrorsByCluster, } from '@backstage/plugin-kubernetes-common'; @@ -27,13 +28,14 @@ import { Table, TableColumn } from '@backstage/core-components'; */ export type ErrorReportingProps = { detectedErrors: DetectedErrorsByCluster; + clusters: ClusterAttributes[]; }; const columns: TableColumn[] = [ { title: 'cluster', width: '10%', - render: (row: Row) => row.clusterName, + render: (row: Row) => row.cluster.title || row.cluster.name, }, { title: 'namespace', @@ -60,7 +62,7 @@ const columns: TableColumn[] = [ ]; interface Row { - clusterName: string; + cluster: ClusterAttributes; error: DetectedError; } @@ -78,11 +80,14 @@ const sortBySeverity = (a: Row, b: Row) => { * * @public */ -export const ErrorReporting = ({ detectedErrors }: ErrorReportingProps) => { +export const ErrorReporting = ({ + detectedErrors, + clusters, +}: ErrorReportingProps) => { const errors = Array.from(detectedErrors.entries()) .flatMap(([clusterName, resourceErrors]) => { return resourceErrors.map(e => ({ - clusterName, + cluster: clusters.find(c => c.name === clusterName)!, error: e, })); }) diff --git a/plugins/kubernetes/src/KubernetesContent.tsx b/plugins/kubernetes/src/KubernetesContent.tsx index 9c266b1854..ed00cb9a13 100644 --- a/plugins/kubernetes/src/KubernetesContent.tsx +++ b/plugins/kubernetes/src/KubernetesContent.tsx @@ -50,6 +50,8 @@ export const KubernetesContent = ({ refreshIntervalMs, ); + const clusters = kubernetesObjects?.items.map(item => item.cluster) ?? []; + const clustersWithErrors = kubernetesObjects?.items.filter(r => r.errors.length > 0) ?? []; @@ -93,7 +95,10 @@ export const KubernetesContent = ({ {kubernetesObjects && ( - + Your Clusters From a8e98aa9819464ae5364fa2ea42908d89fe871c3 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Wed, 24 Jan 2024 11:42:21 -0500 Subject: [PATCH 11/15] refactor PodScope to include ClusterAttributes Signed-off-by: Jamie Klassen --- plugins/kubernetes-react/api-report.md | 2 +- .../src/components/Pods/FixDialog/FixDialog.tsx | 2 +- .../src/components/Pods/PodDrawer/ContainerCard.test.tsx | 6 +++--- .../src/components/Pods/PodDrawer/ContainerCard.tsx | 2 +- .../src/components/Pods/PodDrawer/PodDrawer.tsx | 2 +- .../src/components/Pods/PodLogs/PodLogsDialog.tsx | 2 +- .../kubernetes-react/src/components/Pods/PodLogs/types.ts | 3 ++- .../src/components/Pods/PodLogs/usePodLogs.ts | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/kubernetes-react/api-report.md b/plugins/kubernetes-react/api-report.md index e02cb97992..734bacc7c9 100644 --- a/plugins/kubernetes-react/api-report.md +++ b/plugins/kubernetes-react/api-report.md @@ -750,7 +750,7 @@ export const PodNamesWithMetricsContext: React_2.Context< // @public export interface PodScope { // (undocumented) - clusterName: string; + cluster: ClusterAttributes; // (undocumented) podName: string; // (undocumented) diff --git a/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx index c691cc67fd..d0f3e74c14 100644 --- a/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx +++ b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx @@ -119,7 +119,7 @@ export const FixDialog: React.FC = ({ containerScope={{ podName: pod.metadata?.name ?? 'unknown', podNamespace: pod.metadata?.namespace ?? 'unknown', - clusterName: clusterName, + cluster: { name: clusterName }, containerName: pf.container, }} /> diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.test.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.test.tsx index b7729f8b5f..6d64b8ad5b 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.test.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.test.tsx @@ -36,7 +36,7 @@ describe('ContainerCard', () => { podScope: { name: 'some-name', namespace: 'some-namespace', - clusterName: 'some-cluster', + cluster: { name: 'some-cluster' }, }, containerSpec: { readinessProbe: {}, @@ -71,7 +71,7 @@ describe('ContainerCard', () => { podScope: { podName: 'some-name', podNamespace: 'some-namespace', - clusterName: 'some-cluster', + cluster: { name: 'some-cluster' }, }, containerSpec: {}, containerStatus: { @@ -100,7 +100,7 @@ describe('ContainerCard', () => { podScope: { podName: 'some-name', podNamespace: 'some-namespace', - clusterName: 'some-cluster', + cluster: { name: 'some-cluster' }, }, containerSpec: {}, containerStatus: { diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx index 592a93e3ea..e6ad8a18aa 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx @@ -233,7 +233,7 @@ export const ContainerCard: React.FC = ({ /> {isPodExecTerminalEnabled && ( { podName: podAndErrors.pod.metadata?.name ?? 'unknown', podNamespace: podAndErrors.pod.metadata?.namespace ?? 'unknown', - clusterName: podAndErrors.cluster.name, + cluster: podAndErrors.cluster, }} containerSpec={containerSpec} containerStatus={containerStatus} diff --git a/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx b/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx index 3ffd4d8fa0..fbce4c4853 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx @@ -42,7 +42,7 @@ export const PodLogsDialog = ({ containerScope }: PodLogsDialogProps) => { buttonIcon={} buttonText="Logs" disabled={false} - title={`${containerScope.podName} - ${containerScope.containerName} logs on cluster ${containerScope.clusterName}`} + title={`${containerScope.podName} - ${containerScope.containerName} logs on cluster ${containerScope.cluster.name}`} > diff --git a/plugins/kubernetes-react/src/components/Pods/PodLogs/types.ts b/plugins/kubernetes-react/src/components/Pods/PodLogs/types.ts index 9ad551771e..c9f687d9d5 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodLogs/types.ts +++ b/plugins/kubernetes-react/src/components/Pods/PodLogs/types.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; /** * Contains the details needed to make a log request to Kubernetes, except the container name @@ -22,7 +23,7 @@ export interface PodScope { podName: string; podNamespace: string; - clusterName: string; + cluster: ClusterAttributes; } /** diff --git a/plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts b/plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts index 26764fc64c..98ed6c3177 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts +++ b/plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts @@ -41,7 +41,7 @@ export const usePodLogs = ({ containerScope, previous }: PodLogsOptions) => { podName: containerScope.podName, namespace: containerScope.podNamespace, containerName: containerScope.containerName, - clusterName: containerScope.clusterName, + clusterName: containerScope.cluster.name, previous, }); }, [JSON.stringify(containerScope)]); From 2bae1be978d808db09367c91e22b2229764c8c7a Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Wed, 24 Jan 2024 11:54:08 -0500 Subject: [PATCH 12/15] ClusterAttributes prop for PodExecTerminal Signed-off-by: Jamie Klassen --- plugins/kubernetes-react/api-report.md | 2 +- .../src/components/PodExecTerminal/PodExecTerminal.test.tsx | 6 +++--- .../src/components/PodExecTerminal/PodExecTerminal.tsx | 3 ++- .../components/PodExecTerminal/PodExecTerminalDialog.tsx | 4 ++-- .../src/components/Pods/PodDrawer/ContainerCard.tsx | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/kubernetes-react/api-report.md b/plugins/kubernetes-react/api-report.md index 734bacc7c9..ede2c9ddb7 100644 --- a/plugins/kubernetes-react/api-report.md +++ b/plugins/kubernetes-react/api-report.md @@ -692,7 +692,7 @@ export const PodExecTerminalDialog: ( // @public export interface PodExecTerminalProps { // (undocumented) - clusterName: string; + cluster: ClusterAttributes; // (undocumented) containerName: string; // (undocumented) diff --git a/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.test.tsx b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.test.tsx index 18e40bc241..4aa6112436 100644 --- a/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.test.tsx +++ b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.test.tsx @@ -32,7 +32,7 @@ global.TextEncoder = require('util').TextEncoder; const textEncoder = new TextEncoder(); describe('PodExecTerminal', () => { - const clusterName = 'cluster1'; + const cluster = { name: 'cluster1' }; const containerName = 'container2'; const podName = 'pod1'; const podNamespace = 'podNamespace'; @@ -45,7 +45,7 @@ describe('PodExecTerminal', () => { await renderInTestApp( { await renderInTestApp( { - const { clusterName, containerName, podName } = props; + const { cluster, containerName, podName } = props; const isPodExecTerminalSupported = useIsPodExecTerminalSupported(); @@ -42,7 +42,7 @@ export const PodExecTerminalDialog = (props: PodExecTerminalProps) => { isPodExecTerminalSupported.loading || !isPodExecTerminalSupported.value } - title={`${podName} - ${containerName} terminal shell on cluster ${clusterName}`} + title={`${podName} - ${containerName} terminal shell on cluster ${cluster.name}`} > diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx index e6ad8a18aa..746abbd668 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx @@ -233,7 +233,7 @@ export const ContainerCard: React.FC = ({ /> {isPodExecTerminalEnabled && ( Date: Wed, 24 Jan 2024 12:06:19 -0500 Subject: [PATCH 13/15] pod dialogs display cluster title Signed-off-by: Jamie Klassen --- .changeset/forty-eagles-kick.md | 5 +++++ .github/vale/config/vocabularies/Backstage/accept.txt | 1 + .../components/PodExecTerminal/PodExecTerminalDialog.tsx | 4 +++- .../src/components/Pods/PodLogs/PodLogsDialog.tsx | 6 +++++- 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .changeset/forty-eagles-kick.md diff --git a/.changeset/forty-eagles-kick.md b/.changeset/forty-eagles-kick.md new file mode 100644 index 0000000000..4d701a729b --- /dev/null +++ b/.changeset/forty-eagles-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +Pod dialogs display cluster title when specified. diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 9bb4a52cf4..525e24d251 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -92,6 +92,7 @@ Deutsche dev devops devs +dialogs discoverability Discoverability dls diff --git a/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalDialog.tsx b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalDialog.tsx index a073ad7525..e67c2c8bb4 100644 --- a/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalDialog.tsx +++ b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalDialog.tsx @@ -42,7 +42,9 @@ export const PodExecTerminalDialog = (props: PodExecTerminalProps) => { isPodExecTerminalSupported.loading || !isPodExecTerminalSupported.value } - title={`${podName} - ${containerName} terminal shell on cluster ${cluster.name}`} + title={`${podName} - ${containerName} terminal shell on cluster ${ + cluster.title || cluster.name + }`} > diff --git a/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx b/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx index fbce4c4853..b8b2cbdf42 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx @@ -42,7 +42,11 @@ export const PodLogsDialog = ({ containerScope }: PodLogsDialogProps) => { buttonIcon={} buttonText="Logs" disabled={false} - title={`${containerScope.podName} - ${containerScope.containerName} logs on cluster ${containerScope.cluster.name}`} + title={`${containerScope.podName} - ${ + containerScope.containerName + } logs on cluster ${ + containerScope.cluster.title || containerScope.cluster.name + }`} > From 494dca2326d8ec9495de0ed5830d29b232d8fef3 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Wed, 24 Jan 2024 12:13:43 -0500 Subject: [PATCH 14/15] document title field Signed-off-by: Jamie Klassen --- docs/features/kubernetes/configuration.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 331883be35..ff3a42c7ed 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -38,6 +38,7 @@ kubernetes: plural: 'rollouts' - url: http://127.0.0.2:9999 name: aws-cluster-1 + title: 'My AWS Cluster Number One' authProvider: 'aws' - type: 'gke' projectId: 'gke-clusters' @@ -151,6 +152,11 @@ The base URL to the Kubernetes control plane. Can be found by using the A name to represent this cluster, this must be unique within the `clusters` array. Users will see this value in the Software Catalog Kubernetes plugin. +##### `clusters.\*.title` + +A human-readable name for the cluster. This value will override the `name` field +for the purposes of display in the catalog. + ##### `clusters.\*.authProvider` This determines how the Kubernetes client authenticates with the Kubernetes From 2f8f9bb13aa0accf59585dffe8f4cdef7b61b301 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Thu, 8 Feb 2024 09:57:53 -0500 Subject: [PATCH 15/15] fix changeset to mention breaking changes Signed-off-by: Jamie Klassen --- .changeset/eight-pumas-rule.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.changeset/eight-pumas-rule.md b/.changeset/eight-pumas-rule.md index 57e6b4433b..166ebd8bd3 100644 --- a/.changeset/eight-pumas-rule.md +++ b/.changeset/eight-pumas-rule.md @@ -1,5 +1,7 @@ --- -'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-kubernetes-react': minor --- -The `PodAndErrors` type now includes the full `ClusterAttributes` rather than just the name. +**BREAKING** The `PodScope`, `PodAndErrors`, and `PodExecTerminalProps` types no +longer have a `clusterName` field; instead they now have the field `cluster` +which contains the full `ClusterAttributes`.