From b87a88776d168dc039957ca32adda8ecd9f54b80 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 21:59:57 -0400 Subject: [PATCH 1/7] (feat): kubernetes add new backend endpoints to api interface Signed-off-by: Matthew Clarke --- .../src/service/KubernetesFanOutHandler.ts | 2 +- plugins/kubernetes-backend/src/types/types.ts | 7 +---- plugins/kubernetes-common/src/types.ts | 7 +++++ .../src/api/KubernetesBackendClient.ts | 30 ++++++++++++++++--- plugins/kubernetes/src/api/types.ts | 12 ++++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts index 7fcc9836a3..23163d1004 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -25,7 +25,6 @@ import { FetchResponseWrapper, ObjectToFetch, CustomResource, - CustomResourceMatcher, CustomResourcesByEntity, KubernetesObjectsByEntity, } from '../types/types'; @@ -40,6 +39,7 @@ import { ObjectsByEntityResponse, PodFetchResponse, KubernetesRequestAuth, + CustomResourceMatcher, } from '@backstage/plugin-kubernetes-common'; import { ContainerStatus, diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 33fde70b24..5ddfe7367d 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -18,6 +18,7 @@ import { Entity } from '@backstage/catalog-model'; import { Logger } from 'winston'; import type { JsonObject } from '@backstage/types'; import type { + CustomResourceMatcher, FetchResponse, KubernetesFetchError, KubernetesRequestAuth, @@ -86,12 +87,6 @@ export interface CustomResource extends ObjectToFetch { objectType: 'customresources'; } -/** - * - * @alpha - */ -export type CustomResourceMatcher = Omit; - /** * * @alpha diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index 830c32c32c..07378ae688 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -39,6 +39,13 @@ export interface KubernetesRequestAuth { }; } +/** @public */ +export interface CustomResourceMatcher { + group: string; + apiVersion: string; + plural: string; +} + /** @public */ export interface KubernetesRequestBody { auth?: KubernetesRequestAuth; diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes/src/api/KubernetesBackendClient.ts index 209f5f950d..04f4624b24 100644 --- a/plugins/kubernetes/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes/src/api/KubernetesBackendClient.ts @@ -16,10 +16,13 @@ import { KubernetesApi } from './types'; import { + KubernetesRequestAuth, KubernetesRequestBody, ObjectsByEntityResponse, + CustomResourceMatcher, } from '@backstage/plugin-kubernetes-common'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; export class KubernetesBackendClient implements KubernetesApi { private readonly discoveryApi: DiscoveryApi; @@ -51,10 +54,7 @@ export class KubernetesBackendClient implements KubernetesApi { return await response.json(); } - private async postRequired( - path: string, - requestBody: KubernetesRequestBody, - ): Promise { + private async postRequired(path: string, requestBody: any): Promise { const url = `${await this.discoveryApi.getBaseUrl('kubernetes')}${path}`; const { token: idToken } = await this.identityApi.getCredentials(); const response = await fetch(url, { @@ -78,6 +78,28 @@ export class KubernetesBackendClient implements KubernetesApi { ); } + async getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise { + return await this.postRequired('/resources/workloads/query', { + auth, + entityRef: stringifyEntityRef(entity), + }); + } + + async getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise { + return await this.postRequired(`/resources/custom/query`, { + entityRef: stringifyEntityRef(entity), + auth, + customResources, + }); + } + async getClusters(): Promise<{ name: string; authProvider: string }[]> { const { token: idToken } = await this.identityApi.getCredentials(); const url = `${await this.discoveryApi.getBaseUrl('kubernetes')}/clusters`; diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes/src/api/types.ts index 7c5943a6eb..b7e3f9fd49 100644 --- a/plugins/kubernetes/src/api/types.ts +++ b/plugins/kubernetes/src/api/types.ts @@ -15,10 +15,13 @@ */ import { + KubernetesRequestAuth, KubernetesRequestBody, ObjectsByEntityResponse, + CustomResourceMatcher, } from '@backstage/plugin-kubernetes-common'; import { createApiRef } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; export const kubernetesApiRef = createApiRef({ id: 'plugin.kubernetes.service', @@ -35,4 +38,13 @@ export interface KubernetesApi { oidcTokenProvider?: string | undefined; }[] >; + getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise; + getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise; } From 29dd35cdcb9d504f7c744804e7be5e777e7f1424 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:03:09 -0400 Subject: [PATCH 2/7] update api report Signed-off-by: Matthew Clarke --- plugins/kubernetes-backend/api-report.md | 4 +--- plugins/kubernetes-common/api-report.md | 10 ++++++++++ plugins/kubernetes/api-report.md | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index f97a0fd032..4219387819 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -8,6 +8,7 @@ import { Config } from '@backstage/config'; import { CoreV1Api } from '@kubernetes/client-node'; import { Credentials } from 'aws-sdk'; import { CustomObjectsApi } from '@kubernetes/client-node'; +import type { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; import { Duration } from 'luxon'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; @@ -101,9 +102,6 @@ export interface CustomResource extends ObjectToFetch { objectType: 'customresources'; } -// @alpha (undocumented) -export type CustomResourceMatcher = Omit; - // @alpha (undocumented) export interface CustomResourcesByEntity extends KubernetesObjectsByEntity { // (undocumented) diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index ef36d5ce28..9485bd0294 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -97,6 +97,16 @@ export interface CustomResourceFetchResponse { type: 'customresources'; } +// @public (undocumented) +export interface CustomResourceMatcher { + // (undocumented) + apiVersion: string; + // (undocumented) + group: string; + // (undocumented) + plural: string; +} + // @public (undocumented) export interface DaemonSetsFetchResponse { // (undocumented) diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 81ce386200..98ca4e4725 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -10,10 +10,12 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { ClientPodStatus } from '@backstage/plugin-kubernetes-common'; import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; +import { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { IdentityApi } from '@backstage/core-plugin-api'; import type { JsonObject } from '@backstage/types'; +import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { OAuthApi } from '@backstage/core-plugin-api'; import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; @@ -245,9 +247,20 @@ export interface KubernetesApi { }[] >; // (undocumented) + getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise; + // (undocumented) getObjectsByEntity( requestBody: KubernetesRequestBody, ): Promise; + // (undocumented) + getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise; } // Warning: (ae-missing-release-tag) "kubernetesApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -304,9 +317,20 @@ export class KubernetesBackendClient implements KubernetesApi { }[] >; // (undocumented) + getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise; + // (undocumented) getObjectsByEntity( requestBody: KubernetesRequestBody, ): Promise; + // (undocumented) + getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise; } // Warning: (ae-forgotten-export) The symbol "KubernetesContentProps" needs to be exported by the entry point index.d.ts From 0768d6dece0706b37218a2e08058bf7dd0a8f693 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:04:31 -0400 Subject: [PATCH 3/7] changeset Signed-off-by: Matthew Clarke --- .changeset/poor-lobsters-wonder.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/poor-lobsters-wonder.md diff --git a/.changeset/poor-lobsters-wonder.md b/.changeset/poor-lobsters-wonder.md new file mode 100644 index 0000000000..c0adea235f --- /dev/null +++ b/.changeset/poor-lobsters-wonder.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-common': patch +--- + +add new kubernetes backend endpoints to kubernetes backend client From 3da0c9a1812a92e6d0948a88e8c2306097561574 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:10:42 -0400 Subject: [PATCH 4/7] update mock Signed-off-by: Matthew Clarke --- plugins/kubernetes/dev/index.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx index 068f26b7f5..6a02540604 100644 --- a/plugins/kubernetes/dev/index.tsx +++ b/plugins/kubernetes/dev/index.tsx @@ -24,7 +24,9 @@ import { KubernetesApi, } from '../src'; import { + CustomResourceMatcher, FetchResponse, + KubernetesRequestAuth, ObjectsByEntityResponse, } from '@backstage/plugin-kubernetes-common'; import fixture1 from '../src/__fixtures__/1-deployments.json'; @@ -59,6 +61,19 @@ class MockKubernetesClient implements KubernetesApi { ({ type: type.toLocaleLowerCase('en-US'), resources } as FetchResponse), ); } + async getWorkloadsByEntity( + _auth: KubernetesRequestAuth, + _entity: Entity, + ): Promise { + throw new Error('Method not implemented.'); + } + async getCustomObjectsByEntity( + _auth: KubernetesRequestAuth, + _customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise { + throw new Error('Method not implemented.'); + } async getObjectsByEntity(): Promise { return { From 5eb54be2ac56af8765e18def149cefe09f0f920e Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:15:26 -0400 Subject: [PATCH 5/7] typo Signed-off-by: Matthew Clarke --- plugins/kubernetes/dev/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx index 6a02540604..3dd0557ae1 100644 --- a/plugins/kubernetes/dev/index.tsx +++ b/plugins/kubernetes/dev/index.tsx @@ -70,7 +70,7 @@ class MockKubernetesClient implements KubernetesApi { async getCustomObjectsByEntity( _auth: KubernetesRequestAuth, _customResources: CustomResourceMatcher[], - entity: Entity, + _entity: Entity, ): Promise { throw new Error('Method not implemented.'); } From 72e610f0e49122e3ee5fcce2ad8d5da5669d9d39 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Mon, 19 Sep 2022 15:57:13 -0400 Subject: [PATCH 6/7] pr feedback Signed-off-by: Matthew Clarke --- plugins/kubernetes-common/api-report.md | 18 +++++++++++++++ plugins/kubernetes-common/src/types.ts | 13 +++++++++++ plugins/kubernetes/api-report.md | 18 +++++---------- .../src/api/KubernetesBackendClient.ts | 23 ++++++++----------- plugins/kubernetes/src/api/types.ts | 12 ++++------ 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index 9485bd0294..85015662c6 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -89,6 +89,16 @@ export interface CronJobsFetchResponse { type: 'cronjobs'; } +// @public (undocumented) +export interface CustomObjectsByEntityRequest { + // (undocumented) + auth: KubernetesRequestAuth; + // (undocumented) + customResources: CustomResourceMatcher[]; + // (undocumented) + entity: Entity; +} + // @public (undocumented) export interface CustomResourceFetchResponse { // (undocumented) @@ -243,4 +253,12 @@ export interface StatefulSetsFetchResponse { // (undocumented) type: 'statefulsets'; } + +// @public (undocumented) +export interface WorkloadsByEntityRequest { + // (undocumented) + auth: KubernetesRequestAuth; + // (undocumented) + entity: Entity; +} ``` diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index 07378ae688..149caadb15 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -46,6 +46,19 @@ export interface CustomResourceMatcher { plural: string; } +/** @public */ +export interface WorkloadsByEntityRequest { + auth: KubernetesRequestAuth; + entity: Entity; +} + +/** @public */ +export interface CustomObjectsByEntityRequest { + auth: KubernetesRequestAuth; + customResources: CustomResourceMatcher[]; + entity: Entity; +} + /** @public */ export interface KubernetesRequestBody { auth?: KubernetesRequestAuth; diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 98ca4e4725..b7ec80aee3 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -10,12 +10,11 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { ClientPodStatus } from '@backstage/plugin-kubernetes-common'; import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; -import { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; +import { CustomObjectsByEntityRequest } from '@backstage/plugin-kubernetes-common'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { IdentityApi } from '@backstage/core-plugin-api'; import type { JsonObject } from '@backstage/types'; -import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { OAuthApi } from '@backstage/core-plugin-api'; import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; @@ -33,6 +32,7 @@ import { V1Pod } from '@kubernetes/client-node'; import { V1ReplicaSet } from '@kubernetes/client-node'; import { V1Service } from '@kubernetes/client-node'; import { V1StatefulSet } from '@kubernetes/client-node'; +import { WorkloadsByEntityRequest } from '@backstage/plugin-kubernetes-common'; // Warning: (ae-forgotten-export) The symbol "ClusterProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Cluster" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -248,9 +248,7 @@ export interface KubernetesApi { >; // (undocumented) getCustomObjectsByEntity( - auth: KubernetesRequestAuth, - customResources: CustomResourceMatcher[], - entity: Entity, + request: CustomObjectsByEntityRequest, ): Promise; // (undocumented) getObjectsByEntity( @@ -258,8 +256,7 @@ export interface KubernetesApi { ): Promise; // (undocumented) getWorkloadsByEntity( - auth: KubernetesRequestAuth, - entity: Entity, + request: WorkloadsByEntityRequest, ): Promise; } @@ -318,9 +315,7 @@ export class KubernetesBackendClient implements KubernetesApi { >; // (undocumented) getCustomObjectsByEntity( - auth: KubernetesRequestAuth, - customResources: CustomResourceMatcher[], - entity: Entity, + request: CustomObjectsByEntityRequest, ): Promise; // (undocumented) getObjectsByEntity( @@ -328,8 +323,7 @@ export class KubernetesBackendClient implements KubernetesApi { ): Promise; // (undocumented) getWorkloadsByEntity( - auth: KubernetesRequestAuth, - entity: Entity, + request: WorkloadsByEntityRequest, ): Promise; } diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes/src/api/KubernetesBackendClient.ts index 04f4624b24..bffc966333 100644 --- a/plugins/kubernetes/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes/src/api/KubernetesBackendClient.ts @@ -16,13 +16,13 @@ import { KubernetesApi } from './types'; import { - KubernetesRequestAuth, KubernetesRequestBody, ObjectsByEntityResponse, - CustomResourceMatcher, + WorkloadsByEntityRequest, + CustomObjectsByEntityRequest, } from '@backstage/plugin-kubernetes-common'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { stringifyEntityRef } from '@backstage/catalog-model'; export class KubernetesBackendClient implements KubernetesApi { private readonly discoveryApi: DiscoveryApi; @@ -79,24 +79,21 @@ export class KubernetesBackendClient implements KubernetesApi { } async getWorkloadsByEntity( - auth: KubernetesRequestAuth, - entity: Entity, + request: WorkloadsByEntityRequest, ): Promise { return await this.postRequired('/resources/workloads/query', { - auth, - entityRef: stringifyEntityRef(entity), + auth: request.auth, + entityRef: stringifyEntityRef(request.entity), }); } async getCustomObjectsByEntity( - auth: KubernetesRequestAuth, - customResources: CustomResourceMatcher[], - entity: Entity, + request: CustomObjectsByEntityRequest, ): Promise { return await this.postRequired(`/resources/custom/query`, { - entityRef: stringifyEntityRef(entity), - auth, - customResources, + entityRef: stringifyEntityRef(request.entity), + auth: request.auth, + customResources: request.customResources, }); } diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes/src/api/types.ts index b7e3f9fd49..0005a8d069 100644 --- a/plugins/kubernetes/src/api/types.ts +++ b/plugins/kubernetes/src/api/types.ts @@ -15,13 +15,12 @@ */ import { - KubernetesRequestAuth, KubernetesRequestBody, ObjectsByEntityResponse, - CustomResourceMatcher, + WorkloadsByEntityRequest, + CustomObjectsByEntityRequest, } from '@backstage/plugin-kubernetes-common'; import { createApiRef } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; export const kubernetesApiRef = createApiRef({ id: 'plugin.kubernetes.service', @@ -39,12 +38,9 @@ export interface KubernetesApi { }[] >; getWorkloadsByEntity( - auth: KubernetesRequestAuth, - entity: Entity, + request: WorkloadsByEntityRequest, ): Promise; getCustomObjectsByEntity( - auth: KubernetesRequestAuth, - customResources: CustomResourceMatcher[], - entity: Entity, + request: CustomObjectsByEntityRequest, ): Promise; } From 7a89391d176828e295998b03c1751fe89562b21b Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Mon, 19 Sep 2022 16:07:23 -0400 Subject: [PATCH 7/7] fix dev Signed-off-by: Matthew Clarke --- plugins/kubernetes/dev/index.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx index 3dd0557ae1..05fcdefc8a 100644 --- a/plugins/kubernetes/dev/index.tsx +++ b/plugins/kubernetes/dev/index.tsx @@ -24,10 +24,10 @@ import { KubernetesApi, } from '../src'; import { - CustomResourceMatcher, + CustomObjectsByEntityRequest, FetchResponse, - KubernetesRequestAuth, ObjectsByEntityResponse, + WorkloadsByEntityRequest, } from '@backstage/plugin-kubernetes-common'; import fixture1 from '../src/__fixtures__/1-deployments.json'; import fixture2 from '../src/__fixtures__/2-deployments.json'; @@ -62,15 +62,12 @@ class MockKubernetesClient implements KubernetesApi { ); } async getWorkloadsByEntity( - _auth: KubernetesRequestAuth, - _entity: Entity, + _request: WorkloadsByEntityRequest, ): Promise { throw new Error('Method not implemented.'); } async getCustomObjectsByEntity( - _auth: KubernetesRequestAuth, - _customResources: CustomResourceMatcher[], - _entity: Entity, + _request: CustomObjectsByEntityRequest, ): Promise { throw new Error('Method not implemented.'); }