From ccf00accb4087cb502f32abcf5ef95c015655f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Blaise?= Date: Wed, 9 Aug 2023 16:37:40 +0200 Subject: [PATCH] Add kubernetes-plugin aws annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Clément Blaise --- .changeset/chatty-goats-mate.md | 6 +++ .../CatalogClusterLocator.test.ts | 45 +++++++++++++++++-- .../cluster-locator/CatalogClusterLocator.ts | 30 ++++++++++--- plugins/kubernetes-common/api-report.md | 8 ++++ .../src/catalog-entity-constants.ts | 16 +++++++ 5 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 .changeset/chatty-goats-mate.md diff --git a/.changeset/chatty-goats-mate.md b/.changeset/chatty-goats-mate.md new file mode 100644 index 0000000000..0c57c21bb8 --- /dev/null +++ b/.changeset/chatty-goats-mate.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': minor +'@backstage/plugin-kubernetes-common': minor +--- + +Add AWS Annotations to Kubernetes Cluster Resource diff --git a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts index 81ee863cb7..f436024131 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts @@ -29,7 +29,7 @@ const mockCatalogApi = { annotations: { 'kubernetes.io/api-server': 'https://apiserver.com', 'kubernetes.io/api-server-certificate-authority': 'caData', - 'kubernetes.io/auth-provider': 'aws', + 'kubernetes.io/auth-provider': 'oidc', 'kubernetes.io/oidc-token-provider': 'google', 'kubernetes.io/skip-metrics-lookup': 'true', 'kubernetes.io/skip-tls-verify': 'true', @@ -40,6 +40,24 @@ const mockCatalogApi = { namespace: 'default', }, }, + { + apiVersion: 'version', + kind: 'User', + metadata: { + annotations: { + 'kubernetes.io/api-server': 'https://apiserver.com', + 'kubernetes.io/api-server-certificate-authority': 'caData', + 'kubernetes.io/auth-provider': 'aws', + 'kubernetes.io/aws-assume-role': 'my-role', + 'kubernetes.io/aws-external-id': 'my-id', + 'kubernetes.io/oidc-token-provider': 'google', + 'kubernetes.io/dashboard-url': 'my-url', + 'kubernetes.io/dashboard-app': 'my-app', + }, + name: 'owned', + namespace: 'default', + }, + }, ], }), } as unknown as CatalogApi; @@ -67,12 +85,12 @@ describe('CatalogClusterLocator', () => { const result = await clusterSupplier.getClusters(); - expect(result).toHaveLength(1); + expect(result).toHaveLength(2); expect(result[0]).toStrictEqual({ name: 'owned', url: 'https://apiserver.com', caData: 'caData', - authProvider: 'aws', + authProvider: 'oidc', oidcTokenProvider: 'google', skipMetricsLookup: true, skipTLSVerify: true, @@ -80,4 +98,25 @@ describe('CatalogClusterLocator', () => { dashboardApp: 'my-app', }); }); + + it('returns the aws cluster details provided by annotations', async () => { + const clusterSupplier = CatalogClusterLocator.fromConfig(mockCatalogApi); + + const result = await clusterSupplier.getClusters(); + + expect(result).toHaveLength(2); + expect(result[1]).toStrictEqual({ + name: 'owned', + url: 'https://apiserver.com', + caData: 'caData', + authProvider: 'aws', + assumeRole: 'my-role', + externalId: 'my-id', + oidcTokenProvider: 'google', + skipMetricsLookup: false, + skipTLSVerify: false, + dashboardUrl: 'my-url', + dashboardApp: 'my-app', + }); + }); }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts index b952aefccf..c48cc99eb6 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; +import { + AWSClusterDetails, + ClusterDetails, + KubernetesClustersSupplier, +} from '../types/types'; import { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client'; import { ANNOTATION_KUBERNETES_API_SERVER, @@ -25,6 +29,8 @@ import { ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY, ANNOTATION_KUBERNETES_DASHBOARD_URL, ANNOTATION_KUBERNETES_DASHBOARD_APP, + ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID, + ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE, } from '@backstage/plugin-kubernetes-common'; export class CatalogClusterLocator implements KubernetesClustersSupplier { @@ -69,21 +75,31 @@ export class CatalogClusterLocator implements KubernetesClustersSupplier { skipMetricsLookup: entity.metadata.annotations![ ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP - ]! === 'true' - ? true - : false, + ]! === 'true', skipTLSVerify: entity.metadata.annotations![ ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY - ]! === 'true' - ? true - : false, + ]! === 'true', dashboardUrl: entity.metadata.annotations![ANNOTATION_KUBERNETES_DASHBOARD_URL]!, dashboardApp: entity.metadata.annotations![ANNOTATION_KUBERNETES_DASHBOARD_APP]!, }; + if (clusterDetails.authProvider === 'aws') { + return { + ...clusterDetails, + assumeRole: + entity.metadata.annotations![ + ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE + ]!, + externalId: + entity.metadata.annotations![ + ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID + ]!, + } as AWSClusterDetails; + } + return clusterDetails; }); } diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index 56faeea7d9..aae72d6f1e 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -31,6 +31,14 @@ export const ANNOTATION_KUBERNETES_API_SERVER_CA = export const ANNOTATION_KUBERNETES_AUTH_PROVIDER = 'kubernetes.io/auth-provider'; +// @public +export const ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE = + 'kubernetes.io/aws-assume-role'; + +// @public +export const ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID = + 'kubernetes.io/aws-external-id'; + // @public export const ANNOTATION_KUBERNETES_DASHBOARD_APP = 'kubernetes.io/dashboard-app'; diff --git a/plugins/kubernetes-common/src/catalog-entity-constants.ts b/plugins/kubernetes-common/src/catalog-entity-constants.ts index a1a1996777..8a826d4316 100644 --- a/plugins/kubernetes-common/src/catalog-entity-constants.ts +++ b/plugins/kubernetes-common/src/catalog-entity-constants.ts @@ -76,3 +76,19 @@ export const ANNOTATION_KUBERNETES_DASHBOARD_URL = */ export const ANNOTATION_KUBERNETES_DASHBOARD_APP = 'kubernetes.io/dashboard-app'; + +/** + * Annotation for specifying the assume role use to authenticate with AWS. + * + * @public + */ +export const ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE = + 'kubernetes.io/aws-assume-role'; + +/** + * Annotation for specifying an external id when communicating with AWS + * + * @public + */ +export const ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID = + 'kubernetes.io/aws-external-id';