Don't list the cluster if there are no resources deployed there

Signed-off-by: nliesenfeld <nliesenfeld@spotify.com>
This commit is contained in:
nliesenfeld
2021-03-11 18:21:28 -05:00
parent e07b41751e
commit bb848ac5e8
3 changed files with 422 additions and 42 deletions
@@ -24,43 +24,93 @@ const getClustersByServiceId = jest.fn();
const mockFetch = (mock: jest.Mock) => {
mock.mockImplementation((params: ObjectFetchParams) =>
Promise.resolve({
Promise.resolve(
generateMockResourcesAndErrors(
params.serviceId,
params.clusterDetails.name,
),
),
);
};
function generateMockResourcesAndErrors(
serviceId: String,
clusterName: String,
) {
if (clusterName === 'empty-cluster') {
return {
errors: [],
responses: [
{
type: 'pods',
resources: [
{
metadata: {
name: `my-pods-${params.serviceId}-${params.clusterDetails.name}`,
},
},
],
resources: [],
},
{
type: 'configmaps',
resources: [
{
metadata: {
name: `my-configmaps-${params.serviceId}-${params.clusterDetails.name}`,
},
},
],
resources: [],
},
{
type: 'services',
resources: [
{
metadata: {
name: `my-services-${params.serviceId}-${params.clusterDetails.name}`,
},
},
],
resources: [],
},
],
}),
);
};
};
} else if (clusterName === 'error-cluster') {
return {
errors: ['some random cluster error'],
responses: [
{
type: 'pods',
resources: [],
},
{
type: 'configmaps',
resources: [],
},
{
type: 'services',
resources: [],
},
],
};
}
return {
errors: [],
responses: [
{
type: 'pods',
resources: [
{
metadata: {
name: `my-pods-${serviceId}-${clusterName}`,
},
},
],
},
{
type: 'configmaps',
resources: [
{
metadata: {
name: `my-configmaps-${serviceId}-${clusterName}`,
},
},
],
},
{
type: 'services',
resources: [
{
metadata: {
name: `my-services-${serviceId}-${clusterName}`,
},
},
],
},
],
};
}
describe('handleGetKubernetesObjectsForService', () => {
beforeEach(() => {
@@ -287,4 +337,300 @@ describe('handleGetKubernetesObjectsForService', () => {
],
});
});
it('retrieve objects for three clusters, only two have resources and show in ui', async () => {
getClustersByServiceId.mockImplementation(() =>
Promise.resolve([
{
name: 'test-cluster',
authProvider: 'serviceAccount',
},
{
name: 'other-cluster',
authProvider: 'google',
},
{
name: 'empty-cluster',
authProvider: 'google',
},
]),
);
mockFetch(fetchObjectsForService);
const sut = new KubernetesFanOutHandler(
getVoidLogger(),
{
fetchObjectsForService,
},
{
getClustersByServiceId,
},
[],
);
const result = await sut.getKubernetesObjectsByEntity({
auth: {
google: 'google_token_123',
},
entity: {
apiVersion: 'backstage.io/v1beta1',
kind: 'Component',
metadata: {
name: 'test-component',
annotations: {
'backstage.io/kubernetes-labels-selector':
'backstage.io/test-label=test-component',
},
},
spec: {
type: 'service',
lifecycle: 'production',
owner: 'joe',
},
},
});
expect(getClustersByServiceId.mock.calls.length).toBe(1);
expect(fetchObjectsForService.mock.calls.length).toBe(3);
expect(result).toStrictEqual({
items: [
{
cluster: {
name: 'test-cluster',
},
errors: [],
resources: [
{
resources: [
{
metadata: {
name: 'my-pods-test-component-test-cluster',
},
},
],
type: 'pods',
},
{
resources: [
{
metadata: {
name: 'my-configmaps-test-component-test-cluster',
},
},
],
type: 'configmaps',
},
{
resources: [
{
metadata: {
name: 'my-services-test-component-test-cluster',
},
},
],
type: 'services',
},
],
},
{
cluster: {
name: 'other-cluster',
},
errors: [],
resources: [
{
resources: [
{
metadata: {
name: 'my-pods-test-component-other-cluster',
},
},
],
type: 'pods',
},
{
resources: [
{
metadata: {
name: 'my-configmaps-test-component-other-cluster',
},
},
],
type: 'configmaps',
},
{
resources: [
{
metadata: {
name: 'my-services-test-component-other-cluster',
},
},
],
type: 'services',
},
],
},
],
});
});
it('retrieve objects for four clusters, two have resources and one error cluster', async () => {
getClustersByServiceId.mockImplementation(() =>
Promise.resolve([
{
name: 'test-cluster',
authProvider: 'serviceAccount',
},
{
name: 'other-cluster',
authProvider: 'google',
},
{
name: 'empty-cluster',
authProvider: 'google',
},
{
name: 'error-cluster',
authProvider: 'google',
},
]),
);
mockFetch(fetchObjectsForService);
const sut = new KubernetesFanOutHandler(
getVoidLogger(),
{
fetchObjectsForService,
},
{
getClustersByServiceId,
},
[],
);
const result = await sut.getKubernetesObjectsByEntity({
auth: {
google: 'google_token_123',
},
entity: {
apiVersion: 'backstage.io/v1beta1',
kind: 'Component',
metadata: {
name: 'test-component',
annotations: {
'backstage.io/kubernetes-labels-selector':
'backstage.io/test-label=test-component',
},
},
spec: {
type: 'service',
lifecycle: 'production',
owner: 'joe',
},
},
});
expect(getClustersByServiceId.mock.calls.length).toBe(1);
expect(fetchObjectsForService.mock.calls.length).toBe(4);
expect(result).toStrictEqual({
items: [
{
cluster: {
name: 'test-cluster',
},
errors: [],
resources: [
{
resources: [
{
metadata: {
name: 'my-pods-test-component-test-cluster',
},
},
],
type: 'pods',
},
{
resources: [
{
metadata: {
name: 'my-configmaps-test-component-test-cluster',
},
},
],
type: 'configmaps',
},
{
resources: [
{
metadata: {
name: 'my-services-test-component-test-cluster',
},
},
],
type: 'services',
},
],
},
{
cluster: {
name: 'other-cluster',
},
errors: [],
resources: [
{
resources: [
{
metadata: {
name: 'my-pods-test-component-other-cluster',
},
},
],
type: 'pods',
},
{
resources: [
{
metadata: {
name: 'my-configmaps-test-component-other-cluster',
},
},
],
type: 'configmaps',
},
{
resources: [
{
metadata: {
name: 'my-services-test-component-other-cluster',
},
},
],
type: 'services',
},
],
},
{
cluster: {
name: 'error-cluster',
},
errors: ['some random cluster error'],
resources: [
{
type: 'pods',
resources: [],
},
{
type: 'configmaps',
resources: [],
},
{
type: 'services',
resources: [],
},
],
},
],
});
});
});
@@ -109,6 +109,14 @@ export class KubernetesFanOutHandler {
};
});
}),
).then(r => ({ items: r }));
).then(r => ({
items: r.filter(
item =>
(item.errors !== undefined && item.errors.length >= 1) ||
(item.resources !== undefined &&
item.resources.length >= 1 &&
item.resources.some(fr => fr.resources.length >= 1)),
),
}));
}
}