diff --git a/.changeset/twenty-chairs-argue.md b/.changeset/twenty-chairs-argue.md new file mode 100644 index 0000000000000..c4a0acedbef8a --- /dev/null +++ b/.changeset/twenty-chairs-argue.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes': patch +--- + +Add dashboard support for Rancher diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts index 754647d5e92de..877a9afdfb820 100644 --- a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts +++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts @@ -15,21 +15,88 @@ */ import { rancherFormatter } from './rancher'; -describe('clusterLinks - Rancher formatter', () => { - it('should return an url on the workloads when there is a namespace only', () => { - expect(() => - rancherFormatter({ - dashboardUrl: new URL('https://k8s.foo.com'), - object: { - metadata: { - name: 'foobar', - namespace: 'bar', - }, +describe('clusterLinks - rancher formatter', () => { + it('should return a url on the workloads when there is a namespace only', () => { + const url = rancherFormatter({ + dashboardUrl: new URL('https://k8s.foo.com'), + object: { + metadata: { + namespace: 'bar', }, - kind: 'Deployment', - }), - ).toThrowError( - 'Rancher formatter is not yet implemented. Please, contribute!', + }, + kind: 'foo', + }); + expect(url.href).toBe('https://k8s.foo.com/explorer/workload'); + }); + it('should return a url on the workloads when the kind is not recognized', () => { + const url = rancherFormatter({ + dashboardUrl: new URL('https://k8s.foo.com'), + object: { + metadata: { + name: 'foobar', + namespace: 'bar', + }, + }, + kind: 'UnknownKind', + }); + expect(url.href).toBe('https://k8s.foo.com/explorer/workload'); + }); + it('should return a url on the deployment', () => { + const url = rancherFormatter({ + dashboardUrl: new URL('https://k8s.foo.com/'), + object: { + metadata: { + name: 'foobar', + namespace: 'bar', + }, + }, + kind: 'Deployment', + }); + expect(url.href).toBe( + 'https://k8s.foo.com/explorer/apps.deployment/bar/foobar', + ); + }); + it('should return a url on the service', () => { + const url = rancherFormatter({ + dashboardUrl: new URL('https://k8s.foo.com/'), + object: { + metadata: { + name: 'foobar', + namespace: 'bar', + }, + }, + kind: 'Service', + }); + expect(url.href).toBe('https://k8s.foo.com/explorer/service/bar/foobar'); + }); + it('should return a url on the ingress', () => { + const url = rancherFormatter({ + dashboardUrl: new URL('https://k8s.foo.com/'), + object: { + metadata: { + name: 'foobar', + namespace: 'bar', + }, + }, + kind: 'Ingress', + }); + expect(url.href).toBe( + 'https://k8s.foo.com/explorer/networking.k8s.io.ingress/bar/foobar', + ); + }); + it('should return a url on the deployment for a hpa', () => { + const url = rancherFormatter({ + dashboardUrl: new URL('https://k8s.foo.com/'), + object: { + metadata: { + name: 'foobar', + namespace: 'bar', + }, + }, + kind: 'HorizontalPodAutoscaler', + }); + expect(url.href).toBe( + 'https://k8s.foo.com/explorer/autoscaling.horizontalpodautoscaler/bar/foobar', ); }); }); diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts index 491ca032a95ee..0796d78c77c97 100644 --- a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts +++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts @@ -15,8 +15,22 @@ */ import { ClusterLinksFormatterOptions } from '../../../types/types'; -export function rancherFormatter(_options: ClusterLinksFormatterOptions): URL { - throw new Error( - 'Rancher formatter is not yet implemented. Please, contribute!', - ); +const kindMappings: Record = { + deployment: 'apps.deployment', + ingress: 'networking.k8s.io.ingress', + service: 'service', + horizontalpodautoscaler: 'autoscaling.horizontalpodautoscaler', +}; + +export function rancherFormatter(options: ClusterLinksFormatterOptions): URL { + const result = new URL(options.dashboardUrl.href); + const name = options.object.metadata?.name; + const namespace = options.object.metadata?.namespace; + const validKind = kindMappings[options.kind.toLocaleLowerCase('en-US')]; + if (validKind && name && namespace) { + result.pathname = `explorer/${validKind}/${namespace}/${name}`; + } else if (namespace) { + result.pathname = 'explorer/workload'; + } + return result; }