This commit is contained in:
Moustafa Baiou
2020-11-09 14:00:13 -05:00
committed by moustafab
parent 75d63ee0a0
commit 728767e3d3
6 changed files with 71 additions and 71 deletions
@@ -16,6 +16,7 @@
import { getVoidLogger } from '@backstage/backend-common';
import { KubernetesClientBasedFetcher } from './KubernetesFetcher';
import { ObjectFetchParams } from '..';
describe('KubernetesClientProvider', () => {
let clientMock: any;
@@ -57,17 +58,17 @@ describe('KubernetesClientProvider', () => {
clientMock.listServiceForAllNamespaces.mockRejectedValue(errorResponse);
const result = await sut.fetchObjectsForService(
'some-service',
{
const result = await sut.fetchObjectsForService(<ObjectFetchParams>{
serviceId: 'some-service',
clusterDetails: {
name: 'cluster1',
url: 'http://localhost:9999',
serviceAccountToken: 'token',
authProvider: 'serviceAccount',
},
new Set(['pods', 'services']),
'',
);
objectTypesToFetch: new Set(['pods', 'services']),
labelSelector: '',
});
expect(result).toStrictEqual({
errors: [expectedResult],
@@ -121,17 +122,17 @@ describe('KubernetesClientProvider', () => {
},
});
const result = await sut.fetchObjectsForService(
'some-service',
{
const result = await sut.fetchObjectsForService(<ObjectFetchParams>{
serviceId: 'some-service',
clusterDetails: {
name: 'cluster1',
url: 'http://localhost:9999',
serviceAccountToken: 'token',
authProvider: 'serviceAccount',
},
new Set(['pods', 'services']),
'',
);
objectTypesToFetch: new Set(['pods', 'services']),
labelSelector: '',
});
expect(result).toStrictEqual({
errors: [],
@@ -171,17 +172,17 @@ describe('KubernetesClientProvider', () => {
});
it('should throw error on unknown type', () => {
expect(() =>
sut.fetchObjectsForService(
'some-service',
{
sut.fetchObjectsForService(<ObjectFetchParams>{
serviceId: 'some-service',
clusterDetails: {
name: 'cluster1',
url: 'http://localhost:9999',
serviceAccountToken: 'token',
authProvider: 'serviceAccount',
},
new Set<any>(['foo']),
'',
),
objectTypesToFetch: new Set<any>(['foo']),
labelSelector: '',
}),
).toThrow('unrecognised type=foo');
expect(clientMock.listPodForAllNamespaces.mock.calls.length).toBe(0);
@@ -282,17 +283,17 @@ describe('KubernetesClientProvider', () => {
},
});
await sut.fetchObjectsForService(
'some-service',
{
await sut.fetchObjectsForService(<ObjectFetchParams>{
serviceId: 'some-service',
clusterDetails: {
name: 'cluster1',
url: 'http://localhost:9999',
serviceAccountToken: 'token',
authProvider: 'serviceAccount',
},
new Set(['pods', 'services']),
'',
);
objectTypesToFetch: new Set(['pods', 'services']),
labelSelector: '',
});
const mockCall = clientMock.listPodForAllNamespaces.mock.calls[0];
const actualSelector = mockCall[mockCall.length - 1];
@@ -38,6 +38,7 @@ import {
FetchResponseWrapper,
KubernetesFetchError,
KubernetesErrorTypes,
ObjectFetchParams,
} from '..';
import lodash, { Dictionary } from 'lodash';
@@ -106,18 +107,14 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
}
fetchObjectsForService(
serviceId: string,
clusterDetails: ClusterDetails,
objectTypesToFetch: Set<KubernetesObjectTypes>,
labelSelector: string,
params: ObjectFetchParams,
): Promise<FetchResponseWrapper> {
const fetchResults = Array.from(objectTypesToFetch).map(type => {
const fetchResults = Array.from(params.objectTypesToFetch).map(type => {
return this.fetchByObjectType(
clusterDetails,
params.clusterDetails,
type,
labelSelector.length !== 0
? labelSelector
: `backstage.io/kubernetes-id=${serviceId}`,
params.labelSelector ||
`backstage.io/kubernetes-id=${params.serviceId}`,
).catch(captureKubernetesErrorsRethrowOthers);
});
@@ -25,7 +25,7 @@ const fetchObjectsForService = jest.fn();
const getClustersByServiceId = jest.fn();
const goodEntity: ComponentEntityV1alpha1 = <ComponentEntityV1alpha1>{
const goodEntity: ComponentEntityV1alpha1 = {
apiVersion: 'backstage.io/v1beta1',
kind: 'Component',
metadata: {
@@ -15,6 +15,7 @@
*/
import { Logger } from 'winston';
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
import {
KubernetesRequestBody,
ClusterDetails,
@@ -22,10 +23,10 @@ import {
KubernetesFetcher,
KubernetesObjectTypes,
ObjectsByEntityResponse,
ObjectFetchParams,
} from '../types/types';
import { KubernetesAuthTranslator } from '../kubernetes-auth-translator/types';
import { KubernetesAuthTranslatorGenerator } from '../kubernetes-auth-translator/KubernetesAuthTranslatorGenerator';
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
export type GetKubernetesObjectsForServiceHandler = (
serviceId: string,
@@ -47,18 +48,10 @@ const DEFAULT_OBJECTS = new Set<KubernetesObjectTypes>([
]);
function parseLabelSelector(entity: ComponentEntityV1alpha1): string {
if (
entity &&
entity.spec &&
entity.spec.kubernetes &&
entity.spec.kubernetes.selector
) {
const matchLabels = entity?.spec?.kubernetes?.selector?.matchLabels;
if (matchLabels) {
// TODO: figure out how to convert the selector to the full query param from the yaml
// (as shown here https://github.com/kubernetes/apimachinery/blob/master/pkg/labels/selector.go)
const { matchLabels } = entity.spec.kubernetes.selector;
if (!matchLabels) {
return '';
}
return Object.keys(matchLabels)
.map(key => `${key}=${matchLabels[key.toString()]}`)
.join(',');
@@ -73,7 +66,7 @@ export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServic
serviceLocator,
logger,
requestBody,
objectsToFetch = DEFAULT_OBJECTS,
objectTypesToFetch = DEFAULT_OBJECTS,
) => {
const clusterDetails: ClusterDetails[] = await serviceLocator.getClustersByServiceId(
serviceId,
@@ -102,13 +95,18 @@ export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServic
const labelSelector = parseLabelSelector(requestBody.entity);
return Promise.all(
clusterDetailsDecoratedForAuth.map(cd => {
clusterDetailsDecoratedForAuth.map(clusterDetails => {
return fetcher
.fetchObjectsForService(serviceId, cd, objectsToFetch, labelSelector)
.fetchObjectsForService(<ObjectFetchParams>{
serviceId,
clusterDetails,
objectTypesToFetch,
labelSelector,
})
.then(result => {
return {
cluster: {
name: cd.name,
name: clusterDetails.name,
},
resources: result.responses,
errors: result.errors,
@@ -109,14 +109,18 @@ export interface IngressesFetchResponse {
resources: Array<ExtensionsV1beta1Ingress>;
}
export interface ObjectFetchParams {
serviceId: string;
clusterDetails: ClusterDetails;
objectTypesToFetch: Set<KubernetesObjectTypes>;
labelSelector: string;
}
// Fetches information from a kubernetes cluster using the cluster details object
// to target a specific cluster
export interface KubernetesFetcher {
fetchObjectsForService(
serviceId: string,
clusterDetails: ClusterDetails,
objectTypesToFetch: Set<KubernetesObjectTypes>,
labelSelector: string,
params: ObjectFetchParams,
): Promise<FetchResponseWrapper>;
}