diff --git a/.changeset/stupid-crabs-wash.md b/.changeset/stupid-crabs-wash.md new file mode 100644 index 0000000000..d9e7f317df --- /dev/null +++ b/.changeset/stupid-crabs-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Support fetch pod metrics with custom resources diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts index 3491268d39..ac6a59a7c4 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts @@ -31,6 +31,7 @@ import { registerMswTestHooks, } from '@backstage/backend-test-utils'; import { + CustomResourceFetchResponse, FetchResponse, KubernetesRequestAuth, ObjectsByEntityResponse, @@ -1428,5 +1429,78 @@ describe('KubernetesFanOutHandler', () => { }), ); }); + it('fetch pod metrics when pods used', async () => { + getClustersByEntity.mockImplementation(() => + Promise.resolve({ + clusters: [ + { + name: 'test-cluster', + title: 'cluster-title', + url: '', + authMetadata: {}, + }, + ], + }), + ); + + sut = getKubernetesFanOutHandler([]); + + const resources: CustomResourceFetchResponse[] = [ + { + type: 'customresources', + resources: [ + { + apiVersion: 'v1', + kind: 'Pod', + metadata: { + namespace: `ns-test-component-test-cluster`, + }, + }, + ], + }, + ]; + + fetchObjectsForService.mockImplementation(async () => ({ + responses: resources, + errors: [], + })); + + const result = await sut.getCustomResourcesByEntity( + { + entity, + auth: {}, + customResources: [ + { + group: '', + apiVersion: 'v1', + plural: 'pods', + }, + ], + }, + { credentials: mockCredentials }, + ); + + expect(fetchObjectsForService).toHaveBeenCalledTimes(1); + expect(fetchPodMetricsByNamespaces).toHaveBeenCalledTimes(1); + expect(fetchPodMetricsByNamespaces).toHaveBeenCalledWith( + expect.anything(), + { type: 'anonymous' }, + new Set(['ns-test-component-test-cluster']), + expect.anything(), + ); + expect(result).toStrictEqual({ + items: [ + { + cluster: { + name: 'test-cluster', + title: 'cluster-title', + }, + errors: [], + podMetrics: [POD_METRICS_FIXTURE], + resources, + }, + ], + }); + }); }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts index 54a038fffd..31c0c91807 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -147,7 +147,11 @@ export interface KubernetesFanOutHandlerOptions export interface KubernetesRequestBody extends ObjectsByEntityRequest {} const isPodFetchResponse = (fr: FetchResponse): fr is PodFetchResponse => - fr.type === 'pods'; + fr.type === 'pods' || + (fr.type === 'customresources' && + fr.resources.length > 0 && + fr.resources[0].apiVersion === 'v1' && + fr.resources[0].kind === 'Pod'); const isString = (str: string | undefined): str is string => str !== undefined; const numberOrBigIntToNumberOrString = (