use annotation key authProvider in metadata
This allows the nice simplification of the catalog clusterLocator -- just read the entire annotations block as auth metadata. Signed-off-by: Jamie Klassen <jklassen@vmware.com>
This commit is contained in:
@@ -14,9 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
KubernetesRequestAuth,
|
||||
} from '@backstage/plugin-kubernetes-common';
|
||||
import { DispatchStrategy } from './DispatchStrategy';
|
||||
import { ClusterDetails } from '../types';
|
||||
import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';
|
||||
import { AuthenticationStrategy } from './types';
|
||||
|
||||
describe('decorateClusterDetailsWithAuth', () => {
|
||||
@@ -39,7 +42,7 @@ describe('decorateClusterDetailsWithAuth', () => {
|
||||
url: 'notanything.com',
|
||||
name: 'randomName',
|
||||
authMetadata: {
|
||||
authProvider: 'google',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google',
|
||||
serviceAccountToken: 'added by mock strategy',
|
||||
},
|
||||
};
|
||||
@@ -52,7 +55,7 @@ describe('decorateClusterDetailsWithAuth', () => {
|
||||
{
|
||||
name: 'googleCluster',
|
||||
url: 'anything.com',
|
||||
authMetadata: { authProvider: 'google' },
|
||||
authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' },
|
||||
},
|
||||
authObject,
|
||||
);
|
||||
@@ -61,7 +64,7 @@ describe('decorateClusterDetailsWithAuth', () => {
|
||||
{
|
||||
name: 'googleCluster',
|
||||
url: 'anything.com',
|
||||
authMetadata: { authProvider: 'google' },
|
||||
authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' },
|
||||
},
|
||||
authObject,
|
||||
);
|
||||
@@ -74,7 +77,7 @@ describe('decorateClusterDetailsWithAuth', () => {
|
||||
{
|
||||
name: 'test-cluster',
|
||||
url: 'anything.com',
|
||||
authMetadata: { authProvider: 'linode' },
|
||||
authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'linode' },
|
||||
},
|
||||
authObject,
|
||||
),
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
import { AuthenticationStrategy } from './types';
|
||||
import { AuthMetadata, ClusterDetails } from '../types';
|
||||
import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
KubernetesRequestAuth,
|
||||
} from '@backstage/plugin-kubernetes-common';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -42,7 +45,8 @@ export class DispatchStrategy implements AuthenticationStrategy {
|
||||
clusterDetails: ClusterDetails,
|
||||
auth: KubernetesRequestAuth,
|
||||
) {
|
||||
const authProvider = clusterDetails.authMetadata.authProvider;
|
||||
const authProvider =
|
||||
clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];
|
||||
if (this.strategyMap[authProvider]) {
|
||||
return this.strategyMap[authProvider].decorateClusterDetailsWithAuth(
|
||||
clusterDetails,
|
||||
@@ -55,10 +59,11 @@ export class DispatchStrategy implements AuthenticationStrategy {
|
||||
}
|
||||
|
||||
public validate(authMetadata: AuthMetadata) {
|
||||
const strategy = this.strategyMap[authMetadata.authProvider];
|
||||
const authProvider = authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];
|
||||
const strategy = this.strategyMap[authProvider];
|
||||
if (!strategy) {
|
||||
throw new Error(
|
||||
`authProvider "${authMetadata.authProvider}" has no config associated with it`,
|
||||
`authProvider "${authProvider}" has no config associated with it`,
|
||||
);
|
||||
}
|
||||
strategy.validate(authMetadata);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import '@backstage/backend-common';
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,
|
||||
ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,
|
||||
ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,
|
||||
@@ -35,7 +36,7 @@ const mockCatalogApi = {
|
||||
annotations: {
|
||||
'kubernetes.io/api-server': 'https://apiserver.com',
|
||||
'kubernetes.io/api-server-certificate-authority': 'caData',
|
||||
'kubernetes.io/auth-provider': 'oidc',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc',
|
||||
[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google',
|
||||
'kubernetes.io/skip-metrics-lookup': 'true',
|
||||
'kubernetes.io/skip-tls-verify': 'true',
|
||||
@@ -53,7 +54,7 @@ const mockCatalogApi = {
|
||||
annotations: {
|
||||
'kubernetes.io/api-server': 'https://apiserver.com',
|
||||
'kubernetes.io/api-server-certificate-authority': 'caData',
|
||||
'kubernetes.io/auth-provider': 'aws',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'aws',
|
||||
[ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my-role',
|
||||
[ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: 'my-id',
|
||||
[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google',
|
||||
@@ -97,10 +98,9 @@ describe('CatalogClusterLocator', () => {
|
||||
url: 'https://apiserver.com',
|
||||
caData: 'caData',
|
||||
authMetadata: {
|
||||
authProvider: 'oidc',
|
||||
'kubernetes.io/api-server': 'https://apiserver.com',
|
||||
'kubernetes.io/api-server-certificate-authority': 'caData',
|
||||
'kubernetes.io/auth-provider': 'oidc',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc',
|
||||
[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google',
|
||||
'kubernetes.io/skip-metrics-lookup': 'true',
|
||||
'kubernetes.io/skip-tls-verify': 'true',
|
||||
@@ -125,10 +125,9 @@ describe('CatalogClusterLocator', () => {
|
||||
url: 'https://apiserver.com',
|
||||
caData: 'caData',
|
||||
authMetadata: {
|
||||
authProvider: 'aws',
|
||||
'kubernetes.io/api-server': 'https://apiserver.com',
|
||||
'kubernetes.io/api-server-certificate-authority': 'caData',
|
||||
'kubernetes.io/auth-provider': 'aws',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'aws',
|
||||
[ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my-role',
|
||||
[ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: 'my-id',
|
||||
[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google',
|
||||
|
||||
@@ -57,17 +57,9 @@ export class CatalogClusterLocator implements KubernetesClustersSupplier {
|
||||
const clusterDetails: ClusterDetails = {
|
||||
name: entity.metadata.name,
|
||||
url: entity.metadata.annotations![ANNOTATION_KUBERNETES_API_SERVER]!,
|
||||
authMetadata: entity.metadata.annotations!,
|
||||
caData:
|
||||
entity.metadata.annotations![ANNOTATION_KUBERNETES_API_SERVER_CA]!,
|
||||
...{
|
||||
authMetadata: {
|
||||
authProvider:
|
||||
entity.metadata.annotations![
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER
|
||||
]!,
|
||||
...entity.metadata.annotations,
|
||||
},
|
||||
},
|
||||
skipMetricsLookup:
|
||||
entity.metadata.annotations![
|
||||
ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import '@backstage/backend-common';
|
||||
import { ConfigReader, Config } from '@backstage/config';
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,
|
||||
ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,
|
||||
} from '@backstage/plugin-kubernetes-common';
|
||||
@@ -65,7 +66,9 @@ describe('ConfigClusterLocator', () => {
|
||||
{
|
||||
name: 'cluster1',
|
||||
url: 'http://localhost:8080',
|
||||
authMetadata: { authProvider: 'serviceAccount' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
},
|
||||
skipMetricsLookup: false,
|
||||
skipTLSVerify: false,
|
||||
caData: undefined,
|
||||
@@ -106,7 +109,7 @@ describe('ConfigClusterLocator', () => {
|
||||
dashboardUrl: 'https://k8s.foo.com',
|
||||
url: 'http://localhost:8080',
|
||||
authMetadata: {
|
||||
authProvider: 'serviceAccount',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
serviceAccountToken: 'token',
|
||||
},
|
||||
skipTLSVerify: false,
|
||||
@@ -117,7 +120,7 @@ describe('ConfigClusterLocator', () => {
|
||||
{
|
||||
name: 'cluster2',
|
||||
url: 'http://localhost:8081',
|
||||
authMetadata: { authProvider: 'google' },
|
||||
authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' },
|
||||
skipTLSVerify: true,
|
||||
skipMetricsLookup: false,
|
||||
caData: undefined,
|
||||
@@ -199,7 +202,9 @@ describe('ConfigClusterLocator', () => {
|
||||
{
|
||||
name: 'cluster1',
|
||||
url: 'http://localhost:8080',
|
||||
authMetadata: { authProvider: 'serviceAccount' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
},
|
||||
skipMetricsLookup: false,
|
||||
skipTLSVerify: false,
|
||||
caData: undefined,
|
||||
@@ -235,7 +240,9 @@ describe('ConfigClusterLocator', () => {
|
||||
{
|
||||
name: 'cluster1',
|
||||
url: 'http://localhost:8080',
|
||||
authMetadata: { authProvider: 'serviceAccount' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
},
|
||||
skipMetricsLookup: false,
|
||||
skipTLSVerify: false,
|
||||
caData: undefined,
|
||||
@@ -272,7 +279,9 @@ describe('ConfigClusterLocator', () => {
|
||||
{
|
||||
name: 'cluster1',
|
||||
url: 'http://localhost:8080',
|
||||
authMetadata: { authProvider: 'serviceAccount' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
},
|
||||
skipMetricsLookup: false,
|
||||
skipTLSVerify: false,
|
||||
caData: undefined,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,
|
||||
ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,
|
||||
ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,
|
||||
@@ -45,7 +46,7 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier {
|
||||
caData: c.getOptionalString('caData'),
|
||||
caFile: c.getOptionalString('caFile'),
|
||||
authMetadata: {
|
||||
authProvider,
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider,
|
||||
...ConfigClusterLocator.parseAuthMetadata(c),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
|
||||
import { Config, ConfigReader } from '@backstage/config';
|
||||
import { getCombinedClusterSupplier } from './index';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { ANNOTATION_KUBERNETES_AUTH_PROVIDER } from '@backstage/plugin-kubernetes-common';
|
||||
import { getCombinedClusterSupplier } from './index';
|
||||
import { ClusterDetails } from '../types/types';
|
||||
import { AuthenticationStrategy, DispatchStrategy } from '../auth';
|
||||
|
||||
@@ -57,12 +58,7 @@ describe('getCombinedClusterSupplier', () => {
|
||||
const clusterSupplier = getCombinedClusterSupplier(
|
||||
config,
|
||||
catalogApi,
|
||||
new DispatchStrategy({
|
||||
authStrategyMap: {
|
||||
serviceAccount: mockStrategy,
|
||||
google: mockStrategy,
|
||||
},
|
||||
}),
|
||||
mockStrategy,
|
||||
);
|
||||
const result = await clusterSupplier.getClusters();
|
||||
|
||||
@@ -71,7 +67,7 @@ describe('getCombinedClusterSupplier', () => {
|
||||
name: 'cluster1',
|
||||
url: 'http://localhost:8080',
|
||||
authMetadata: {
|
||||
authProvider: 'serviceAccount',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
serviceAccountToken: 'token',
|
||||
},
|
||||
skipMetricsLookup: false,
|
||||
@@ -82,7 +78,7 @@ describe('getCombinedClusterSupplier', () => {
|
||||
{
|
||||
name: 'cluster2',
|
||||
url: 'http://localhost:8081',
|
||||
authMetadata: { authProvider: 'google' },
|
||||
authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' },
|
||||
skipMetricsLookup: false,
|
||||
skipTLSVerify: false,
|
||||
caData: undefined,
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
import { getVoidLogger } from '@backstage/backend-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Config, ConfigReader } from '@backstage/config';
|
||||
import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,
|
||||
ObjectsByEntityResponse,
|
||||
} from '@backstage/plugin-kubernetes-common';
|
||||
import express from 'express';
|
||||
import request from 'supertest';
|
||||
import {
|
||||
@@ -63,12 +67,17 @@ describe('KubernetesBuilder', () => {
|
||||
{
|
||||
name: 'some-cluster',
|
||||
url: 'https://localhost:1234',
|
||||
authMetadata: { authProvider: 'serviceAccount' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'some-other-cluster',
|
||||
url: 'https://localhost:1235',
|
||||
authMetadata: { authProvider: 'google' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc',
|
||||
[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google',
|
||||
},
|
||||
},
|
||||
];
|
||||
const clusterSupplier: KubernetesClustersSupplier = {
|
||||
@@ -116,7 +125,8 @@ describe('KubernetesBuilder', () => {
|
||||
},
|
||||
{
|
||||
name: 'some-other-cluster',
|
||||
authProvider: 'google',
|
||||
authProvider: 'oidc',
|
||||
oidcTokenProvider: 'google',
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -190,14 +200,16 @@ describe('KubernetesBuilder', () => {
|
||||
const someCluster: ClusterDetails = {
|
||||
name: 'some-cluster',
|
||||
url: 'https://localhost:1234',
|
||||
authMetadata: { authProvider: 'serviceAccount' },
|
||||
authMetadata: {
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount',
|
||||
},
|
||||
};
|
||||
const clusters: ClusterDetails[] = [
|
||||
someCluster,
|
||||
{
|
||||
name: 'some-other-cluster',
|
||||
url: 'https://localhost:1235',
|
||||
authMetadata: { authProvider: 'google' },
|
||||
authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' },
|
||||
},
|
||||
];
|
||||
const clusterSupplier: KubernetesClustersSupplier = {
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import { kubernetesPermissions } from '@backstage/plugin-kubernetes-common';
|
||||
import {
|
||||
ANNOTATION_KUBERNETES_AUTH_PROVIDER,
|
||||
ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,
|
||||
kubernetesPermissions,
|
||||
} from '@backstage/plugin-kubernetes-common';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';
|
||||
import express from 'express';
|
||||
@@ -341,11 +345,12 @@ export class KubernetesBuilder {
|
||||
const clusterDetails = await this.fetchClusterDetails(clusterSupplier);
|
||||
res.json({
|
||||
items: clusterDetails.map(cd => {
|
||||
const oidcTokenProvider = cd.authMetadata.oidcTokenProvider;
|
||||
const oidcTokenProvider =
|
||||
cd.authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];
|
||||
return {
|
||||
name: cd.name,
|
||||
dashboardUrl: cd.dashboardUrl,
|
||||
authProvider: cd.authMetadata.authProvider,
|
||||
authProvider: cd.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER],
|
||||
...(oidcTokenProvider && { oidcTokenProvider }),
|
||||
};
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user