cleanup
This commit is contained in:
committed by
moustafab
parent
75d63ee0a0
commit
728767e3d3
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -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>;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,26 @@ It is only meant for local development, and the setup for it can be found inside
|
||||
|
||||
## Surfacing your Kubernetes components as part of an entity
|
||||
|
||||
There are 2 ways to surface your kubernetes components as part of an entity.
|
||||
There are two ways to surface your kubernetes components as part of an entity.
|
||||
The label selector takes precedence over the annotation/service id.
|
||||
|
||||
### Common `backstage.io/kubernetes-id` label
|
||||
### Full label selector
|
||||
|
||||
#### Adding the entity label selector to the spec
|
||||
|
||||
In order for Backstage to detect that an entity has kubernetes components the `kubernetes.selector` must have a valid selector. (Currently only matchLabels is supported)
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
kubernetes:
|
||||
selector:
|
||||
matchLabels:
|
||||
someKey: someValue
|
||||
other-key: other-value
|
||||
app.kubernetes.io/name: dice-roller
|
||||
```
|
||||
|
||||
### Common `backstage.io/kubernetes-id` label on objects
|
||||
|
||||
#### Adding the entity annotation
|
||||
|
||||
@@ -37,19 +53,3 @@ as a part of an entity, Kubernetes components must be labeled with the following
|
||||
```yaml
|
||||
'backstage.io/kubernetes-id': <ENTITY_NAME>
|
||||
```
|
||||
|
||||
### Full label selector
|
||||
|
||||
#### Adding the entity label selector to the spec
|
||||
|
||||
In order for Backstage to detect that an entity has kubernetes components the `kubernetes.selector` must have a valid selector. (Currently only matchLabels is supported)
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
kubernetes:
|
||||
selector:
|
||||
matchLabels:
|
||||
someKey: someValue
|
||||
other-key: other-value
|
||||
app.kubernetes.io/name: dice-roller
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user