Merge pull request #30862 from backstage/catalog-provider-gcp-support-creds-json
[Catalog provider gcp] Support google service account creds json
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-gcp': patch
|
||||
---
|
||||
|
||||
Added support for Google Service account credentials config used in GkeEntityProvider.
|
||||
Added support for additional metadata `authProvider` and `owner` to be set for the GKE cluster entities.
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
This is an extension module to the plugin-catalog-backend plugin, containing catalog processors and providers to ingest GCP resources as `Resource` kind entities.
|
||||
|
||||
## Authentication
|
||||
|
||||
The GKE Entity Provider supports two authentication methods:
|
||||
|
||||
1. **Service Account Credentials** (recommended for production): Provide Google Service Account credentials directly in the configuration
|
||||
2. **Application Default Credentials**: If no credentials are provided, the provider falls back to:
|
||||
- `GOOGLE_APPLICATION_CREDENTIALS` environment variable pointing to a service account key file
|
||||
- Google Cloud SDK default credentials (when running on Google Cloud Platform)
|
||||
|
||||
## installation
|
||||
|
||||
Register the plugin in `catalog.ts``
|
||||
@@ -38,4 +47,26 @@ catalog:
|
||||
frequency: { minutes: 30 }
|
||||
# supports ISO duration, "human duration" as used in code
|
||||
timeout: { minutes: 3 }
|
||||
# Optional: Google Service Account credentials for authentication
|
||||
# If not provided, falls back to Application Default Credentials or GOOGLE_APPLICATION_CREDENTIALS
|
||||
googleServiceAccountCredentials: |
|
||||
{
|
||||
"type": "service_account",
|
||||
"project_id": "your-project-id",
|
||||
"private_key_id": "key-id",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "your-service-account@your-project.iam.gserviceaccount.com",
|
||||
"client_id": "client-id",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
|
||||
}
|
||||
# Optional: Authentication provider for Kubernetes clusters
|
||||
# Defaults to 'google' if not specified
|
||||
# Common values: 'google', 'googleServiceAccount'
|
||||
authProvider: googleServiceAccount
|
||||
# Optional: Owner of the discovered GKE clusters
|
||||
# Defaults to 'unknown' if not specified
|
||||
owner: platform-team
|
||||
```
|
||||
|
||||
+16
@@ -38,6 +38,22 @@ export interface Config {
|
||||
* (Optional) TaskScheduleDefinition for the refresh.
|
||||
*/
|
||||
schedule: SchedulerServiceTaskScheduleDefinitionConfig;
|
||||
/**
|
||||
* (Optional) Google Service Account credentials for authentication
|
||||
* JSON string containing the service account key
|
||||
* @visibility secret
|
||||
*/
|
||||
googleServiceAccountCredentials?: string;
|
||||
/**
|
||||
* (Optional) Authentication provider to use for Kubernetes clusters
|
||||
* Defaults to 'google' for backward compatibility
|
||||
*/
|
||||
authProvider?: string;
|
||||
/**
|
||||
* (Optional) Owner of the discovered clusters
|
||||
* Defaults to 'unknown' if not specified
|
||||
*/
|
||||
owner?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,6 +19,13 @@ import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api';
|
||||
import * as container from '@google-cloud/container';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
|
||||
// Mock the container module
|
||||
jest.mock('@google-cloud/container', () => ({
|
||||
v1: {
|
||||
ClusterManagerClient: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('GkeEntityProvider', () => {
|
||||
const clusterManagerClientMock = {
|
||||
listClusters: jest.fn(),
|
||||
@@ -189,6 +196,275 @@ describe('GkeEntityProvider', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it('should use configured values for authProvider and owner', async () => {
|
||||
const customGkeEntityProvider = GkeEntityProvider.fromConfigWithClient({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/parent1/locations/-'],
|
||||
authProvider: 'googleServiceAccount',
|
||||
owner: 'sre',
|
||||
schedule: {
|
||||
frequency: {
|
||||
minutes: 3,
|
||||
},
|
||||
timeout: {
|
||||
minutes: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
clusterManagerClient: clusterManagerClientMock as any,
|
||||
});
|
||||
|
||||
clusterManagerClientMock.listClusters.mockImplementation(() => [
|
||||
{
|
||||
clusters: [
|
||||
{
|
||||
name: 'some-cluster',
|
||||
endpoint: '127.0.0.1',
|
||||
location: 'some-location',
|
||||
selfLink: 'https://127.0.0.1/some-link',
|
||||
masterAuth: {
|
||||
clusterCaCertificate: 'abcdefg',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
await customGkeEntityProvider.connect(connectionMock);
|
||||
await customGkeEntityProvider.refresh();
|
||||
expect(connectionMock.applyMutation).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('authProvider and owner configuration', () => {
|
||||
it('should use default values when authProvider and owner not configured', async () => {
|
||||
const defaultGkeEntityProvider = GkeEntityProvider.fromConfigWithClient({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/parent1/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 3 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
clusterManagerClient: clusterManagerClientMock as any,
|
||||
});
|
||||
|
||||
clusterManagerClientMock.listClusters.mockImplementation(() => [
|
||||
{
|
||||
clusters: [
|
||||
{
|
||||
name: 'default-cluster',
|
||||
endpoint: '127.0.0.1',
|
||||
location: 'us-central1',
|
||||
selfLink: 'https://127.0.0.1/default-link',
|
||||
masterAuth: {
|
||||
clusterCaCertificate: 'defaultcert',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
await defaultGkeEntityProvider.connect(connectionMock);
|
||||
await defaultGkeEntityProvider.refresh();
|
||||
|
||||
expect(connectionMock.applyMutation).toHaveBeenCalledWith({
|
||||
type: 'full',
|
||||
entities: [
|
||||
{
|
||||
entity: expect.objectContaining({
|
||||
metadata: expect.objectContaining({
|
||||
name: 'default-cluster',
|
||||
annotations: expect.objectContaining({
|
||||
'kubernetes.io/auth-provider': 'google', // Default value
|
||||
}),
|
||||
}),
|
||||
spec: expect.objectContaining({
|
||||
owner: 'unknown', // Default value
|
||||
type: 'kubernetes-cluster',
|
||||
}),
|
||||
}),
|
||||
locationKey: 'gcp-gke:us-central1',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should use both custom authProvider and owner when configured', async () => {
|
||||
const fullyCustomGkeEntityProvider =
|
||||
GkeEntityProvider.fromConfigWithClient({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/parent1/locations/-'],
|
||||
authProvider: 'aws',
|
||||
owner: 'devops-team',
|
||||
schedule: {
|
||||
frequency: { minutes: 3 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
clusterManagerClient: clusterManagerClientMock as any,
|
||||
});
|
||||
|
||||
clusterManagerClientMock.listClusters.mockImplementation(() => [
|
||||
{
|
||||
clusters: [
|
||||
{
|
||||
name: 'aws-auth-cluster',
|
||||
endpoint: '127.0.0.1',
|
||||
location: 'asia-southeast1',
|
||||
selfLink: 'https://127.0.0.1/aws-link',
|
||||
masterAuth: {
|
||||
clusterCaCertificate: 'awscert',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
await fullyCustomGkeEntityProvider.connect(connectionMock);
|
||||
await fullyCustomGkeEntityProvider.refresh();
|
||||
|
||||
expect(connectionMock.applyMutation).toHaveBeenCalledWith({
|
||||
type: 'full',
|
||||
entities: [
|
||||
{
|
||||
entity: expect.objectContaining({
|
||||
metadata: expect.objectContaining({
|
||||
name: 'aws-auth-cluster',
|
||||
annotations: expect.objectContaining({
|
||||
'kubernetes.io/auth-provider': 'aws',
|
||||
}),
|
||||
}),
|
||||
spec: expect.objectContaining({
|
||||
owner: 'devops-team',
|
||||
type: 'kubernetes-cluster',
|
||||
}),
|
||||
}),
|
||||
locationKey: 'gcp-gke:asia-southeast1',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should apply authProvider and owner to multiple clusters', async () => {
|
||||
const multiClusterGkeEntityProvider =
|
||||
GkeEntityProvider.fromConfigWithClient({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/parent1/locations/-'],
|
||||
authProvider: 'oidc',
|
||||
owner: 'sre-team',
|
||||
schedule: {
|
||||
frequency: { minutes: 3 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
clusterManagerClient: clusterManagerClientMock as any,
|
||||
});
|
||||
|
||||
clusterManagerClientMock.listClusters.mockImplementation(() => [
|
||||
{
|
||||
clusters: [
|
||||
{
|
||||
name: 'cluster-1',
|
||||
endpoint: '127.0.0.1',
|
||||
location: 'us-central1',
|
||||
selfLink: 'https://127.0.0.1/cluster1-link',
|
||||
masterAuth: {
|
||||
clusterCaCertificate: 'cert1',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'cluster-2',
|
||||
endpoint: '127.0.0.2',
|
||||
location: 'us-east1',
|
||||
selfLink: 'https://127.0.0.2/cluster2-link',
|
||||
masterAuth: {
|
||||
clusterCaCertificate: 'cert2',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
await multiClusterGkeEntityProvider.connect(connectionMock);
|
||||
await multiClusterGkeEntityProvider.refresh();
|
||||
|
||||
expect(connectionMock.applyMutation).toHaveBeenCalledWith({
|
||||
type: 'full',
|
||||
entities: [
|
||||
{
|
||||
entity: expect.objectContaining({
|
||||
metadata: expect.objectContaining({
|
||||
name: 'cluster-1',
|
||||
annotations: expect.objectContaining({
|
||||
'kubernetes.io/auth-provider': 'oidc',
|
||||
}),
|
||||
}),
|
||||
spec: expect.objectContaining({
|
||||
owner: 'sre-team',
|
||||
type: 'kubernetes-cluster',
|
||||
}),
|
||||
}),
|
||||
locationKey: 'gcp-gke:us-central1',
|
||||
},
|
||||
{
|
||||
entity: expect.objectContaining({
|
||||
metadata: expect.objectContaining({
|
||||
name: 'cluster-2',
|
||||
annotations: expect.objectContaining({
|
||||
'kubernetes.io/auth-provider': 'oidc',
|
||||
}),
|
||||
}),
|
||||
spec: expect.objectContaining({
|
||||
owner: 'sre-team',
|
||||
type: 'kubernetes-cluster',
|
||||
}),
|
||||
}),
|
||||
locationKey: 'gcp-gke:us-east1',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should log GKE API errors', async () => {
|
||||
clusterManagerClientMock.listClusters.mockRejectedValue(
|
||||
new Error('some-error'),
|
||||
@@ -197,4 +473,192 @@ describe('GkeEntityProvider', () => {
|
||||
expect(connectionMock.applyMutation).toHaveBeenCalledTimes(0);
|
||||
expect(logger.error).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
describe('credentials support', () => {
|
||||
const MockedClusterManagerClient = container.v1
|
||||
.ClusterManagerClient as jest.MockedClass<
|
||||
typeof container.v1.ClusterManagerClient
|
||||
>;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
MockedClusterManagerClient.mockClear();
|
||||
schedulerMock.createScheduledTaskRunner.mockReturnValue(taskRunner);
|
||||
});
|
||||
|
||||
it('should use credentials from config when provided', () => {
|
||||
const mockCredentials = {
|
||||
type: 'service_account',
|
||||
project_id: 'test-project',
|
||||
private_key_id: 'key-id',
|
||||
private_key:
|
||||
'-----BEGIN PRIVATE KEY-----\ntest-key\n-----END PRIVATE KEY-----\n',
|
||||
client_email: 'test@test-project.iam.gserviceaccount.com',
|
||||
client_id: 'client-id',
|
||||
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
|
||||
token_uri: 'https://oauth2.googleapis.com/token',
|
||||
auth_provider_x509_cert_url:
|
||||
'https://www.googleapis.com/oauth2/v1/certs',
|
||||
client_x509_cert_url:
|
||||
'https://www.googleapis.com/robot/v1/metadata/x509/test%40test-project.iam.gserviceaccount.com',
|
||||
};
|
||||
|
||||
GkeEntityProvider.fromConfig({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/test-project/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
googleServiceAccountCredentials:
|
||||
JSON.stringify(mockCredentials),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
});
|
||||
|
||||
expect(MockedClusterManagerClient).toHaveBeenCalledWith({
|
||||
credentials: mockCredentials,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fall back to default credentials when no credentials provided', () => {
|
||||
GkeEntityProvider.fromConfig({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/test-project/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
// No googleServiceAccountCredentials provided
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
});
|
||||
|
||||
expect(MockedClusterManagerClient).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should throw error for invalid JSON credentials', () => {
|
||||
expect(() => {
|
||||
GkeEntityProvider.fromConfig({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/test-project/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
googleServiceAccountCredentials: 'invalid-json',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
});
|
||||
}).toThrow(
|
||||
'Failed to parse Google Service Account credentials from config:',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error for malformed JSON credentials', () => {
|
||||
expect(() => {
|
||||
GkeEntityProvider.fromConfig({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/test-project/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
googleServiceAccountCredentials: '{"incomplete": "json"',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
});
|
||||
}).toThrow(
|
||||
'Failed to parse Google Service Account credentials from config:',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle undefined credentials as fallback to default', () => {
|
||||
GkeEntityProvider.fromConfig({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/test-project/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
// googleServiceAccountCredentials is undefined
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
});
|
||||
|
||||
expect(MockedClusterManagerClient).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should read authProvider and owner from config', () => {
|
||||
const provider = GkeEntityProvider.fromConfig({
|
||||
logger: logger as any,
|
||||
config: new ConfigReader({
|
||||
catalog: {
|
||||
providers: {
|
||||
gcp: {
|
||||
gke: {
|
||||
parents: ['projects/test-project/locations/-'],
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
},
|
||||
authProvider: 'googleServiceAccount',
|
||||
owner: 'platform-team',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
scheduler: schedulerMock,
|
||||
});
|
||||
|
||||
expect(provider).toBeDefined();
|
||||
expect(MockedClusterManagerClient).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -47,6 +47,8 @@ export class GkeEntityProvider implements EntityProvider {
|
||||
private readonly logger: LoggerService;
|
||||
private readonly scheduleFn: () => Promise<void>;
|
||||
private readonly gkeParents: string[];
|
||||
private readonly gkeAuthProvider: string | undefined;
|
||||
private readonly gkeOwner: string | undefined;
|
||||
private readonly clusterManagerClient: container.v1.ClusterManagerClient;
|
||||
private connection?: EntityProviderConnection;
|
||||
|
||||
@@ -54,11 +56,15 @@ export class GkeEntityProvider implements EntityProvider {
|
||||
logger: LoggerService,
|
||||
taskRunner: SchedulerServiceTaskRunner,
|
||||
gkeParents: string[],
|
||||
gkeAuthProvider: string | undefined,
|
||||
gkeOwner: string | undefined,
|
||||
clusterManagerClient: container.v1.ClusterManagerClient,
|
||||
) {
|
||||
this.logger = logger;
|
||||
this.scheduleFn = this.createScheduleFn(taskRunner);
|
||||
this.gkeParents = gkeParents;
|
||||
this.gkeAuthProvider = gkeAuthProvider;
|
||||
this.gkeOwner = gkeOwner;
|
||||
this.clusterManagerClient = clusterManagerClient;
|
||||
}
|
||||
|
||||
@@ -71,11 +77,37 @@ export class GkeEntityProvider implements EntityProvider {
|
||||
scheduler: SchedulerService;
|
||||
config: Config;
|
||||
}) {
|
||||
const gkeProviderConfig = config.getConfig('catalog.providers.gcp.gke');
|
||||
const credentials = gkeProviderConfig.getOptionalString(
|
||||
'googleServiceAccountCredentials',
|
||||
);
|
||||
|
||||
let clusterManagerClient: container.v1.ClusterManagerClient;
|
||||
|
||||
if (credentials && credentials.trim()) {
|
||||
// Use credentials from config
|
||||
try {
|
||||
const credentialsObject = JSON.parse(credentials);
|
||||
clusterManagerClient = new container.v1.ClusterManagerClient({
|
||||
credentials: credentialsObject,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to parse Google Service Account credentials from config: ${
|
||||
error instanceof Error ? error.message : 'Invalid JSON'
|
||||
}`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Fall back to Application Default Credentials or GOOGLE_APPLICATION_CREDENTIALS
|
||||
clusterManagerClient = new container.v1.ClusterManagerClient();
|
||||
}
|
||||
|
||||
return GkeEntityProvider.fromConfigWithClient({
|
||||
logger,
|
||||
scheduler: scheduler,
|
||||
config,
|
||||
clusterManagerClient: new container.v1.ClusterManagerClient(),
|
||||
clusterManagerClient,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -98,6 +130,8 @@ export class GkeEntityProvider implements EntityProvider {
|
||||
logger,
|
||||
scheduler.createScheduledTaskRunner(schedule),
|
||||
gkeProviderConfig.getStringArray('parents'),
|
||||
gkeProviderConfig.getOptionalString('authProvider'),
|
||||
gkeProviderConfig.getOptionalString('owner'),
|
||||
clusterManagerClient,
|
||||
);
|
||||
}
|
||||
@@ -152,7 +186,8 @@ export class GkeEntityProvider implements EntityProvider {
|
||||
[ANNOTATION_KUBERNETES_API_SERVER]: `https://${cluster.endpoint}`,
|
||||
[ANNOTATION_KUBERNETES_API_SERVER_CA]:
|
||||
cluster.masterAuth?.clusterCaCertificate || '',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google',
|
||||
[ANNOTATION_KUBERNETES_AUTH_PROVIDER]:
|
||||
this.gkeAuthProvider || 'google',
|
||||
[ANNOTATION_KUBERNETES_DASHBOARD_APP]: 'gke',
|
||||
[ANNOTATION_LOCATION]: location,
|
||||
[ANNOTATION_ORIGIN_LOCATION]: location,
|
||||
@@ -167,7 +202,7 @@ export class GkeEntityProvider implements EntityProvider {
|
||||
},
|
||||
spec: {
|
||||
type: 'kubernetes-cluster',
|
||||
owner: 'unknown',
|
||||
owner: this.gkeOwner || 'unknown',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
+44
@@ -67,3 +67,47 @@ exports[`GkeEntityProvider should return clusters as Resources 1`] = `
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GkeEntityProvider should use configured values for authProvider and owner 1`] = `
|
||||
[MockFunction] {
|
||||
"calls": [
|
||||
[
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"entity": {
|
||||
"apiVersion": "backstage.io/v1alpha1",
|
||||
"kind": "Resource",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"backstage.io/managed-by-location": "gcp-gke:some-location",
|
||||
"backstage.io/managed-by-origin-location": "gcp-gke:some-location",
|
||||
"kubernetes.io/api-server": "https://127.0.0.1",
|
||||
"kubernetes.io/api-server-certificate-authority": "abcdefg",
|
||||
"kubernetes.io/auth-provider": "googleServiceAccount",
|
||||
"kubernetes.io/dashboard-app": "gke",
|
||||
"kubernetes.io/dashboard-parameters": "{"projectId":"parent1","region":"some-location","clusterName":"some-cluster"}",
|
||||
},
|
||||
"name": "some-cluster",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": {
|
||||
"owner": "sre",
|
||||
"type": "kubernetes-cluster",
|
||||
},
|
||||
},
|
||||
"locationKey": "gcp-gke:some-location",
|
||||
},
|
||||
],
|
||||
"type": "full",
|
||||
},
|
||||
],
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user