Merge pull request #10765 from mclarke47/k8s-namespaced-lookup

add kubernetes namespace annotation
This commit is contained in:
Ben Lambert
2022-04-13 22:06:11 +02:00
committed by GitHub
7 changed files with 99 additions and 3 deletions
+2
View File
@@ -245,6 +245,8 @@ export interface ObjectFetchParams {
// (undocumented)
labelSelector: string;
// (undocumented)
namespace?: string;
// (undocumented)
objectTypesToFetch: Set<ObjectToFetch>;
// (undocumented)
serviceId: string;
@@ -207,6 +207,11 @@ export class KubernetesFanOutHandler {
'backstage.io/kubernetes-label-selector'
] || `backstage.io/kubernetes-id=${entityName}`;
const namespace =
requestBody.entity?.metadata?.annotations?.[
'backstage.io/kubernetes-namespace'
];
return Promise.all(
clusterDetailsDecoratedForAuth.map(clusterDetailsItem => {
return this.fetcher
@@ -216,19 +221,26 @@ export class KubernetesFanOutHandler {
objectTypesToFetch: this.objectTypesToFetch,
labelSelector,
customResources: this.customResources,
namespace,
})
.then(result => this.getMetricsForPods(clusterDetailsItem, result))
.then(r => this.toClusterObjects(clusterDetailsItem, r));
}),
).then(r => ({
items: r.filter(
).then(this.toObjectsByEntityResponse);
}
toObjectsByEntityResponse(
clusterObjects: ClusterObjects[],
): ObjectsByEntityResponse {
return {
items: clusterObjects.filter(
item =>
(item.errors !== undefined && item.errors.length >= 1) ||
(item.resources !== undefined &&
item.resources.length >= 1 &&
item.resources.some(fr => fr.resources.length >= 1)),
),
}));
};
}
toClusterObjects(
@@ -42,6 +42,7 @@ describe('KubernetesFetcher', () => {
jest.resetAllMocks();
clientMock = {
listClusterCustomObject: jest.fn(),
listNamespacedCustomObject: jest.fn(),
addInterceptor: jest.fn(),
};
@@ -479,4 +480,47 @@ describe('KubernetesFetcher', () => {
const expectedSelector = 'backstage.io/kubernetes-id=some-service';
expect(actualSelector).toBe(expectedSelector);
});
it('should use namespace if provided', async () => {
clientMock.listNamespacedCustomObject.mockResolvedValueOnce({
body: {
items: [
{
metadata: {
name: 'pod-name',
},
},
],
},
});
clientMock.listNamespacedCustomObject.mockResolvedValueOnce({
body: {
items: [
{
metadata: {
name: 'service-name',
},
},
],
},
});
await sut.fetchObjectsForService({
serviceId: 'some-service',
clusterDetails: {
name: 'cluster1',
url: 'http://localhost:9999',
serviceAccountToken: 'token',
authProvider: 'serviceAccount',
},
objectTypesToFetch: OBJECTS_TO_FETCH,
labelSelector: '',
namespace: 'some-namespace',
customResources: [],
});
const mockCall = clientMock.listNamespacedCustomObject.mock.calls[0];
const namespace = mockCall[2];
expect(namespace).toBe('some-namespace');
});
});
@@ -97,6 +97,7 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
params.labelSelector ||
`backstage.io/kubernetes-id=${params.serviceId}`,
toFetch.objectType,
params.namespace,
).catch(this.captureKubernetesErrorsRethrowOthers.bind(this));
});
@@ -138,6 +139,7 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
resource: ObjectToFetch,
labelSelector: string,
objectType: KubernetesObjectTypes,
namespace?: string,
): Promise<FetchResponse> {
const customObjects =
this.kubernetesClientProvider.getCustomObjectsClient(clusterDetails);
@@ -146,6 +148,26 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
requestOptions.uri = requestOptions.uri.replace('/apis//v1/', '/api/v1/');
});
if (namespace) {
return customObjects
.listNamespacedCustomObject(
resource.group,
resource.apiVersion,
namespace,
resource.plural,
'',
false,
'',
'',
labelSelector,
)
.then(r => {
return {
type: objectType,
resources: (r.body as any).items,
};
});
}
return customObjects
.listClusterCustomObject(
resource.group,
@@ -34,6 +34,7 @@ export interface ObjectFetchParams {
objectTypesToFetch: Set<ObjectToFetch>;
labelSelector: string;
customResources: CustomResource[];
namespace?: string;
}
// Fetches information from a kubernetes cluster using the cluster details object