add Azure as a Kubernetes auth provider (#11299)
* add azure auth provider Signed-off-by: Guilherme Oenning <goenning@eshopworld.com> * fix prettier-S Signed-off-by: Guilherme Oenning <goenning@eshopworld.com> * add aks dashboard formatter Signed-off-by: Guilherme Oenning <goenning@eshopworld.com> * ammend patch notes Signed-off-by: Guilherme Oenning <goenning@eshopworld.com> * typo Signed-off-by: Guilherme Oenning <goenning@eshopworld.com> * update enum to include azure Signed-off-by: goenning <me@goenning.net> * fix typo Signed-off-by: goenning <me@goenning.net> * add plugin to changeset Signed-off-by: goenning <me@goenning.net> Co-authored-by: Guilherme Oenning <goenning@eshopworld.com>
This commit is contained in:
committed by
GitHub
parent
ccfb9f972d
commit
1ef98cfe48
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { KubernetesAuthProvider } from './types';
|
||||
import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common';
|
||||
|
||||
export class AzureKubernetesAuthProvider implements KubernetesAuthProvider {
|
||||
async decorateRequestBodyForAuth(
|
||||
requestBody: KubernetesRequestBody,
|
||||
): Promise<KubernetesRequestBody> {
|
||||
// No-op, with azure auth, server's Azure credentials are used for access
|
||||
return requestBody;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import { ServiceAccountKubernetesAuthProvider } from './ServiceAccountKubernetes
|
||||
import { AwsKubernetesAuthProvider } from './AwsKubernetesAuthProvider';
|
||||
import { OAuthApi } from '@backstage/core-plugin-api';
|
||||
import { GoogleServiceAccountAuthProvider } from './GoogleServiceAccountAuthProvider';
|
||||
import { AzureKubernetesAuthProvider } from './AzureKubernetesAuthProvider';
|
||||
|
||||
export class KubernetesAuthProviders implements KubernetesAuthProvidersApi {
|
||||
private readonly kubernetesAuthProviderMap: Map<
|
||||
@@ -43,6 +44,10 @@ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi {
|
||||
new GoogleServiceAccountAuthProvider(),
|
||||
);
|
||||
this.kubernetesAuthProviderMap.set('aws', new AwsKubernetesAuthProvider());
|
||||
this.kubernetesAuthProviderMap.set(
|
||||
'azure',
|
||||
new AzureKubernetesAuthProvider(),
|
||||
);
|
||||
}
|
||||
|
||||
async decorateRequestBodyForAuth(
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
import { aksFormatter } from './aks';
|
||||
|
||||
describe('clusterLinks - AKS formatter', () => {
|
||||
it('should return an url on the workloads when there is a namespace only', () => {
|
||||
it('should provide a dashboardParameters in the options', () => {
|
||||
expect(() =>
|
||||
aksFormatter({
|
||||
dashboardUrl: new URL('https://k8s.foo.com'),
|
||||
object: {
|
||||
metadata: {
|
||||
name: 'foobar',
|
||||
@@ -28,6 +27,90 @@ describe('clusterLinks - AKS formatter', () => {
|
||||
},
|
||||
kind: 'Deployment',
|
||||
}),
|
||||
).toThrowError('AKS formatter is not yet implemented. Please, contribute!');
|
||||
).toThrowError('AKS dashboard requires a dashboardParameters option');
|
||||
});
|
||||
it('should provide a subscriptionId in the dashboardParameters options', () => {
|
||||
expect(() =>
|
||||
aksFormatter({
|
||||
dashboardParameters: {
|
||||
resourceGroup: 'rg-1',
|
||||
clusterName: 'cluster-1',
|
||||
},
|
||||
object: {
|
||||
metadata: {
|
||||
name: 'foobar',
|
||||
namespace: 'bar',
|
||||
},
|
||||
},
|
||||
kind: 'Deployment',
|
||||
}),
|
||||
).toThrowError(
|
||||
'AKS dashboard requires a "subscriptionId" of type string in the dashboardParameters option',
|
||||
);
|
||||
});
|
||||
it('should provide a resourceGroup in the dashboardParameters options', () => {
|
||||
expect(() =>
|
||||
aksFormatter({
|
||||
dashboardParameters: {
|
||||
subscriptionId: '1234-GUID-5678',
|
||||
clusterName: 'cluster-1',
|
||||
},
|
||||
object: {
|
||||
metadata: {
|
||||
name: 'foobar',
|
||||
namespace: 'bar',
|
||||
},
|
||||
},
|
||||
kind: 'Deployment',
|
||||
}),
|
||||
).toThrowError(
|
||||
'AKS dashboard requires a "resourceGroup" of type string in the dashboardParameters option',
|
||||
);
|
||||
});
|
||||
it('should provide a clusterName in the dashboardParameters options', () => {
|
||||
expect(() =>
|
||||
aksFormatter({
|
||||
dashboardParameters: {
|
||||
subscriptionId: '1234-GUID-5678',
|
||||
resourceGroup: 'us-east1-c',
|
||||
},
|
||||
object: {
|
||||
metadata: {
|
||||
name: 'foobar',
|
||||
namespace: 'bar',
|
||||
},
|
||||
},
|
||||
kind: 'Deployment',
|
||||
}),
|
||||
).toThrowError(
|
||||
'AKS dashboard requires a "clusterName" of type string in the dashboardParameters option',
|
||||
);
|
||||
});
|
||||
it('should return an url on the cluster with object details', () => {
|
||||
const url = aksFormatter({
|
||||
dashboardParameters: {
|
||||
subscriptionId: '1234-GUID-5678',
|
||||
resourceGroup: 'rg-1',
|
||||
clusterName: 'cluster-1',
|
||||
},
|
||||
object: {
|
||||
metadata: {
|
||||
name: 'my-deployment',
|
||||
namespace: 'my-namespace',
|
||||
uid: '111-GUID-222',
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: {
|
||||
app: 'foo',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kind: 'Deployment',
|
||||
});
|
||||
expect(url.href).toBe(
|
||||
'https://portal.azure.com/#blade/Microsoft_Azure_ContainerService/AksK8ResourceMenuBlade/overview-Deployment/aksClusterId/%2Fsubscriptions%2F1234-GUID-5678%2FresourceGroups%2Frg-1%2Fproviders%2FMicrosoft.ContainerService%2FmanagedClusters%2Fcluster-1/resource/%7B%22kind%22%3A%22Deployment%22%2C%22metadata%22%3A%7B%22name%22%3A%22my-deployment%22%2C%22namespace%22%3A%22my-namespace%22%2C%22uid%22%3A%22111-GUID-222%22%7D%2C%22spec%22%3A%7B%22selector%22%3A%7B%22matchLabels%22%3A%7B%22app%22%3A%22foo%22%7D%7D%7D%7D',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,39 @@
|
||||
*/
|
||||
import { ClusterLinksFormatterOptions } from '../../../types/types';
|
||||
|
||||
export function aksFormatter(_options: ClusterLinksFormatterOptions): URL {
|
||||
throw new Error('AKS formatter is not yet implemented. Please, contribute!');
|
||||
const basePath =
|
||||
'https://portal.azure.com/#blade/Microsoft_Azure_ContainerService/AksK8ResourceMenuBlade/overview-Deployment/aksClusterId';
|
||||
|
||||
const requiredParams = ['subscriptionId', 'resourceGroup', 'clusterName'];
|
||||
|
||||
export function aksFormatter(options: ClusterLinksFormatterOptions): URL {
|
||||
if (!options.dashboardParameters) {
|
||||
throw new Error('AKS dashboard requires a dashboardParameters option');
|
||||
}
|
||||
const args = options.dashboardParameters;
|
||||
for (const param of requiredParams) {
|
||||
if (typeof args[param] !== 'string') {
|
||||
throw new Error(
|
||||
`AKS dashboard requires a "${param}" of type string in the dashboardParameters option`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const path = `/subscriptions/${args.subscriptionId}/resourceGroups/${args.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${args.clusterName}`;
|
||||
|
||||
const { name, namespace, uid } = options.object.metadata;
|
||||
const { selector } = options.object.spec;
|
||||
const params = {
|
||||
kind: options.kind,
|
||||
metadata: { name, namespace, uid },
|
||||
spec: {
|
||||
selector,
|
||||
},
|
||||
};
|
||||
|
||||
return new URL(
|
||||
`${basePath}/${encodeURIComponent(path)}/resource/${encodeURIComponent(
|
||||
JSON.stringify(params),
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user