@backstage/plugin-kubernetes 0.6.5-next.1 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # @backstage/plugin-kubernetes
2
2
 
3
+ ## 0.6.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 1ef98cfe48: add Azure Identity auth provider and AKS dashboard formatter
8
+ - 447e060872: Add support for 'oidc' as authProvider for kubernetes authentication
9
+ and adds optional 'oidcTokenProvider' config value. This will allow
10
+ users to authenticate to kubernetes cluster using id tokens obtained
11
+ from the configured auth provider in their backstage instance.
12
+ - Updated dependencies
13
+ - @backstage/core-components@0.9.4
14
+ - @backstage/plugin-kubernetes-common@0.2.10
15
+ - @backstage/core-plugin-api@1.0.2
16
+ - @backstage/plugin-catalog-react@1.1.0
17
+ - @backstage/config@1.0.1
18
+ - @backstage/catalog-model@1.0.2
19
+
20
+ ## 0.6.5-next.3
21
+
22
+ ### Patch Changes
23
+
24
+ - 447e060872: Add support for 'oidc' as authProvider for kubernetes authentication
25
+ and adds optional 'oidcTokenProvider' config value. This will allow
26
+ users to authenticate to kubernetes cluster using id tokens obtained
27
+ from the configured auth provider in their backstage instance.
28
+ - Updated dependencies
29
+ - @backstage/plugin-kubernetes-common@0.2.10-next.1
30
+ - @backstage/core-components@0.9.4-next.2
31
+
32
+ ## 0.6.5-next.2
33
+
34
+ ### Patch Changes
35
+
36
+ - 1ef98cfe48: add Azure Identity auth provider and AKS dashboard formatter
37
+ - Updated dependencies
38
+ - @backstage/core-components@0.9.4-next.1
39
+ - @backstage/plugin-kubernetes-common@0.2.10-next.0
40
+ - @backstage/config@1.0.1-next.0
41
+ - @backstage/plugin-catalog-react@1.1.0-next.2
42
+ - @backstage/catalog-model@1.0.2-next.0
43
+ - @backstage/core-plugin-api@1.0.2-next.1
44
+
3
45
  ## 0.6.5-next.1
4
46
 
5
47
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
- import { DiscoveryApi, IdentityApi, OAuthApi } from '@backstage/core-plugin-api';
3
+ import { DiscoveryApi, IdentityApi, OAuthApi, OpenIdConnectApi } from '@backstage/core-plugin-api';
4
4
  import { Entity } from '@backstage/catalog-model';
5
5
  import { KubernetesRequestBody, ObjectsByEntityResponse, ClusterObjects, ClientPodStatus, ClusterAttributes } from '@backstage/plugin-kubernetes-common';
6
6
  import { JsonObject } from '@backstage/types';
@@ -22,6 +22,7 @@ interface KubernetesApi {
22
22
  getClusters(): Promise<{
23
23
  name: string;
24
24
  authProvider: string;
25
+ oidcTokenProvider?: string | undefined;
25
26
  }[]>;
26
27
  }
27
28
 
@@ -53,6 +54,9 @@ declare class KubernetesAuthProviders implements KubernetesAuthProvidersApi {
53
54
  private readonly kubernetesAuthProviderMap;
54
55
  constructor(options: {
55
56
  googleAuthApi: OAuthApi;
57
+ oidcProviders?: {
58
+ [key: string]: OpenIdConnectApi;
59
+ };
56
60
  });
57
61
  decorateRequestBodyForAuth(authProvider: string, requestBody: KubernetesRequestBody): Promise<KubernetesRequestBody>;
58
62
  }
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, googleAuthApiRef, createRoutableExtension, useApi } from '@backstage/core-plugin-api';
1
+ import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, googleAuthApiRef, microsoftAuthApiRef, oktaAuthApiRef, oneloginAuthApiRef, createRoutableExtension, useApi } from '@backstage/core-plugin-api';
2
2
  import * as React from 'react';
3
3
  import React__default, { Fragment, useState, useEffect, useContext } from 'react';
4
4
  import { useEntity } from '@backstage/plugin-catalog-react';
@@ -108,6 +108,30 @@ class GoogleServiceAccountAuthProvider {
108
108
  }
109
109
  }
110
110
 
111
+ class AzureKubernetesAuthProvider {
112
+ async decorateRequestBodyForAuth(requestBody) {
113
+ return requestBody;
114
+ }
115
+ }
116
+
117
+ class OidcKubernetesAuthProvider {
118
+ constructor(providerName, authProvider) {
119
+ this.providerName = providerName;
120
+ this.authProvider = authProvider;
121
+ }
122
+ async decorateRequestBodyForAuth(requestBody) {
123
+ const authToken = await this.authProvider.getIdToken();
124
+ const auth = { ...requestBody.auth };
125
+ if (auth.oidc) {
126
+ auth.oidc[this.providerName] = authToken;
127
+ } else {
128
+ auth.oidc = { [this.providerName]: authToken };
129
+ }
130
+ requestBody.auth = auth;
131
+ return requestBody;
132
+ }
133
+ }
134
+
111
135
  class KubernetesAuthProviders {
112
136
  constructor(options) {
113
137
  this.kubernetesAuthProviderMap = /* @__PURE__ */ new Map();
@@ -115,12 +139,21 @@ class KubernetesAuthProviders {
115
139
  this.kubernetesAuthProviderMap.set("serviceAccount", new ServiceAccountKubernetesAuthProvider());
116
140
  this.kubernetesAuthProviderMap.set("googleServiceAccount", new GoogleServiceAccountAuthProvider());
117
141
  this.kubernetesAuthProviderMap.set("aws", new AwsKubernetesAuthProvider());
142
+ this.kubernetesAuthProviderMap.set("azure", new AzureKubernetesAuthProvider());
143
+ if (options.oidcProviders) {
144
+ Object.keys(options.oidcProviders).forEach((provider) => {
145
+ this.kubernetesAuthProviderMap.set(`oidc.${provider}`, new OidcKubernetesAuthProvider(provider, options.oidcProviders[provider]));
146
+ });
147
+ }
118
148
  }
119
149
  async decorateRequestBodyForAuth(authProvider, requestBody) {
120
150
  const kubernetesAuthProvider = this.kubernetesAuthProviderMap.get(authProvider);
121
151
  if (kubernetesAuthProvider) {
122
152
  return await kubernetesAuthProvider.decorateRequestBodyForAuth(requestBody);
123
153
  }
154
+ if (authProvider.startsWith("oidc.")) {
155
+ throw new Error(`KubernetesAuthProviders has no oidcProvider configured for ${authProvider}`);
156
+ }
124
157
  throw new Error(`authProvider "${authProvider}" has no KubernetesAuthProvider defined for it`);
125
158
  }
126
159
  }
@@ -141,9 +174,25 @@ const kubernetesPlugin = createPlugin({
141
174
  }),
142
175
  createApiFactory({
143
176
  api: kubernetesAuthProvidersApiRef,
144
- deps: { googleAuthApi: googleAuthApiRef },
145
- factory: ({ googleAuthApi }) => {
146
- return new KubernetesAuthProviders({ googleAuthApi });
177
+ deps: {
178
+ googleAuthApi: googleAuthApiRef,
179
+ microsoftAuthApi: microsoftAuthApiRef,
180
+ oktaAuthApi: oktaAuthApiRef,
181
+ oneloginAuthApi: oneloginAuthApiRef
182
+ },
183
+ factory: ({
184
+ googleAuthApi,
185
+ microsoftAuthApi,
186
+ oktaAuthApi,
187
+ oneloginAuthApi
188
+ }) => {
189
+ const oidcProviders = {
190
+ google: googleAuthApi,
191
+ microsoft: microsoftAuthApi,
192
+ okta: oktaAuthApi,
193
+ onelogin: oneloginAuthApi
194
+ };
195
+ return new KubernetesAuthProviders({ googleAuthApi, oidcProviders });
147
196
  }
148
197
  })
149
198
  ],
@@ -582,7 +631,7 @@ const useKubernetesObjects = (entity, intervalMs = 1e4) => {
582
631
  return;
583
632
  }
584
633
  const authProviders = [
585
- ...new Set(clusters.map((c) => c.authProvider))
634
+ ...new Set(clusters.map((c) => `${c.authProvider}${c.oidcTokenProvider ? `.${c.oidcTokenProvider}` : ""}`))
586
635
  ];
587
636
  let requestBody = {
588
637
  entity
@@ -727,8 +776,29 @@ function openshiftFormatter(options) {
727
776
  return new URL(path, basePath);
728
777
  }
729
778
 
730
- function aksFormatter(_options) {
731
- throw new Error("AKS formatter is not yet implemented. Please, contribute!");
779
+ const basePath = "https://portal.azure.com/#blade/Microsoft_Azure_ContainerService/AksK8ResourceMenuBlade/overview-Deployment/aksClusterId";
780
+ const requiredParams = ["subscriptionId", "resourceGroup", "clusterName"];
781
+ function aksFormatter(options) {
782
+ if (!options.dashboardParameters) {
783
+ throw new Error("AKS dashboard requires a dashboardParameters option");
784
+ }
785
+ const args = options.dashboardParameters;
786
+ for (const param of requiredParams) {
787
+ if (typeof args[param] !== "string") {
788
+ throw new Error(`AKS dashboard requires a "${param}" of type string in the dashboardParameters option`);
789
+ }
790
+ }
791
+ const path = `/subscriptions/${args.subscriptionId}/resourceGroups/${args.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${args.clusterName}`;
792
+ const { name, namespace, uid } = options.object.metadata;
793
+ const { selector } = options.object.spec;
794
+ const params = {
795
+ kind: options.kind,
796
+ metadata: { name, namespace, uid },
797
+ spec: {
798
+ selector
799
+ }
800
+ };
801
+ return new URL(`${basePath}/${encodeURIComponent(path)}/resource/${encodeURIComponent(JSON.stringify(params))}`);
732
802
  }
733
803
 
734
804
  function eksFormatter(_options) {