@backstage/plugin-kubernetes-backend 0.17.0-next.1 → 0.17.1-next.0

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,54 @@
1
1
  # @backstage/plugin-kubernetes-backend
2
2
 
3
+ ## 0.17.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/catalog-model@1.5.0-next.0
9
+ - @backstage/plugin-auth-node@0.4.13-next.0
10
+ - @backstage/backend-common@0.21.8-next.0
11
+ - @backstage/backend-plugin-api@0.6.18-next.0
12
+ - @backstage/plugin-kubernetes-node@0.1.12-next.0
13
+ - @backstage/catalog-client@1.6.5-next.0
14
+ - @backstage/plugin-catalog-node@1.11.2-next.0
15
+ - @backstage/plugin-kubernetes-common@0.7.6-next.0
16
+ - @backstage/config@1.2.0
17
+ - @backstage/errors@1.2.4
18
+ - @backstage/integration-aws-node@0.1.12
19
+ - @backstage/types@1.1.1
20
+ - @backstage/plugin-permission-common@0.7.13
21
+ - @backstage/plugin-permission-node@0.7.29-next.0
22
+
23
+ ## 0.17.0
24
+
25
+ ### Minor Changes
26
+
27
+ - 6c19c14: **BREAKING**: `KubernetesProxy` now requires the `DiscoveryService` to be passed to the constuctor
28
+ - 5dd8177: **BREAKING** Winston logger has been replaced with `LoggerService`
29
+
30
+ ### Patch Changes
31
+
32
+ - f5cec55: Fixing issue where `BackstageCredentials` were not properly forwarded for all calls
33
+ - dd269e9: Fixed a bug where the proxy handler did not properly handle a missing header
34
+ - 9d89aed: Fixed a crash reading `credentials` from `undefined`.
35
+ - e5a2ccc: Updated dependency `@types/http-proxy-middleware` to `^1.0.0`.
36
+ - Updated dependencies
37
+ - @backstage/plugin-kubernetes-node@0.1.11
38
+ - @backstage/backend-common@0.21.7
39
+ - @backstage/plugin-permission-node@0.7.28
40
+ - @backstage/backend-plugin-api@0.6.17
41
+ - @backstage/plugin-auth-node@0.4.12
42
+ - @backstage/catalog-client@1.6.4
43
+ - @backstage/integration-aws-node@0.1.12
44
+ - @backstage/plugin-catalog-node@1.11.1
45
+ - @backstage/catalog-model@1.4.5
46
+ - @backstage/config@1.2.0
47
+ - @backstage/errors@1.2.4
48
+ - @backstage/types@1.1.1
49
+ - @backstage/plugin-kubernetes-common@0.7.5
50
+ - @backstage/plugin-permission-common@0.7.13
51
+
3
52
  ## 0.17.0-next.1
4
53
 
5
54
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-kubernetes-backend",
3
- "version": "0.17.0-next.1",
3
+ "version": "0.17.1-next.0",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/alpha.cjs.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var backendCommon = require('@backstage/backend-common');
6
5
  var backendPluginApi = require('@backstage/backend-plugin-api');
7
6
  var alpha = require('@backstage/plugin-catalog-node/alpha');
8
7
  var pluginKubernetesBackend = require('@backstage/plugin-kubernetes-backend');
@@ -142,9 +141,8 @@ const kubernetesPlugin = backendPluginApi.createBackendPlugin({
142
141
  auth,
143
142
  httpAuth
144
143
  }) {
145
- const winstonLogger = backendCommon.loggerToWinstonLogger(logger);
146
144
  const builder = pluginKubernetesBackend.KubernetesBuilder.createBuilder({
147
- logger: winstonLogger,
145
+ logger,
148
146
  config,
149
147
  catalogApi,
150
148
  permissions,
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nimport { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';\n\nimport {\n kubernetesAuthStrategyExtensionPoint,\n kubernetesClusterSupplierExtensionPoint,\n kubernetesFetcherExtensionPoint,\n kubernetesObjectsProviderExtensionPoint,\n kubernetesServiceLocatorExtensionPoint,\n type AuthenticationStrategy,\n type KubernetesAuthStrategyExtensionPoint,\n type KubernetesClusterSupplierExtensionPoint,\n type KubernetesClustersSupplier,\n type KubernetesFetcher,\n type KubernetesFetcherExtensionPoint,\n type KubernetesObjectsProvider,\n type KubernetesObjectsProviderExtensionPoint,\n type KubernetesServiceLocator,\n type KubernetesServiceLocatorExtensionPoint,\n} from '@backstage/plugin-kubernetes-node';\n\nclass ObjectsProvider implements KubernetesObjectsProviderExtensionPoint {\n private objectsProvider: KubernetesObjectsProvider | undefined;\n\n getObjectsProvider() {\n return this.objectsProvider;\n }\n\n addObjectsProvider(provider: KubernetesObjectsProvider) {\n if (this.objectsProvider) {\n throw new Error(\n 'Multiple Kubernetes objects provider is not supported at this time',\n );\n }\n this.objectsProvider = provider;\n }\n}\n\nclass ClusterSuplier implements KubernetesClusterSupplierExtensionPoint {\n private clusterSupplier: KubernetesClustersSupplier | undefined;\n\n getClusterSupplier() {\n return this.clusterSupplier;\n }\n\n addClusterSupplier(clusterSupplier: KubernetesClustersSupplier) {\n if (this.clusterSupplier) {\n throw new Error(\n 'Multiple Kubernetes Cluster Suppliers is not supported at this time',\n );\n }\n this.clusterSupplier = clusterSupplier;\n }\n}\n\nclass Fetcher implements KubernetesFetcherExtensionPoint {\n private fetcher: KubernetesFetcher | undefined;\n\n getFetcher() {\n return this.fetcher;\n }\n\n addFetcher(fetcher: KubernetesFetcher) {\n if (this.fetcher) {\n throw new Error(\n 'Multiple Kubernetes Fetchers is not supported at this time',\n );\n }\n this.fetcher = fetcher;\n }\n}\n\nclass ServiceLocator implements KubernetesServiceLocatorExtensionPoint {\n private serviceLocator: KubernetesServiceLocator | undefined;\n\n getServiceLocator() {\n return this.serviceLocator;\n }\n\n addServiceLocator(serviceLocator: KubernetesServiceLocator) {\n if (this.serviceLocator) {\n throw new Error(\n 'Multiple Kubernetes Service Locators is not supported at this time',\n );\n }\n this.serviceLocator = serviceLocator;\n }\n}\n\nclass AuthStrategy implements KubernetesAuthStrategyExtensionPoint {\n private authStrategies: Array<{\n key: string;\n strategy: AuthenticationStrategy;\n }>;\n\n constructor() {\n this.authStrategies = new Array<{\n key: string;\n strategy: AuthenticationStrategy;\n }>();\n }\n\n static addAuthStrategiesFromArray(\n authStrategies: Array<{ key: string; strategy: AuthenticationStrategy }>,\n builder: KubernetesBuilder,\n ) {\n authStrategies.forEach(st => builder.addAuthStrategy(st.key, st.strategy));\n }\n\n getAuthenticationStrategies() {\n return this.authStrategies;\n }\n\n addAuthStrategy(key: string, authStrategy: AuthenticationStrategy) {\n this.authStrategies.push({ key, strategy: authStrategy });\n }\n}\n\n/**\n * This is the backend plugin that provides the Kubernetes integration.\n * @alpha\n */\n\nexport const kubernetesPlugin = createBackendPlugin({\n pluginId: 'kubernetes',\n register(env) {\n const extPointObjectsProvider = new ObjectsProvider();\n const extPointClusterSuplier = new ClusterSuplier();\n const extPointAuthStrategy = new AuthStrategy();\n const extPointFetcher = new Fetcher();\n const extPointServiceLocator = new ServiceLocator();\n\n env.registerExtensionPoint(\n kubernetesObjectsProviderExtensionPoint,\n extPointObjectsProvider,\n );\n env.registerExtensionPoint(\n kubernetesClusterSupplierExtensionPoint,\n extPointClusterSuplier,\n );\n env.registerExtensionPoint(\n kubernetesAuthStrategyExtensionPoint,\n extPointAuthStrategy,\n );\n env.registerExtensionPoint(\n kubernetesFetcherExtensionPoint,\n extPointFetcher,\n );\n env.registerExtensionPoint(\n kubernetesServiceLocatorExtensionPoint,\n extPointServiceLocator,\n );\n\n env.registerInit({\n deps: {\n http: coreServices.httpRouter,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n catalogApi: catalogServiceRef,\n permissions: coreServices.permissions,\n auth: coreServices.auth,\n httpAuth: coreServices.httpAuth,\n },\n async init({\n http,\n logger,\n config,\n discovery,\n catalogApi,\n permissions,\n auth,\n httpAuth,\n }) {\n const winstonLogger = loggerToWinstonLogger(logger);\n // TODO: expose all of the customization & extension points of the builder here\n const builder: KubernetesBuilder = KubernetesBuilder.createBuilder({\n logger: winstonLogger,\n config,\n catalogApi,\n permissions,\n discovery,\n auth,\n httpAuth,\n })\n .setObjectsProvider(extPointObjectsProvider.getObjectsProvider())\n .setClusterSupplier(extPointClusterSuplier.getClusterSupplier())\n .setFetcher(extPointFetcher.getFetcher())\n .setServiceLocator(extPointServiceLocator.getServiceLocator());\n\n AuthStrategy.addAuthStrategiesFromArray(\n extPointAuthStrategy.getAuthenticationStrategies(),\n builder,\n );\n const { router } = await builder.build();\n http.use(router);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","kubernetesObjectsProviderExtensionPoint","kubernetesClusterSupplierExtensionPoint","kubernetesAuthStrategyExtensionPoint","kubernetesFetcherExtensionPoint","kubernetesServiceLocatorExtensionPoint","coreServices","catalogServiceRef","loggerToWinstonLogger","KubernetesBuilder"],"mappings":"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"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nimport { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';\n\nimport {\n type AuthenticationStrategy,\n kubernetesAuthStrategyExtensionPoint,\n type KubernetesAuthStrategyExtensionPoint,\n type KubernetesClustersSupplier,\n kubernetesClusterSupplierExtensionPoint,\n type KubernetesClusterSupplierExtensionPoint,\n type KubernetesFetcher,\n kubernetesFetcherExtensionPoint,\n type KubernetesFetcherExtensionPoint,\n type KubernetesObjectsProvider,\n kubernetesObjectsProviderExtensionPoint,\n type KubernetesObjectsProviderExtensionPoint,\n type KubernetesServiceLocator,\n kubernetesServiceLocatorExtensionPoint,\n type KubernetesServiceLocatorExtensionPoint,\n} from '@backstage/plugin-kubernetes-node';\n\nclass ObjectsProvider implements KubernetesObjectsProviderExtensionPoint {\n private objectsProvider: KubernetesObjectsProvider | undefined;\n\n getObjectsProvider() {\n return this.objectsProvider;\n }\n\n addObjectsProvider(provider: KubernetesObjectsProvider) {\n if (this.objectsProvider) {\n throw new Error(\n 'Multiple Kubernetes objects provider is not supported at this time',\n );\n }\n this.objectsProvider = provider;\n }\n}\n\nclass ClusterSuplier implements KubernetesClusterSupplierExtensionPoint {\n private clusterSupplier: KubernetesClustersSupplier | undefined;\n\n getClusterSupplier() {\n return this.clusterSupplier;\n }\n\n addClusterSupplier(clusterSupplier: KubernetesClustersSupplier) {\n if (this.clusterSupplier) {\n throw new Error(\n 'Multiple Kubernetes Cluster Suppliers is not supported at this time',\n );\n }\n this.clusterSupplier = clusterSupplier;\n }\n}\n\nclass Fetcher implements KubernetesFetcherExtensionPoint {\n private fetcher: KubernetesFetcher | undefined;\n\n getFetcher() {\n return this.fetcher;\n }\n\n addFetcher(fetcher: KubernetesFetcher) {\n if (this.fetcher) {\n throw new Error(\n 'Multiple Kubernetes Fetchers is not supported at this time',\n );\n }\n this.fetcher = fetcher;\n }\n}\n\nclass ServiceLocator implements KubernetesServiceLocatorExtensionPoint {\n private serviceLocator: KubernetesServiceLocator | undefined;\n\n getServiceLocator() {\n return this.serviceLocator;\n }\n\n addServiceLocator(serviceLocator: KubernetesServiceLocator) {\n if (this.serviceLocator) {\n throw new Error(\n 'Multiple Kubernetes Service Locators is not supported at this time',\n );\n }\n this.serviceLocator = serviceLocator;\n }\n}\n\nclass AuthStrategy implements KubernetesAuthStrategyExtensionPoint {\n private authStrategies: Array<{\n key: string;\n strategy: AuthenticationStrategy;\n }>;\n\n constructor() {\n this.authStrategies = new Array<{\n key: string;\n strategy: AuthenticationStrategy;\n }>();\n }\n\n static addAuthStrategiesFromArray(\n authStrategies: Array<{ key: string; strategy: AuthenticationStrategy }>,\n builder: KubernetesBuilder,\n ) {\n authStrategies.forEach(st => builder.addAuthStrategy(st.key, st.strategy));\n }\n\n getAuthenticationStrategies() {\n return this.authStrategies;\n }\n\n addAuthStrategy(key: string, authStrategy: AuthenticationStrategy) {\n this.authStrategies.push({ key, strategy: authStrategy });\n }\n}\n\n/**\n * This is the backend plugin that provides the Kubernetes integration.\n * @alpha\n */\n\nexport const kubernetesPlugin = createBackendPlugin({\n pluginId: 'kubernetes',\n register(env) {\n const extPointObjectsProvider = new ObjectsProvider();\n const extPointClusterSuplier = new ClusterSuplier();\n const extPointAuthStrategy = new AuthStrategy();\n const extPointFetcher = new Fetcher();\n const extPointServiceLocator = new ServiceLocator();\n\n env.registerExtensionPoint(\n kubernetesObjectsProviderExtensionPoint,\n extPointObjectsProvider,\n );\n env.registerExtensionPoint(\n kubernetesClusterSupplierExtensionPoint,\n extPointClusterSuplier,\n );\n env.registerExtensionPoint(\n kubernetesAuthStrategyExtensionPoint,\n extPointAuthStrategy,\n );\n env.registerExtensionPoint(\n kubernetesFetcherExtensionPoint,\n extPointFetcher,\n );\n env.registerExtensionPoint(\n kubernetesServiceLocatorExtensionPoint,\n extPointServiceLocator,\n );\n\n env.registerInit({\n deps: {\n http: coreServices.httpRouter,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n catalogApi: catalogServiceRef,\n permissions: coreServices.permissions,\n auth: coreServices.auth,\n httpAuth: coreServices.httpAuth,\n },\n async init({\n http,\n logger,\n config,\n discovery,\n catalogApi,\n permissions,\n auth,\n httpAuth,\n }) {\n // TODO: expose all of the customization & extension points of the builder here\n const builder: KubernetesBuilder = KubernetesBuilder.createBuilder({\n logger,\n config,\n catalogApi,\n permissions,\n discovery,\n auth,\n httpAuth,\n })\n .setObjectsProvider(extPointObjectsProvider.getObjectsProvider())\n .setClusterSupplier(extPointClusterSuplier.getClusterSupplier())\n .setFetcher(extPointFetcher.getFetcher())\n .setServiceLocator(extPointServiceLocator.getServiceLocator());\n\n AuthStrategy.addAuthStrategiesFromArray(\n extPointAuthStrategy.getAuthenticationStrategies(),\n builder,\n );\n const { router } = await builder.build();\n http.use(router);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","kubernetesObjectsProviderExtensionPoint","kubernetesClusterSupplierExtensionPoint","kubernetesAuthStrategyExtensionPoint","kubernetesFetcherExtensionPoint","kubernetesServiceLocatorExtensionPoint","coreServices","catalogServiceRef","KubernetesBuilder"],"mappings":"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"}
package/dist/index.cjs.js CHANGED
@@ -81,7 +81,7 @@ class AnonymousStrategy {
81
81
  var __defProp$c = Object.defineProperty;
82
82
  var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
83
83
  var __publicField$c = (obj, key, value) => {
84
- __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
84
+ __defNormalProp$c(obj, key + "" , value);
85
85
  return value;
86
86
  };
87
87
  const defaultRegion = "us-east-1";
@@ -257,7 +257,7 @@ class GoogleServiceAccountStrategy {
257
257
  var __defProp$a = Object.defineProperty;
258
258
  var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
259
259
  var __publicField$a = (obj, key, value) => {
260
- __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
260
+ __defNormalProp$a(obj, key + "" , value);
261
261
  return value;
262
262
  };
263
263
  class DispatchStrategy {
@@ -345,7 +345,7 @@ class OidcStrategy {
345
345
  var __defProp$9 = Object.defineProperty;
346
346
  var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
347
347
  var __publicField$9 = (obj, key, value) => {
348
- __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
348
+ __defNormalProp$9(obj, key + "" , value);
349
349
  return value;
350
350
  };
351
351
  class ConfigClusterLocator {
@@ -470,7 +470,7 @@ function runPeriodically(fn, delayMs) {
470
470
 
471
471
  var name = "@backstage/plugin-kubernetes-backend";
472
472
  var description = "A Backstage backend plugin that integrates towards Kubernetes";
473
- var version = "0.17.0-next.1";
473
+ var version = "0.17.1-next.0";
474
474
  var main = "src/index.ts";
475
475
  var types = "src/index.ts";
476
476
  var license = "Apache-2.0";
@@ -538,7 +538,7 @@ var dependencies = {
538
538
  "@jest-mock/express": "^2.0.1",
539
539
  "@kubernetes/client-node": "0.20.0",
540
540
  "@types/express": "^4.17.6",
541
- "@types/http-proxy-middleware": "^0.19.3",
541
+ "@types/http-proxy-middleware": "^1.0.0",
542
542
  "@types/luxon": "^3.0.0",
543
543
  compression: "^1.7.4",
544
544
  cors: "^2.8.5",
@@ -914,7 +914,7 @@ const addResourceRoutesToRouter = (router, catalogApi, objectsProvider, auth, ht
914
914
  var __defProp$6 = Object.defineProperty;
915
915
  var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
916
916
  var __publicField$6 = (obj, key, value) => {
917
- __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
917
+ __defNormalProp$6(obj, key + "" , value);
918
918
  return value;
919
919
  };
920
920
  class CatalogRelationServiceLocator {
@@ -950,7 +950,7 @@ class CatalogRelationServiceLocator {
950
950
  var __defProp$5 = Object.defineProperty;
951
951
  var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
952
952
  var __publicField$5 = (obj, key, value) => {
953
- __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
953
+ __defNormalProp$5(obj, key + "" , value);
954
954
  return value;
955
955
  };
956
956
  class MultiTenantServiceLocator {
@@ -967,7 +967,7 @@ class MultiTenantServiceLocator {
967
967
  var __defProp$4 = Object.defineProperty;
968
968
  var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
969
969
  var __publicField$4 = (obj, key, value) => {
970
- __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
970
+ __defNormalProp$4(obj, key + "" , value);
971
971
  return value;
972
972
  };
973
973
  class SingleTenantServiceLocator {
@@ -1259,7 +1259,7 @@ class KubernetesFanOutHandler {
1259
1259
  var __defProp$2 = Object.defineProperty;
1260
1260
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1261
1261
  var __publicField$2 = (obj, key, value) => {
1262
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
1262
+ __defNormalProp$2(obj, key + "" , value);
1263
1263
  return value;
1264
1264
  };
1265
1265
  const isError = (fr) => fr.hasOwnProperty("errorType");
@@ -1515,7 +1515,8 @@ class KubernetesProxy {
1515
1515
  if (!middleware) {
1516
1516
  const logger = this.logger.child({ cluster: originalCluster.name });
1517
1517
  middleware = httpProxyMiddleware.createProxyMiddleware({
1518
- logProvider: () => logger,
1518
+ // TODO: Add 'log' to LoggerService
1519
+ logProvider: () => backendCommon.loggerToWinstonLogger(logger),
1519
1520
  ws: true,
1520
1521
  secure: !originalCluster.skipTLSVerify,
1521
1522
  changeOrigin: true,
@@ -1540,8 +1541,8 @@ class KubernetesProxy {
1540
1541
  cluster.caData
1541
1542
  )) == null ? void 0 : _a.toString()
1542
1543
  };
1543
- const authHeader = req.header(HEADER_KUBERNETES_AUTH);
1544
- if (authHeader) {
1544
+ const authHeader = req.headers[HEADER_KUBERNETES_AUTH.toLocaleLowerCase("en-US")];
1545
+ if (typeof authHeader === "string") {
1545
1546
  req.headers.authorization = authHeader;
1546
1547
  } else {
1547
1548
  const authObj = KubernetesProxy.authHeadersToKubernetesRequestAuth(
@@ -1564,7 +1565,7 @@ class KubernetesProxy {
1564
1565
  `Cluster '${originalCluster.name}' request error`,
1565
1566
  error
1566
1567
  );
1567
- logger.error(wrappedError);
1568
+ logger.error("Kubernetes proxy error", wrappedError);
1568
1569
  const body = {
1569
1570
  error: errors.serializeError(wrappedError, {
1570
1571
  includeStack: process.env.NODE_ENV === "development"
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/auth/AksStrategy.ts","../src/auth/AnonymousStrategy.ts","../src/auth/AwsIamStrategy.ts","../src/auth/AzureIdentityStrategy.ts","../src/auth/GoogleStrategy.ts","../src/auth/GoogleServiceAccountStrategy.ts","../src/auth/DispatchStrategy.ts","../src/auth/ServiceAccountStrategy.ts","../src/auth/OidcStrategy.ts","../src/cluster-locator/ConfigClusterLocator.ts","../src/service/runPeriodically.ts","../src/cluster-locator/GkeClusterLocator.ts","../src/cluster-locator/CatalogClusterLocator.ts","../src/cluster-locator/LocalKubectlProxyLocator.ts","../src/cluster-locator/index.ts","../src/routes/resourcesRoutes.ts","../src/service-locator/CatalogRelationServiceLocator.ts","../src/service-locator/MultiTenantServiceLocator.ts","../src/service-locator/SingleTenantServiceLocator.ts","../src/service/KubernetesFanOutHandler.ts","../src/service/KubernetesFetcher.ts","../src/service/KubernetesProxy.ts","../src/service/KubernetesBuilder.ts","../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';\n\n/**\n *\n * @public\n */\nexport class AksStrategy implements AuthenticationStrategy {\n public async getCredential(\n _: ClusterDetails,\n requestAuth: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const token = requestAuth.aks;\n return token\n ? { type: 'bearer token', token: token as string }\n : { type: 'anonymous' };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport class AnonymousStrategy implements AuthenticationStrategy {\n public async getCredential(): Promise<KubernetesCredential> {\n return { type: 'anonymous' };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { fromTemporaryCredentials } from '@aws-sdk/credential-providers';\nimport { SignatureV4 } from '@aws-sdk/signature-v4';\nimport { Sha256 } from '@aws-crypto/sha256-js';\nimport {\n AwsCredentialsManager,\n DefaultAwsCredentialsManager,\n} from '@backstage/integration-aws-node';\nimport { Config } from '@backstage/config';\nimport {\n ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,\n ANNOTATION_KUBERNETES_AWS_CLUSTER_ID,\n ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport type SigningCreds = {\n accessKeyId: string | undefined;\n secretAccessKey: string | undefined;\n sessionToken: string | undefined;\n};\n\nconst defaultRegion = 'us-east-1';\n\n/**\n *\n * @public\n */\nexport class AwsIamStrategy implements AuthenticationStrategy {\n private readonly credsManager: AwsCredentialsManager;\n\n constructor(opts: { config: Config }) {\n this.credsManager = DefaultAwsCredentialsManager.fromConfig(opts.config);\n }\n\n public async getCredential(\n clusterDetails: ClusterDetails,\n ): Promise<KubernetesCredential> {\n return {\n type: 'bearer token',\n token: await this.getBearerToken(\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_CLUSTER_ID] ??\n clusterDetails.name,\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE],\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID],\n ),\n };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n private async getBearerToken(\n clusterId: string,\n assumeRole?: string,\n externalId?: string,\n ): Promise<string> {\n const region = process.env.AWS_REGION ?? defaultRegion;\n\n let credentials = (await this.credsManager.getCredentialProvider())\n .sdkCredentialProvider;\n if (assumeRole) {\n credentials = fromTemporaryCredentials({\n masterCredentials: credentials,\n clientConfig: {\n region,\n },\n params: {\n RoleArn: assumeRole,\n ExternalId: externalId,\n },\n });\n }\n\n const signer = new SignatureV4({\n credentials,\n region,\n service: 'sts',\n sha256: Sha256,\n });\n\n const request = await signer.presign(\n {\n headers: {\n host: `sts.${region}.amazonaws.com`,\n 'x-k8s-aws-id': clusterId,\n },\n hostname: `sts.${region}.amazonaws.com`,\n method: 'GET',\n path: '/',\n protocol: 'https:',\n query: {\n Action: 'GetCallerIdentity',\n Version: '2011-06-15',\n },\n },\n { expiresIn: 0 },\n );\n\n const query = Object.keys(request?.query ?? {})\n .map(\n q =>\n `${encodeURIComponent(q)}=${encodeURIComponent(\n request.query?.[q] as string,\n )}`,\n )\n .join('&');\n\n const url = `https://${request.hostname}${request.path}?${query}`;\n\n return `k8s-aws-v1.${Buffer.from(url).toString('base64url')}`;\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from 'winston';\nimport {\n AccessToken,\n DefaultAzureCredential,\n TokenCredential,\n} from '@azure/identity';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\nconst aksScope = '6dae42f8-4368-4678-94ff-3960e28e3630/.default'; // This scope is the same for all Azure Managed Kubernetes\n\n/**\n *\n * @public\n */\nexport class AzureIdentityStrategy implements AuthenticationStrategy {\n private accessToken: AccessToken = { token: '', expiresOnTimestamp: 0 };\n private newTokenPromise: Promise<string> | undefined;\n\n constructor(\n private readonly logger: Logger,\n private readonly tokenCredential: TokenCredential = new DefaultAzureCredential(),\n ) {}\n\n public async getCredential(): Promise<KubernetesCredential> {\n if (!this.tokenRequiresRefresh()) {\n return { type: 'bearer token', token: this.accessToken.token };\n }\n\n if (!this.newTokenPromise) {\n this.newTokenPromise = this.fetchNewToken();\n }\n\n return this.newTokenPromise\n ? { type: 'bearer token', token: await this.newTokenPromise }\n : { type: 'anonymous' };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n private async fetchNewToken(): Promise<string> {\n try {\n this.logger.info('Fetching new Azure token for AKS');\n\n const newAccessToken = await this.tokenCredential.getToken(aksScope, {\n requestOptions: { timeout: 10_000 }, // 10 seconds\n });\n if (!newAccessToken) {\n throw new Error('AccessToken is null');\n }\n\n this.accessToken = newAccessToken;\n } catch (err) {\n this.logger.error('Unable to fetch Azure token', err);\n\n // only throw the error if the token has already expired, otherwise re-use existing until we're able to fetch a new token\n if (this.tokenExpired()) {\n throw err;\n }\n }\n\n this.newTokenPromise = undefined;\n return this.accessToken.token;\n }\n\n private tokenRequiresRefresh(): boolean {\n // Set tokens to expire 15 minutes before its actual expiry time\n const expiresOn = this.accessToken.expiresOnTimestamp - 15 * 60 * 1000;\n return Date.now() >= expiresOn;\n }\n\n private tokenExpired(): boolean {\n return Date.now() >= this.accessToken.expiresOnTimestamp;\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport class GoogleStrategy implements AuthenticationStrategy {\n public async getCredential(\n _: ClusterDetails,\n requestAuth: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const token = requestAuth.google;\n if (!token) {\n throw new Error(\n 'Google token not found under auth.google in request body',\n );\n }\n return { type: 'bearer token', token: token as string };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport * as container from '@google-cloud/container';\n\n/**\n *\n * @public\n */\nexport class GoogleServiceAccountStrategy implements AuthenticationStrategy {\n public async getCredential(): Promise<KubernetesCredential> {\n const client = new container.v1.ClusterManagerClient();\n const token = await client.auth.getAccessToken();\n\n if (!token) {\n throw new Error(\n 'Unable to obtain access token for the current Google Application Default Credentials',\n );\n }\n return { type: 'bearer token', token };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n KubernetesRequestAuth,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport type DispatchStrategyOptions = {\n authStrategyMap: {\n [key: string]: AuthenticationStrategy;\n };\n};\n/**\n * used to direct a KubernetesAuthProvider to its corresponding AuthenticationStrategy\n * @public\n */\nexport class DispatchStrategy implements AuthenticationStrategy {\n private readonly strategyMap: { [key: string]: AuthenticationStrategy };\n\n constructor(options: DispatchStrategyOptions) {\n this.strategyMap = options.authStrategyMap;\n }\n\n public getCredential(\n clusterDetails: ClusterDetails,\n auth: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const authProvider =\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n if (this.strategyMap[authProvider]) {\n return this.strategyMap[authProvider].getCredential(clusterDetails, auth);\n }\n throw new Error(\n `authProvider \"${authProvider}\" has no AuthenticationStrategy associated with it`,\n );\n }\n\n public validateCluster(authMetadata: AuthMetadata): Error[] {\n const authProvider = authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n const strategy = this.strategyMap[authProvider];\n if (!strategy) {\n return [\n new Error(\n `authProvider \"${authProvider}\" has no config associated with it`,\n ),\n ];\n }\n return strategy.validateCluster(authMetadata);\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport { KubeConfig, User } from '@kubernetes/client-node';\nimport fs from 'fs-extra';\n\n/**\n *\n * @public\n */\nexport class ServiceAccountStrategy implements AuthenticationStrategy {\n public async getCredential(\n clusterDetails: ClusterDetails,\n ): Promise<KubernetesCredential> {\n const token = clusterDetails.authMetadata.serviceAccountToken;\n if (token) {\n return { type: 'bearer token', token };\n }\n const kc = new KubeConfig();\n kc.loadFromCluster();\n // loadFromCluster is guaranteed to populate the user\n const user = kc.getCurrentUser() as User;\n\n return {\n type: 'bearer token',\n token: fs.readFileSync(user.authProvider.config.tokenFile).toString(),\n };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { JsonObject } from '@backstage/types';\nimport {\n ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,\n KubernetesRequestAuth,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport class OidcStrategy implements AuthenticationStrategy {\n public async getCredential(\n clusterDetails: ClusterDetails,\n authConfig: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const oidcTokenProvider =\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];\n\n if (!oidcTokenProvider || oidcTokenProvider === '') {\n throw new Error(\n `oidc authProvider requires a configured oidcTokenProvider`,\n );\n }\n\n const token = (authConfig.oidc as JsonObject | null)?.[oidcTokenProvider];\n\n if (!token) {\n throw new Error(\n `Auth token not found under oidc.${oidcTokenProvider} in request body`,\n );\n }\n return { type: 'bearer token', token: token as string };\n }\n\n public validateCluster(authMetadata: AuthMetadata): Error[] {\n const oidcTokenProvider =\n authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];\n if (!oidcTokenProvider || oidcTokenProvider === '') {\n return [new Error(`Must specify a token provider for 'oidc' strategy`)];\n }\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,\n ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,\n ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,\n} from '@backstage/plugin-kubernetes-common';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport { AuthenticationStrategy } from '../auth';\n\nexport class ConfigClusterLocator implements KubernetesClustersSupplier {\n private readonly clusterDetails: ClusterDetails[];\n\n constructor(clusterDetails: ClusterDetails[]) {\n this.clusterDetails = clusterDetails;\n }\n\n static fromConfig(\n config: Config,\n authStrategy: AuthenticationStrategy,\n ): ConfigClusterLocator {\n const clusterNames = new Set();\n return new ConfigClusterLocator(\n config.getConfigArray('clusters').map(c => {\n const authMetadataBlock = c.getOptional<{\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]?: string;\n }>('authMetadata');\n const name = c.getString('name');\n if (clusterNames.has(name)) {\n throw new Error(`Duplicate cluster name '${name}'`);\n }\n clusterNames.add(name);\n const authProvider =\n authMetadataBlock?.[ANNOTATION_KUBERNETES_AUTH_PROVIDER] ??\n c.getOptionalString('authProvider');\n if (!authProvider) {\n throw new Error(\n `cluster '${name}' has no auth provider configured; this must be ` +\n `specified via the 'authProvider' or ` +\n `'authMetadata.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}' parameter`,\n );\n }\n const title = c.getOptionalString('title');\n const clusterDetails: ClusterDetails = {\n name,\n ...(title && { title }),\n url: c.getString('url'),\n skipTLSVerify: c.getOptionalBoolean('skipTLSVerify') ?? false,\n skipMetricsLookup: c.getOptionalBoolean('skipMetricsLookup') ?? false,\n caData: c.getOptionalString('caData'),\n caFile: c.getOptionalString('caFile'),\n authMetadata: {\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider,\n ...ConfigClusterLocator.parseAuthMetadata(c),\n ...authMetadataBlock,\n },\n };\n\n const customResources = c.getOptionalConfigArray('customResources');\n if (customResources) {\n clusterDetails.customResources = customResources.map(cr => {\n return {\n group: cr.getString('group'),\n apiVersion: cr.getString('apiVersion'),\n plural: cr.getString('plural'),\n };\n });\n }\n\n const dashboardUrl = c.getOptionalString('dashboardUrl');\n if (dashboardUrl) {\n clusterDetails.dashboardUrl = dashboardUrl;\n }\n const dashboardApp = c.getOptionalString('dashboardApp');\n if (dashboardApp) {\n clusterDetails.dashboardApp = dashboardApp;\n }\n if (c.has('dashboardParameters')) {\n clusterDetails.dashboardParameters = c.get('dashboardParameters');\n }\n\n const validationErrors = authStrategy.validateCluster(\n clusterDetails.authMetadata,\n );\n if (validationErrors.length !== 0) {\n throw new Error(\n `Invalid cluster '${clusterDetails.name}': ${validationErrors\n .map(e => e.message)\n .join(', ')}`,\n );\n }\n return clusterDetails;\n }),\n );\n }\n\n private static parseAuthMetadata(\n clusterConfig: Config,\n ): Record<string, string> | undefined {\n const serviceAccountToken = clusterConfig.getOptionalString(\n 'serviceAccountToken',\n );\n const assumeRole = clusterConfig.getOptionalString('assumeRole');\n const externalId = clusterConfig.getOptionalString('externalId');\n const oidcTokenProvider =\n clusterConfig.getOptionalString('oidcTokenProvider');\n\n return serviceAccountToken || assumeRole || externalId || oidcTokenProvider\n ? {\n ...(serviceAccountToken && { serviceAccountToken }),\n ...(assumeRole && {\n [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: assumeRole,\n }),\n ...(externalId && {\n [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: externalId,\n }),\n ...(oidcTokenProvider && {\n [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: oidcTokenProvider,\n }),\n }\n : undefined;\n }\n\n async getClusters(): Promise<ClusterDetails[]> {\n return this.clusterDetails;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Runs a function repeatedly, with a fixed wait between invocations.\n *\n * Supports async functions, and silently ignores exceptions and rejections.\n *\n * @param fn - The function to run. May return a Promise.\n * @param delayMs - The delay between a completed function invocation and the\n * next.\n * @returns A function that, when called, stops the invocation loop.\n */\nexport function runPeriodically(fn: () => any, delayMs: number): () => void {\n let cancel: () => void;\n let cancelled = false;\n const cancellationPromise = new Promise<void>(resolve => {\n cancel = () => {\n resolve();\n cancelled = true;\n };\n });\n\n const startRefresh = async () => {\n while (!cancelled) {\n try {\n await fn();\n } catch {\n // ignore intentionally\n }\n\n await Promise.race([\n new Promise(resolve => setTimeout(resolve, delayMs)),\n cancellationPromise,\n ]);\n }\n };\n startRefresh();\n\n return cancel!;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ANNOTATION_KUBERNETES_AUTH_PROVIDER } from '@backstage/plugin-kubernetes-common';\nimport { Config } from '@backstage/config';\nimport { ForwardedError } from '@backstage/errors';\nimport * as container from '@google-cloud/container';\nimport { Duration } from 'luxon';\nimport { runPeriodically } from '../service/runPeriodically';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport packageinfo from '../../package.json';\n\ninterface MatchResourceLabelEntry {\n key: string;\n value: string;\n}\n\ntype GkeClusterLocatorOptions = {\n projectId: string;\n authProvider: string;\n region?: string;\n skipTLSVerify?: boolean;\n skipMetricsLookup?: boolean;\n exposeDashboard?: boolean;\n matchingResourceLabels?: MatchResourceLabelEntry[];\n};\n\nexport class GkeClusterLocator implements KubernetesClustersSupplier {\n constructor(\n private readonly options: GkeClusterLocatorOptions,\n private readonly client: container.v1.ClusterManagerClient,\n private clusterDetails: ClusterDetails[] | undefined = undefined,\n private hasClusterDetails: boolean = false,\n ) {}\n\n static fromConfigWithClient(\n config: Config,\n client: container.v1.ClusterManagerClient,\n refreshInterval?: Duration,\n ): GkeClusterLocator {\n const matchingResourceLabels: MatchResourceLabelEntry[] =\n config.getOptionalConfigArray('matchingResourceLabels')?.map(mrl => {\n return { key: mrl.getString('key'), value: mrl.getString('value') };\n }) ?? [];\n\n const storeAuthProviderString =\n config.getOptionalString('authProvider') === 'googleServiceAccount'\n ? 'googleServiceAccount'\n : 'google';\n\n const options = {\n projectId: config.getString('projectId'),\n authProvider: storeAuthProviderString,\n region: config.getOptionalString('region') ?? '-',\n skipTLSVerify: config.getOptionalBoolean('skipTLSVerify') ?? false,\n skipMetricsLookup:\n config.getOptionalBoolean('skipMetricsLookup') ?? false,\n exposeDashboard: config.getOptionalBoolean('exposeDashboard') ?? false,\n matchingResourceLabels,\n };\n const gkeClusterLocator = new GkeClusterLocator(options, client);\n if (refreshInterval) {\n runPeriodically(\n () => gkeClusterLocator.refreshClusters(),\n refreshInterval.toMillis(),\n );\n }\n return gkeClusterLocator;\n }\n\n // Added an `x-goog-api-client` header to API requests made by the GKE cluster locator to clearly identify API requests from this plugin.\n static fromConfig(\n config: Config,\n refreshInterval: Duration | undefined = undefined,\n ): GkeClusterLocator {\n return GkeClusterLocator.fromConfigWithClient(\n config,\n new container.v1.ClusterManagerClient({\n libName: `backstage/kubernetes-backend.GkeClusterLocator`,\n libVersion: packageinfo.version,\n }),\n refreshInterval,\n );\n }\n\n async getClusters(): Promise<ClusterDetails[]> {\n if (!this.hasClusterDetails) {\n // refresh at least once when first called, when retries are disabled and in tests\n await this.refreshClusters();\n }\n return this.clusterDetails ?? [];\n }\n\n // TODO pass caData into the object\n async refreshClusters(): Promise<void> {\n const {\n projectId,\n region,\n authProvider,\n skipTLSVerify,\n skipMetricsLookup,\n exposeDashboard,\n matchingResourceLabels,\n } = this.options;\n const request = {\n parent: `projects/${projectId}/locations/${region}`,\n };\n\n try {\n const [response] = await this.client.listClusters(request);\n this.clusterDetails = (response.clusters ?? [])\n .filter(r => {\n return matchingResourceLabels?.every(mrl => {\n if (!r.resourceLabels) {\n return false;\n }\n return r.resourceLabels[mrl.key] === mrl.value;\n });\n })\n .map(r => ({\n // TODO filter out clusters which don't have name or endpoint\n name: r.name ?? 'unknown',\n url: `https://${r.endpoint ?? ''}`,\n authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider },\n skipTLSVerify,\n skipMetricsLookup,\n ...(exposeDashboard\n ? {\n dashboardApp: 'gke',\n dashboardParameters: {\n projectId,\n region,\n clusterName: r.name,\n },\n }\n : {}),\n }));\n this.hasClusterDetails = true;\n } catch (e) {\n throw new ForwardedError(\n `There was an error retrieving clusters from GKE for projectId=${projectId} region=${region}`,\n e,\n );\n }\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthService,\n BackstageCredentials,\n} from '@backstage/backend-plugin-api';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client';\nimport {\n ANNOTATION_KUBERNETES_API_SERVER,\n ANNOTATION_KUBERNETES_API_SERVER_CA,\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP,\n ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY,\n ANNOTATION_KUBERNETES_DASHBOARD_URL,\n ANNOTATION_KUBERNETES_DASHBOARD_APP,\n ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS,\n} from '@backstage/plugin-kubernetes-common';\nimport { JsonObject } from '@backstage/types';\n\nfunction isObject(obj: unknown): obj is JsonObject {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj);\n}\n\nexport class CatalogClusterLocator implements KubernetesClustersSupplier {\n private catalogClient: CatalogApi;\n private auth: AuthService;\n\n constructor(catalogClient: CatalogApi, auth: AuthService) {\n this.catalogClient = catalogClient;\n this.auth = auth;\n }\n\n static fromConfig(\n catalogApi: CatalogApi,\n auth: AuthService,\n ): CatalogClusterLocator {\n return new CatalogClusterLocator(catalogApi, auth);\n }\n\n async getClusters(options?: {\n credentials: BackstageCredentials;\n }): Promise<ClusterDetails[]> {\n const apiServerKey = `metadata.annotations.${ANNOTATION_KUBERNETES_API_SERVER}`;\n const apiServerCaKey = `metadata.annotations.${ANNOTATION_KUBERNETES_API_SERVER_CA}`;\n const authProviderKey = `metadata.annotations.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}`;\n\n const filter: Record<string, symbol | string> = {\n kind: 'Resource',\n 'spec.type': 'kubernetes-cluster',\n [apiServerKey]: CATALOG_FILTER_EXISTS,\n [apiServerCaKey]: CATALOG_FILTER_EXISTS,\n [authProviderKey]: CATALOG_FILTER_EXISTS,\n };\n\n const clusters = await this.catalogClient.getEntities(\n {\n filter: [filter],\n },\n options?.credentials\n ? {\n token: (\n await this.auth.getPluginRequestToken({\n onBehalfOf: options.credentials,\n targetPluginId: 'catalog',\n })\n ).token,\n }\n : undefined,\n );\n return clusters.items.map(entity => {\n const annotations = entity.metadata.annotations!;\n const clusterDetails: ClusterDetails = {\n name: entity.metadata.name,\n title: entity.metadata.title,\n url: annotations[ANNOTATION_KUBERNETES_API_SERVER],\n authMetadata: annotations,\n caData: annotations[ANNOTATION_KUBERNETES_API_SERVER_CA],\n skipMetricsLookup:\n annotations[ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP] === 'true',\n skipTLSVerify:\n annotations[ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY] === 'true',\n dashboardUrl: annotations[ANNOTATION_KUBERNETES_DASHBOARD_URL],\n dashboardApp: annotations[ANNOTATION_KUBERNETES_DASHBOARD_APP],\n dashboardParameters: this.getDashboardParameters(annotations),\n };\n\n return clusterDetails;\n });\n }\n\n private getDashboardParameters(\n annotations: Record<string, string>,\n ): JsonObject | undefined {\n const dashboardParamsString =\n annotations[ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS];\n if (dashboardParamsString) {\n try {\n const dashboardParams = JSON.parse(dashboardParamsString);\n return isObject(dashboardParams) ? dashboardParams : undefined;\n } catch {\n return undefined;\n }\n }\n return undefined;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ANNOTATION_KUBERNETES_AUTH_PROVIDER } from '@backstage/plugin-kubernetes-common';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n} from '@backstage/plugin-kubernetes-node';\nimport dns from 'node:dns';\n\nexport class LocalKubectlProxyClusterLocator\n implements KubernetesClustersSupplier\n{\n private readonly clusterDetails: ClusterDetails[];\n // verbatim: when false, IPv4 addresses are placed before IPv6 addresses, ignoring the order from the DNS resolver\n // By default kubectl proxy listens on 127.0.0.1 instead of [::1]\n private lookupPromise = dns.promises.lookup('localhost', { verbatim: false });\n\n public constructor() {\n this.clusterDetails = [\n {\n name: 'local',\n url: 'http://localhost:8001',\n authMetadata: {\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'localKubectlProxy',\n },\n skipMetricsLookup: true,\n },\n ];\n }\n\n async getClusters(): Promise<ClusterDetails[]> {\n const lookupResolution = await this.lookupPromise;\n this.clusterDetails[0].url = `http://${lookupResolution.address}:8001`;\n return this.clusterDetails;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport { Duration } from 'luxon';\nimport { Logger } from 'winston';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport { AuthenticationStrategy } from '../auth/types';\nimport { ConfigClusterLocator } from './ConfigClusterLocator';\nimport { GkeClusterLocator } from './GkeClusterLocator';\nimport { CatalogClusterLocator } from './CatalogClusterLocator';\nimport { LocalKubectlProxyClusterLocator } from './LocalKubectlProxyLocator';\nimport {\n AuthService,\n BackstageCredentials,\n} from '@backstage/backend-plugin-api';\n\nclass CombinedClustersSupplier implements KubernetesClustersSupplier {\n constructor(\n readonly clusterSuppliers: KubernetesClustersSupplier[],\n readonly logger: Logger,\n ) {}\n\n async getClusters(options: {\n credentials: BackstageCredentials;\n }): Promise<ClusterDetails[]> {\n const clusters = await Promise.all(\n this.clusterSuppliers.map(supplier => supplier.getClusters(options)),\n )\n .then(res => {\n return res.flat();\n })\n .catch(e => {\n throw e;\n });\n return this.warnDuplicates(clusters);\n }\n\n private warnDuplicates(clusters: ClusterDetails[]): ClusterDetails[] {\n const clusterNames = new Set<string>();\n const duplicatedNames = new Set<string>();\n for (const clusterName of clusters.map(c => c.name)) {\n if (clusterNames.has(clusterName)) {\n duplicatedNames.add(clusterName);\n } else {\n clusterNames.add(clusterName);\n }\n }\n for (const clusterName of duplicatedNames) {\n this.logger.warn(`Duplicate cluster name '${clusterName}'`);\n }\n return clusters;\n }\n}\n\nexport const getCombinedClusterSupplier = (\n rootConfig: Config,\n catalogClient: CatalogApi,\n authStrategy: AuthenticationStrategy,\n logger: Logger,\n refreshInterval: Duration | undefined = undefined,\n auth: AuthService,\n): KubernetesClustersSupplier => {\n const clusterSuppliers = rootConfig\n .getConfigArray('kubernetes.clusterLocatorMethods')\n .map(clusterLocatorMethod => {\n const type = clusterLocatorMethod.getString('type');\n switch (type) {\n case 'catalog':\n return CatalogClusterLocator.fromConfig(catalogClient, auth);\n case 'localKubectlProxy':\n return new LocalKubectlProxyClusterLocator();\n case 'config':\n return ConfigClusterLocator.fromConfig(\n clusterLocatorMethod,\n authStrategy,\n );\n case 'gke':\n return GkeClusterLocator.fromConfig(\n clusterLocatorMethod,\n refreshInterval,\n );\n default:\n throw new Error(\n `Unsupported kubernetes.clusterLocatorMethods: \"${type}\"`,\n );\n }\n });\n\n return new CombinedClustersSupplier(clusterSuppliers, logger);\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n CompoundEntityRef,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { InputError } from '@backstage/errors';\nimport express, { Request } from 'express';\nimport { KubernetesObjectsProvider } from '@backstage/plugin-kubernetes-node';\nimport { AuthService, HttpAuthService } from '@backstage/backend-plugin-api';\n\nexport const addResourceRoutesToRouter = (\n router: express.Router,\n catalogApi: CatalogApi,\n objectsProvider: KubernetesObjectsProvider,\n auth: AuthService,\n httpAuth: HttpAuthService,\n) => {\n const getEntityByReq = async (req: Request<any>) => {\n const rawEntityRef = req.body.entityRef;\n if (rawEntityRef && typeof rawEntityRef !== 'string') {\n throw new InputError(`entity query must be a string`);\n } else if (!rawEntityRef) {\n throw new InputError('entity is a required field');\n }\n let entityRef: CompoundEntityRef | undefined = undefined;\n\n try {\n entityRef = parseEntityRef(rawEntityRef);\n } catch (error) {\n throw new InputError(`Invalid entity ref, ${error}`);\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(req),\n targetPluginId: 'catalog',\n });\n\n const entity = await catalogApi.getEntityByRef(entityRef, { token });\n if (!entity) {\n throw new InputError(\n `Entity ref missing, ${stringifyEntityRef(entityRef)}`,\n );\n }\n\n return entity;\n };\n\n router.post('/resources/workloads/query', async (req, res) => {\n const entity = await getEntityByReq(req);\n const response = await objectsProvider.getKubernetesObjectsByEntity(\n {\n entity,\n auth: req.body.auth,\n },\n { credentials: await httpAuth.credentials(req) },\n );\n res.json(response);\n });\n\n router.post('/resources/custom/query', async (req, res) => {\n const entity = await getEntityByReq(req);\n\n if (!req.body.customResources) {\n throw new InputError('customResources is a required field');\n } else if (!Array.isArray(req.body.customResources)) {\n throw new InputError('customResources must be an array');\n } else if (req.body.customResources.length === 0) {\n throw new InputError('at least 1 customResource is required');\n }\n\n const response = await objectsProvider.getCustomResourcesByEntity(\n {\n entity,\n customResources: req.body.customResources,\n auth: req.body.auth,\n },\n { credentials: await httpAuth.credentials(req) },\n );\n res.json(response);\n });\n};\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n KubernetesServiceLocator,\n ServiceLocatorRequestContext,\n} from '@backstage/plugin-kubernetes-node';\n\n// This locator assumes that service is located on the clusters it depends on\n// Therefore it will return the clusters based on the relations it has or none otherwise\nexport class CatalogRelationServiceLocator implements KubernetesServiceLocator {\n private readonly clusterSupplier: KubernetesClustersSupplier;\n\n constructor(clusterSupplier: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n }\n\n // As this implementation always returns all clusters serviceId is ignored here\n getClustersByEntity(\n entity: Entity,\n requestContext: ServiceLocatorRequestContext,\n ): Promise<{ clusters: ClusterDetails[] }> {\n if (\n entity.relations &&\n entity.relations.some(\n r => r.type === 'dependsOn' && r.targetRef.includes('resource:'),\n )\n ) {\n return this.clusterSupplier\n .getClusters({ credentials: requestContext.credentials })\n .then(clusters => {\n return {\n clusters: clusters.filter(c =>\n this.doesEntityDependOnCluster(entity, c),\n ),\n };\n });\n }\n return Promise.resolve({ clusters: [] });\n }\n\n protected doesEntityDependOnCluster(\n entity: Entity,\n cluster: ClusterDetails,\n ): boolean {\n return entity.relations!.some(\n rel =>\n rel.type === 'dependsOn' &&\n rel.targetRef ===\n `resource:${entity.metadata.namespace ?? 'default'}/${cluster.name}`,\n );\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n KubernetesServiceLocator,\n ServiceLocatorRequestContext,\n} from '../types/types';\n\n// This locator assumes that every service is located on every cluster\n// Therefore it will always return all clusters provided\nexport class MultiTenantServiceLocator implements KubernetesServiceLocator {\n private readonly clusterSupplier: KubernetesClustersSupplier;\n\n constructor(clusterSupplier: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n }\n\n // As this implementation always returns all clusters serviceId is ignored here\n getClustersByEntity(\n _entity: Entity,\n requestContext: ServiceLocatorRequestContext,\n ): Promise<{ clusters: ClusterDetails[] }> {\n return this.clusterSupplier\n .getClusters({ credentials: requestContext.credentials })\n .then(clusters => ({ clusters }));\n }\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n KubernetesServiceLocator,\n ServiceLocatorRequestContext,\n} from '../types/types';\n\n// This locator assumes that service is located on one cluster\n// Therefore it will always return specified cluster provided in backstage.io/kubernetes-cluster annotation\n// If backstage.io/kubernetes-cluster annotation not provided will always return all cluster provided\nexport class SingleTenantServiceLocator implements KubernetesServiceLocator {\n private readonly clusterSupplier: KubernetesClustersSupplier;\n\n constructor(clusterSupplier: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n }\n\n // As this implementation always returns all clusters serviceId is ignored here\n getClustersByEntity(\n _entity: Entity,\n requestContext: ServiceLocatorRequestContext,\n ): Promise<{ clusters: ClusterDetails[] }> {\n return this.clusterSupplier\n .getClusters({ credentials: requestContext.credentials })\n .then(clusters => {\n if (\n _entity.metadata?.annotations?.['backstage.io/kubernetes-cluster']\n ) {\n return {\n clusters: clusters.filter(\n c =>\n c.name ===\n _entity.metadata?.annotations?.[\n 'backstage.io/kubernetes-cluster'\n ],\n ),\n };\n }\n return { clusters };\n });\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { Logger } from 'winston';\nimport {\n KubernetesFetcher,\n KubernetesObjectsProviderOptions,\n KubernetesServiceLocator,\n ObjectsByEntityRequest,\n FetchResponseWrapper,\n ObjectToFetch,\n CustomResource,\n} from '../types/types';\nimport {\n ClientContainerStatus,\n ClientCurrentResourceUsage,\n ClientPodStatus,\n ClusterObjects,\n FetchResponse,\n ObjectsByEntityResponse,\n PodFetchResponse,\n KubernetesRequestAuth,\n CustomResourceMatcher,\n PodStatusFetchResponse,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n ContainerStatus,\n CurrentResourceUsage,\n PodStatus,\n} from '@kubernetes/client-node';\nimport {\n AuthenticationStrategy,\n ClusterDetails,\n CustomResourcesByEntity,\n KubernetesCredential,\n KubernetesObjectsByEntity,\n KubernetesObjectsProvider,\n} from '@backstage/plugin-kubernetes-node';\nimport { BackstageCredentials } from '@backstage/backend-plugin-api';\n\n/**\n *\n * @public\n */\nexport const DEFAULT_OBJECTS: ObjectToFetch[] = [\n {\n group: '',\n apiVersion: 'v1',\n plural: 'pods',\n objectType: 'pods',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'services',\n objectType: 'services',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'configmaps',\n objectType: 'configmaps',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'limitranges',\n objectType: 'limitranges',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'resourcequotas',\n objectType: 'resourcequotas',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'deployments',\n objectType: 'deployments',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'replicasets',\n objectType: 'replicasets',\n },\n {\n group: 'autoscaling',\n apiVersion: 'v1',\n plural: 'horizontalpodautoscalers',\n objectType: 'horizontalpodautoscalers',\n },\n {\n group: 'batch',\n apiVersion: 'v1',\n plural: 'jobs',\n objectType: 'jobs',\n },\n {\n group: 'batch',\n apiVersion: 'v1',\n plural: 'cronjobs',\n objectType: 'cronjobs',\n },\n {\n group: 'networking.k8s.io',\n apiVersion: 'v1',\n plural: 'ingresses',\n objectType: 'ingresses',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'statefulsets',\n objectType: 'statefulsets',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'daemonsets',\n objectType: 'daemonsets',\n },\n];\n\nexport interface KubernetesFanOutHandlerOptions\n extends KubernetesObjectsProviderOptions {\n authStrategy: AuthenticationStrategy;\n}\n\nexport interface KubernetesRequestBody extends ObjectsByEntityRequest {}\n\nconst isPodFetchResponse = (fr: FetchResponse): fr is PodFetchResponse =>\n fr.type === 'pods';\nconst isString = (str: string | undefined): str is string => str !== undefined;\n\nconst numberOrBigIntToNumberOrString = (\n value: number | BigInt,\n): number | string => {\n return typeof value === 'bigint' ? value.toString() : (value as number);\n};\n\nconst toClientSafeResource = (\n current: CurrentResourceUsage,\n): ClientCurrentResourceUsage => {\n return {\n currentUsage: numberOrBigIntToNumberOrString(current.CurrentUsage),\n requestTotal: numberOrBigIntToNumberOrString(current.RequestTotal),\n limitTotal: numberOrBigIntToNumberOrString(current.LimitTotal),\n };\n};\n\nconst toClientSafeContainer = (\n container: ContainerStatus,\n): ClientContainerStatus => {\n return {\n container: container.Container,\n cpuUsage: toClientSafeResource(container.CPUUsage),\n memoryUsage: toClientSafeResource(container.MemoryUsage),\n };\n};\n\nconst toClientSafePodMetrics = (\n podMetrics: PodStatusFetchResponse[],\n): ClientPodStatus[] => {\n return podMetrics\n .map(r => r.resources)\n .flat()\n .map((pd: PodStatus): ClientPodStatus => {\n return {\n pod: pd.Pod,\n memory: toClientSafeResource(pd.Memory),\n cpu: toClientSafeResource(pd.CPU),\n containers: pd.Containers.map(toClientSafeContainer),\n };\n });\n};\n\ntype responseWithMetrics = [FetchResponseWrapper, PodStatusFetchResponse[]];\n\nexport class KubernetesFanOutHandler implements KubernetesObjectsProvider {\n private readonly logger: Logger;\n private readonly fetcher: KubernetesFetcher;\n private readonly serviceLocator: KubernetesServiceLocator;\n private readonly customResources: CustomResource[];\n private readonly objectTypesToFetch: Set<ObjectToFetch>;\n private readonly authStrategy: AuthenticationStrategy;\n\n constructor({\n logger,\n fetcher,\n serviceLocator,\n customResources,\n objectTypesToFetch = DEFAULT_OBJECTS,\n authStrategy,\n }: KubernetesFanOutHandlerOptions) {\n this.logger = logger;\n this.fetcher = fetcher;\n this.serviceLocator = serviceLocator;\n this.customResources = customResources;\n this.objectTypesToFetch = new Set(objectTypesToFetch);\n this.authStrategy = authStrategy;\n }\n\n async getCustomResourcesByEntity(\n { entity, auth, customResources }: CustomResourcesByEntity,\n options: { credentials: BackstageCredentials },\n ): Promise<ObjectsByEntityResponse> {\n // Don't fetch the default object types only the provided custom resources\n return this.fanOutRequests(\n entity,\n auth,\n { credentials: options.credentials },\n new Set<ObjectToFetch>(),\n customResources,\n );\n }\n\n async getKubernetesObjectsByEntity(\n { entity, auth }: KubernetesObjectsByEntity,\n options: { credentials: BackstageCredentials },\n ): Promise<ObjectsByEntityResponse> {\n return this.fanOutRequests(\n entity,\n auth,\n {\n credentials: options.credentials,\n },\n this.objectTypesToFetch,\n );\n }\n\n private async fanOutRequests(\n entity: Entity,\n auth: KubernetesRequestAuth,\n options: { credentials: BackstageCredentials },\n objectTypesToFetch: Set<ObjectToFetch>,\n customResources?: CustomResourceMatcher[],\n ) {\n const entityName =\n entity.metadata?.annotations?.['backstage.io/kubernetes-id'] ||\n entity.metadata?.name;\n\n const { clusters } = await this.serviceLocator.getClustersByEntity(entity, {\n objectTypesToFetch: objectTypesToFetch,\n customResources: customResources ?? [],\n credentials: options.credentials,\n });\n\n this.logger.info(\n `entity.metadata.name=${entityName} clusterDetails=[${clusters\n .map(c => c.name)\n .join(', ')}]`,\n );\n\n const labelSelector: string =\n entity.metadata?.annotations?.[\n 'backstage.io/kubernetes-label-selector'\n ] || `backstage.io/kubernetes-id=${entityName}`;\n\n const namespace =\n entity.metadata?.annotations?.['backstage.io/kubernetes-namespace'];\n\n return Promise.all(\n clusters.map(async clusterDetails => {\n const credential = await this.authStrategy.getCredential(\n clusterDetails,\n auth,\n );\n return this.fetcher\n .fetchObjectsForService({\n serviceId: entityName,\n clusterDetails,\n credential,\n objectTypesToFetch,\n labelSelector,\n customResources: (\n customResources ||\n clusterDetails.customResources ||\n this.customResources\n ).map(c => ({\n ...c,\n objectType: 'customresources',\n })),\n namespace,\n })\n .then(result =>\n this.getMetricsForPods(\n clusterDetails,\n credential,\n labelSelector,\n result,\n ),\n )\n .catch(\n (e): Promise<responseWithMetrics> =>\n e.name === 'FetchError'\n ? Promise.resolve([\n {\n errors: [\n { errorType: 'FETCH_ERROR', message: e.message },\n ],\n responses: [],\n },\n [],\n ])\n : Promise.reject(e),\n )\n .then(r => this.toClusterObjects(clusterDetails, r));\n }),\n ).then(this.toObjectsByEntityResponse);\n }\n\n toObjectsByEntityResponse(\n clusterObjects: ClusterObjects[],\n ): ObjectsByEntityResponse {\n return {\n items: clusterObjects.filter(\n item =>\n (item.errors !== undefined && item.errors.length >= 1) ||\n (item.resources !== undefined &&\n item.resources.length >= 1 &&\n item.resources.some(fr => fr.resources?.length >= 1)),\n ),\n };\n }\n\n toClusterObjects(\n clusterDetails: ClusterDetails,\n [result, metrics]: responseWithMetrics,\n ): ClusterObjects {\n const objects: ClusterObjects = {\n cluster: {\n name: clusterDetails.name,\n ...(clusterDetails.title && { title: clusterDetails.title }),\n },\n podMetrics: toClientSafePodMetrics(metrics),\n resources: result.responses,\n errors: result.errors,\n };\n if (clusterDetails.dashboardUrl) {\n objects.cluster.dashboardUrl = clusterDetails.dashboardUrl;\n }\n if (clusterDetails.dashboardApp) {\n objects.cluster.dashboardApp = clusterDetails.dashboardApp;\n }\n if (clusterDetails.dashboardParameters) {\n objects.cluster.dashboardParameters = clusterDetails.dashboardParameters;\n }\n return objects;\n }\n\n async getMetricsForPods(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n labelSelector: string,\n result: FetchResponseWrapper,\n ): Promise<responseWithMetrics> {\n if (clusterDetails.skipMetricsLookup) {\n return [result, []];\n }\n const namespaces: Set<string> = new Set<string>(\n result.responses\n .filter(isPodFetchResponse)\n .flatMap(r => r.resources)\n .map(p => p.metadata?.namespace)\n .filter(isString),\n );\n\n if (namespaces.size === 0) {\n return [result, []];\n }\n\n const podMetrics = await this.fetcher.fetchPodMetricsByNamespaces(\n clusterDetails,\n credential,\n namespaces,\n labelSelector,\n );\n\n result.errors.push(...podMetrics.errors);\n return [result, podMetrics.responses as PodStatusFetchResponse[]];\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Config,\n Cluster,\n CoreV1Api,\n KubeConfig,\n Metrics,\n bufferFromFileOrString,\n topPods,\n} from '@kubernetes/client-node';\nimport lodash, { Dictionary } from 'lodash';\nimport { Logger } from 'winston';\nimport {\n FetchResponseWrapper,\n KubernetesFetcher,\n ObjectFetchParams,\n} from '../types/types';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n FetchResponse,\n KubernetesFetchError,\n KubernetesErrorTypes,\n PodStatusFetchResponse,\n} from '@backstage/plugin-kubernetes-common';\nimport fetch, { RequestInit, Response } from 'node-fetch';\nimport * as https from 'https';\nimport fs from 'fs-extra';\nimport { JsonObject } from '@backstage/types';\nimport {\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\nexport interface KubernetesClientBasedFetcherOptions {\n logger: Logger;\n}\n\ntype FetchResult = FetchResponse | KubernetesFetchError;\n\nconst isError = (fr: FetchResult): fr is KubernetesFetchError =>\n fr.hasOwnProperty('errorType');\n\nfunction fetchResultsToResponseWrapper(\n results: FetchResult[],\n): FetchResponseWrapper {\n const groupBy: Dictionary<FetchResult[]> = lodash.groupBy(results, value => {\n return isError(value) ? 'errors' : 'responses';\n });\n\n return {\n errors: groupBy.errors ?? [],\n responses: groupBy.responses ?? [],\n } as FetchResponseWrapper; // TODO would be nice to get rid of this 'as'\n}\n\nconst statusCodeToErrorType = (statusCode: number): KubernetesErrorTypes => {\n switch (statusCode) {\n case 400:\n return 'BAD_REQUEST';\n case 401:\n return 'UNAUTHORIZED_ERROR';\n case 404:\n return 'NOT_FOUND';\n case 500:\n return 'SYSTEM_ERROR';\n default:\n return 'UNKNOWN_ERROR';\n }\n};\n\nexport class KubernetesClientBasedFetcher implements KubernetesFetcher {\n private readonly logger: Logger;\n\n constructor({ logger }: KubernetesClientBasedFetcherOptions) {\n this.logger = logger;\n }\n\n fetchObjectsForService(\n params: ObjectFetchParams,\n ): Promise<FetchResponseWrapper> {\n const fetchResults = Array.from(params.objectTypesToFetch)\n .concat(params.customResources)\n .map(({ objectType, group, apiVersion, plural }) =>\n this.fetchResource(\n params.clusterDetails,\n params.credential,\n group,\n apiVersion,\n plural,\n params.namespace,\n params.labelSelector,\n ).then(\n (r: Response): Promise<FetchResult> =>\n r.ok\n ? r.json().then(\n ({ kind, items }): FetchResponse => ({\n type: objectType,\n resources:\n objectType === 'customresources'\n ? items.map((item: JsonObject) => ({\n ...item,\n kind: kind.replace(/(List)$/, ''),\n }))\n : items,\n }),\n )\n : this.handleUnsuccessfulResponse(params.clusterDetails.name, r),\n ),\n );\n\n return Promise.all(fetchResults).then(fetchResultsToResponseWrapper);\n }\n\n fetchPodMetricsByNamespaces(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n namespaces: Set<string>,\n labelSelector?: string,\n ): Promise<FetchResponseWrapper> {\n const fetchResults = Array.from(namespaces).map(async ns => {\n const [podMetrics, podList] = await Promise.all([\n this.fetchResource(\n clusterDetails,\n credential,\n 'metrics.k8s.io',\n 'v1beta1',\n 'pods',\n ns,\n labelSelector,\n ),\n this.fetchResource(\n clusterDetails,\n credential,\n '',\n 'v1',\n 'pods',\n ns,\n labelSelector,\n ),\n ]);\n if (podMetrics.ok && podList.ok) {\n return topPods(\n {\n listPodForAllNamespaces: () =>\n podList.json().then(b => ({ body: b })),\n } as unknown as CoreV1Api,\n {\n getPodMetrics: () => podMetrics.json(),\n } as unknown as Metrics,\n ).then(\n (resources): PodStatusFetchResponse => ({\n type: 'podstatus',\n resources,\n }),\n );\n } else if (podMetrics.ok) {\n return this.handleUnsuccessfulResponse(clusterDetails.name, podList);\n }\n return this.handleUnsuccessfulResponse(clusterDetails.name, podMetrics);\n });\n\n return Promise.all(fetchResults).then(fetchResultsToResponseWrapper);\n }\n\n private async handleUnsuccessfulResponse(\n clusterName: string,\n res: Response,\n ): Promise<KubernetesFetchError> {\n const resourcePath = new URL(res.url).pathname;\n this.logger.warn(\n `Received ${\n res.status\n } status when fetching \"${resourcePath}\" from cluster \"${clusterName}\"; body=[${await res.text()}]`,\n );\n return {\n errorType: statusCodeToErrorType(res.status),\n statusCode: res.status,\n resourcePath,\n };\n }\n\n private fetchResource(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n group: string,\n apiVersion: string,\n plural: string,\n namespace?: string,\n labelSelector?: string,\n ): Promise<Response> {\n const encode = (s: string) => encodeURIComponent(s);\n let resourcePath = group\n ? `/apis/${encode(group)}/${encode(apiVersion)}`\n : `/api/${encode(apiVersion)}`;\n if (namespace) {\n resourcePath += `/namespaces/${encode(namespace)}`;\n }\n resourcePath += `/${encode(plural)}`;\n\n let url: URL;\n let requestInit: RequestInit;\n const authProvider =\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n\n if (this.isServiceAccountAuthentication(authProvider, clusterDetails)) {\n [url, requestInit] = this.fetchArgsInCluster(credential);\n } else if (!this.isCredentialMissing(authProvider, credential)) {\n [url, requestInit] = this.fetchArgs(clusterDetails, credential);\n } else {\n return Promise.reject(\n new Error(\n `no bearer token or client cert for cluster '${clusterDetails.name}' and not running in Kubernetes`,\n ),\n );\n }\n\n if (url.pathname === '/') {\n url.pathname = resourcePath;\n } else {\n url.pathname += resourcePath;\n }\n\n if (labelSelector) {\n url.search = `labelSelector=${encode(labelSelector)}`;\n }\n\n return fetch(url, requestInit);\n }\n\n private isServiceAccountAuthentication(\n authProvider: string,\n clusterDetails: ClusterDetails,\n ) {\n return (\n authProvider === 'serviceAccount' &&\n !clusterDetails.authMetadata.serviceAccountToken &&\n fs.pathExistsSync(Config.SERVICEACCOUNT_CA_PATH)\n );\n }\n\n private isCredentialMissing(\n authProvider: string,\n credential: KubernetesCredential,\n ) {\n return (\n authProvider !== 'localKubectlProxy' && credential.type === 'anonymous'\n );\n }\n\n private fetchArgs(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n ): [URL, RequestInit] {\n const requestInit: RequestInit = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n ...(credential.type === 'bearer token' && {\n Authorization: `Bearer ${credential.token}`,\n }),\n },\n };\n\n const url: URL = new URL(clusterDetails.url);\n if (url.protocol === 'https:') {\n requestInit.agent = new https.Agent({\n ca:\n bufferFromFileOrString(\n clusterDetails.caFile,\n clusterDetails.caData,\n ) ?? undefined,\n rejectUnauthorized: !clusterDetails.skipTLSVerify,\n ...(credential.type === 'x509 client certificate' && {\n cert: credential.cert,\n key: credential.key,\n }),\n });\n }\n return [url, requestInit];\n }\n private fetchArgsInCluster(\n credential: KubernetesCredential,\n ): [URL, RequestInit] {\n const requestInit: RequestInit = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n ...(credential.type === 'bearer token' && {\n Authorization: `Bearer ${credential.token}`,\n }),\n },\n };\n\n const kc = new KubeConfig();\n kc.loadFromCluster();\n // loadFromCluster is guaranteed to populate the cluster/user/context\n const cluster = kc.getCurrentCluster() as Cluster;\n\n const url = new URL(cluster.server);\n if (url.protocol === 'https:') {\n requestInit.agent = new https.Agent({\n ca: fs.readFileSync(cluster.caFile as string),\n });\n }\n return [url, requestInit];\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ErrorResponseBody,\n ForwardedError,\n NotAllowedError,\n NotFoundError,\n serializeError,\n} from '@backstage/errors';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n KubernetesRequestAuth,\n kubernetesProxyPermission,\n} from '@backstage/plugin-kubernetes-common';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport {\n Cluster,\n KubeConfig,\n bufferFromFileOrString,\n} from '@kubernetes/client-node';\nimport { createProxyMiddleware, RequestHandler } from 'http-proxy-middleware';\nimport { Logger } from 'winston';\nimport fs from 'fs-extra';\nimport { Config } from '@kubernetes/client-node';\n\nimport { AuthenticationStrategy } from '../auth';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\n\nimport type { Request } from 'express';\nimport { IncomingHttpHeaders } from 'http';\nimport {\n DiscoveryService,\n HttpAuthService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { createLegacyAuthAdapters } from '@backstage/backend-common';\n\nexport const APPLICATION_JSON: string = 'application/json';\n\n/**\n * The header that is used to specify the cluster name.\n *\n * @public\n */\nexport const HEADER_KUBERNETES_CLUSTER: string = 'Backstage-Kubernetes-Cluster';\n\n/**\n * The header that is used to specify the Authentication Authorities token.\n * e.x if using the google auth provider as your authentication authority then this field would be the google provided bearer token.\n * @public\n */\nexport const HEADER_KUBERNETES_AUTH: string =\n 'Backstage-Kubernetes-Authorization';\n\n/**\n * The options object expected to be passed as a parameter to KubernetesProxy.createRequestHandler().\n *\n * @public\n */\nexport type KubernetesProxyCreateRequestHandlerOptions = {\n permissionApi: PermissionsService;\n};\n\n/**\n * Options accepted as a parameter by the KubernetesProxy\n *\n * @public\n */\nexport type KubernetesProxyOptions = {\n logger: Logger;\n clusterSupplier: KubernetesClustersSupplier;\n authStrategy: AuthenticationStrategy;\n discovery: DiscoveryService;\n httpAuth?: HttpAuthService;\n};\n\n/**\n * A proxy that routes requests to the Kubernetes API.\n *\n * @public\n */\nexport class KubernetesProxy {\n private readonly middlewareForClusterName = new Map<string, RequestHandler>();\n private readonly logger: Logger;\n private readonly clusterSupplier: KubernetesClustersSupplier;\n private readonly authStrategy: AuthenticationStrategy;\n private readonly httpAuth: HttpAuthService;\n\n constructor(options: KubernetesProxyOptions) {\n this.logger = options.logger;\n this.clusterSupplier = options.clusterSupplier;\n this.authStrategy = options.authStrategy;\n\n const legacy = createLegacyAuthAdapters({\n discovery: options.discovery,\n httpAuth: options.httpAuth,\n });\n\n this.httpAuth = legacy.httpAuth;\n }\n\n public createRequestHandler(\n options: KubernetesProxyCreateRequestHandlerOptions,\n ): RequestHandler {\n const { permissionApi } = options;\n return async (req, res, next) => {\n const authorizeResponse = await permissionApi.authorize(\n [{ permission: kubernetesProxyPermission }],\n {\n credentials: await this.httpAuth.credentials(req),\n },\n );\n const auth = authorizeResponse[0];\n\n if (auth.result === AuthorizeResult.DENY) {\n res.status(403).json({ error: new NotAllowedError('Unauthorized') });\n return;\n }\n\n const middleware = await this.getMiddleware(req);\n\n // If req is an upgrade handshake, use middleware upgrade instead of http request handler https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade\n if (\n req.header('connection')?.toLowerCase() === 'upgrade' &&\n req.header('upgrade')?.toLowerCase() === 'websocket'\n ) {\n // Missing the `head`, since it's optional we pass undefined to avoid type issues\n middleware.upgrade!(req, req.socket, undefined);\n } else {\n middleware(req, res, next);\n }\n };\n }\n\n // We create one middleware per remote cluster and hold on to them, because\n // the secure property isn't possible to decide on a per-request basis with a\n // single middleware instance - and we don't expect it to change over time.\n private async getMiddleware(originalReq: Request): Promise<RequestHandler> {\n const originalCluster = await this.getClusterForRequest(originalReq);\n let middleware = this.middlewareForClusterName.get(originalCluster.name);\n if (!middleware) {\n const logger = this.logger.child({ cluster: originalCluster.name });\n middleware = createProxyMiddleware({\n logProvider: () => logger,\n ws: true,\n secure: !originalCluster.skipTLSVerify,\n changeOrigin: true,\n pathRewrite: async (path, req) => {\n // Re-evaluate the cluster on each request, in case it has changed\n const cluster = await this.getClusterForRequest(req);\n const url = new URL(cluster.url);\n return path.replace(\n new RegExp(`^${originalReq.baseUrl}`),\n url.pathname || '',\n );\n },\n router: async req => {\n // Re-evaluate the cluster on each request, in case it has changed\n const cluster = await this.getClusterForRequest(req);\n const url = new URL(cluster.url);\n\n const target: any = {\n protocol: url.protocol,\n host: url.hostname,\n port: url.port,\n ca: bufferFromFileOrString(\n cluster.caFile,\n cluster.caData,\n )?.toString(),\n };\n\n const authHeader = req.header(HEADER_KUBERNETES_AUTH);\n if (authHeader) {\n req.headers.authorization = authHeader;\n } else {\n // Map Backstage-Kubernetes-Authorization-X-X headers to a KubernetesRequestAuth object\n const authObj = KubernetesProxy.authHeadersToKubernetesRequestAuth(\n req.headers,\n );\n\n const credential = await this.getClusterForRequest(req).then(cd => {\n return this.authStrategy.getCredential(cd, authObj);\n });\n\n if (credential.type === 'bearer token') {\n req.headers.authorization = `Bearer ${credential.token}`;\n } else if (credential.type === 'x509 client certificate') {\n target.key = credential.key;\n target.cert = credential.cert;\n }\n }\n\n return target;\n },\n onError: (error, req, res) => {\n const wrappedError = new ForwardedError(\n `Cluster '${originalCluster.name}' request error`,\n error,\n );\n\n logger.error(wrappedError);\n\n const body: ErrorResponseBody = {\n error: serializeError(wrappedError, {\n includeStack: process.env.NODE_ENV === 'development',\n }),\n request: { method: req.method, url: req.originalUrl },\n response: { statusCode: 500 },\n };\n res.status(500).json(body);\n },\n });\n this.middlewareForClusterName.set(originalCluster.name, middleware);\n }\n return middleware;\n }\n\n private async getClusterForRequest(req: Request): Promise<ClusterDetails> {\n const clusterName = req.headers[HEADER_KUBERNETES_CLUSTER.toLowerCase()];\n const clusters = await this.clusterSupplier.getClusters({\n credentials: await this.httpAuth.credentials(req),\n });\n\n if (!clusters || clusters.length <= 0) {\n throw new NotFoundError(`No Clusters configured`);\n }\n\n const hasClusterNameHeader =\n typeof clusterName === 'string' && clusterName.length > 0;\n\n let cluster: ClusterDetails | undefined;\n\n if (hasClusterNameHeader) {\n cluster = clusters.find(c => c.name === clusterName);\n } else if (clusters.length === 1) {\n cluster = clusters.at(0);\n }\n\n if (!cluster) {\n throw new NotFoundError(`Cluster '${clusterName}' not found`);\n }\n\n const authProvider =\n cluster.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n\n if (\n authProvider === 'serviceAccount' &&\n fs.pathExistsSync(Config.SERVICEACCOUNT_CA_PATH) &&\n !cluster.authMetadata.serviceAccountToken\n ) {\n const kc = new KubeConfig();\n kc.loadFromCluster();\n const clusterFromKubeConfig = kc.getCurrentCluster() as Cluster;\n\n const url = new URL(clusterFromKubeConfig.server);\n cluster.url = clusterFromKubeConfig.server;\n if (url.protocol === 'https:') {\n cluster.caFile = clusterFromKubeConfig.caFile;\n }\n }\n\n return cluster;\n }\n\n private static authHeadersToKubernetesRequestAuth(\n originalHeaders: IncomingHttpHeaders,\n ): KubernetesRequestAuth {\n return Object.keys(originalHeaders)\n .filter(header => header.startsWith('backstage-kubernetes-authorization'))\n .map(header =>\n KubernetesProxy.headerToDictionary(header, originalHeaders),\n )\n .filter(headerAsDic => Object.keys(headerAsDic).length !== 0)\n .reduce(KubernetesProxy.combineHeaders, {});\n }\n\n private static headerToDictionary(\n header: string,\n originalHeaders: IncomingHttpHeaders,\n ): KubernetesRequestAuth {\n const obj: KubernetesRequestAuth = {};\n const headerSplitted = header.split('-');\n if (headerSplitted.length >= 4) {\n const framework = headerSplitted[3].toLowerCase();\n if (headerSplitted.length >= 5) {\n const provider = headerSplitted.slice(4).join('-').toLowerCase();\n obj[framework] = { [provider]: originalHeaders[header] };\n } else {\n obj[framework] = originalHeaders[header];\n }\n }\n return obj;\n }\n\n private static combineHeaders(\n authObj: any,\n header: any,\n ): KubernetesRequestAuth {\n const framework = Object.keys(header)[0];\n\n if (authObj[framework]) {\n authObj[framework] = {\n ...authObj[framework],\n ...header[framework],\n };\n } else {\n authObj[framework] = header[framework];\n }\n\n return authObj;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,\n kubernetesPermissions,\n} from '@backstage/plugin-kubernetes-common';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Duration } from 'luxon';\nimport { Logger } from 'winston';\n\nimport {\n AksStrategy,\n AnonymousStrategy,\n AwsIamStrategy,\n AzureIdentityStrategy,\n DispatchStrategy,\n GoogleServiceAccountStrategy,\n GoogleStrategy,\n OidcStrategy,\n ServiceAccountStrategy,\n} from '../auth';\nimport { getCombinedClusterSupplier } from '../cluster-locator';\n\nimport { createLegacyAuthAdapters } from '@backstage/backend-common';\nimport {\n AuthService,\n BackstageCredentials,\n DiscoveryService,\n HttpAuthService,\n} from '@backstage/backend-plugin-api';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n CustomResource,\n KubernetesClustersSupplier,\n KubernetesFetcher,\n KubernetesObjectTypes,\n KubernetesObjectsProvider,\n KubernetesServiceLocator,\n} from '@backstage/plugin-kubernetes-node';\nimport { addResourceRoutesToRouter } from '../routes/resourcesRoutes';\nimport { CatalogRelationServiceLocator } from '../service-locator/CatalogRelationServiceLocator';\nimport { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator';\nimport { SingleTenantServiceLocator } from '../service-locator/SingleTenantServiceLocator';\nimport {\n KubernetesObjectsProviderOptions,\n ObjectsByEntityRequest,\n ServiceLocatorMethod,\n} from '../types/types';\nimport {\n DEFAULT_OBJECTS,\n KubernetesFanOutHandler,\n} from './KubernetesFanOutHandler';\nimport { KubernetesClientBasedFetcher } from './KubernetesFetcher';\nimport { KubernetesProxy } from './KubernetesProxy';\n\n/**\n *\n * @public\n */\nexport interface KubernetesEnvironment {\n logger: Logger;\n config: Config;\n catalogApi: CatalogApi;\n discovery: DiscoveryService;\n permissions: PermissionEvaluator;\n auth?: AuthService;\n httpAuth?: HttpAuthService;\n}\n\n/**\n * The return type of the `KubernetesBuilder.build` method\n *\n * @public\n */\nexport type KubernetesBuilderReturn = Promise<{\n router: express.Router;\n clusterSupplier: KubernetesClustersSupplier;\n customResources: CustomResource[];\n fetcher: KubernetesFetcher;\n proxy: KubernetesProxy;\n objectsProvider: KubernetesObjectsProvider;\n serviceLocator: KubernetesServiceLocator;\n authStrategyMap: { [key: string]: AuthenticationStrategy };\n}>;\n\n/**\n *\n * @public\n */\nexport class KubernetesBuilder {\n private clusterSupplier?: KubernetesClustersSupplier;\n private defaultClusterRefreshInterval: Duration = Duration.fromObject({\n minutes: 60,\n });\n private objectsProvider?: KubernetesObjectsProvider;\n private fetcher?: KubernetesFetcher;\n private serviceLocator?: KubernetesServiceLocator;\n private proxy?: KubernetesProxy;\n private authStrategyMap?: { [key: string]: AuthenticationStrategy };\n\n static createBuilder(env: KubernetesEnvironment) {\n return new KubernetesBuilder(env);\n }\n\n constructor(protected readonly env: KubernetesEnvironment) {}\n\n public async build(): KubernetesBuilderReturn {\n const logger = this.env.logger;\n const config = this.env.config;\n const permissions = this.env.permissions;\n\n logger.info('Initializing Kubernetes backend');\n\n if (!config.has('kubernetes')) {\n if (process.env.NODE_ENV !== 'development') {\n throw new Error('Kubernetes configuration is missing');\n }\n logger.warn(\n 'Failed to initialize kubernetes backend: kubernetes config is missing',\n );\n return {\n router: Router(),\n } as unknown as KubernetesBuilderReturn;\n }\n\n const { auth, httpAuth } = createLegacyAuthAdapters({\n auth: this.env.auth,\n httpAuth: this.env.httpAuth,\n discovery: this.env.discovery,\n });\n\n const customResources = this.buildCustomResources();\n\n const fetcher = this.getFetcher();\n\n const clusterSupplier = this.getClusterSupplier();\n\n const authStrategyMap = this.getAuthStrategyMap();\n\n const proxy = this.getProxy(\n logger,\n clusterSupplier,\n this.env.discovery,\n httpAuth,\n );\n\n const serviceLocator = this.getServiceLocator();\n\n const objectsProvider = this.getObjectsProvider({\n logger,\n fetcher,\n config,\n serviceLocator,\n customResources,\n objectTypesToFetch: this.getObjectTypesToFetch(),\n });\n\n const router = this.buildRouter(\n objectsProvider,\n clusterSupplier,\n this.env.catalogApi,\n proxy,\n permissions,\n auth,\n httpAuth,\n );\n\n return {\n clusterSupplier,\n customResources,\n fetcher,\n proxy,\n objectsProvider,\n router,\n serviceLocator,\n authStrategyMap,\n };\n }\n\n public setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n return this;\n }\n\n public setDefaultClusterRefreshInterval(refreshInterval: Duration) {\n this.defaultClusterRefreshInterval = refreshInterval;\n return this;\n }\n\n public setObjectsProvider(objectsProvider?: KubernetesObjectsProvider) {\n this.objectsProvider = objectsProvider;\n return this;\n }\n\n public setFetcher(fetcher?: KubernetesFetcher) {\n this.fetcher = fetcher;\n return this;\n }\n\n public setServiceLocator(serviceLocator?: KubernetesServiceLocator) {\n this.serviceLocator = serviceLocator;\n return this;\n }\n\n public setProxy(proxy?: KubernetesProxy) {\n this.proxy = proxy;\n return this;\n }\n\n public setAuthStrategyMap(authStrategyMap: {\n [key: string]: AuthenticationStrategy;\n }) {\n this.authStrategyMap = authStrategyMap;\n }\n\n public addAuthStrategy(key: string, strategy: AuthenticationStrategy) {\n if (key.includes('-')) {\n throw new Error('Strategy name can not include dashes');\n }\n this.getAuthStrategyMap()[key] = strategy;\n return this;\n }\n\n protected buildCustomResources() {\n const customResources: CustomResource[] = (\n this.env.config.getOptionalConfigArray('kubernetes.customResources') ?? []\n ).map(\n c =>\n ({\n group: c.getString('group'),\n apiVersion: c.getString('apiVersion'),\n plural: c.getString('plural'),\n objectType: 'customresources',\n } as CustomResource),\n );\n\n this.env.logger.info(\n `action=LoadingCustomResources numOfCustomResources=${customResources.length}`,\n );\n return customResources;\n }\n\n protected buildClusterSupplier(\n refreshInterval: Duration,\n ): KubernetesClustersSupplier {\n const config = this.env.config;\n const { auth } = createLegacyAuthAdapters(this.env);\n this.clusterSupplier = getCombinedClusterSupplier(\n config,\n this.env.catalogApi,\n new DispatchStrategy({ authStrategyMap: this.getAuthStrategyMap() }),\n this.env.logger,\n refreshInterval,\n auth,\n );\n\n return this.clusterSupplier;\n }\n\n protected buildObjectsProvider(\n options: KubernetesObjectsProviderOptions,\n ): KubernetesObjectsProvider {\n const authStrategyMap = this.getAuthStrategyMap();\n this.objectsProvider = new KubernetesFanOutHandler({\n ...options,\n authStrategy: new DispatchStrategy({\n authStrategyMap,\n }),\n });\n\n return this.objectsProvider;\n }\n\n protected buildFetcher(): KubernetesFetcher {\n this.fetcher = new KubernetesClientBasedFetcher({\n logger: this.env.logger,\n });\n\n return this.fetcher;\n }\n\n protected buildServiceLocator(\n method: ServiceLocatorMethod,\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n switch (method) {\n case 'multiTenant':\n this.serviceLocator =\n this.buildMultiTenantServiceLocator(clusterSupplier);\n break;\n case 'singleTenant':\n this.serviceLocator =\n this.buildSingleTenantServiceLocator(clusterSupplier);\n break;\n case 'catalogRelation':\n this.serviceLocator =\n this.buildCatalogRelationServiceLocator(clusterSupplier);\n break;\n case 'http':\n this.serviceLocator = this.buildHttpServiceLocator(clusterSupplier);\n break;\n default:\n throw new Error(\n `Unsupported kubernetes.serviceLocatorMethod \"${method}\"`,\n );\n }\n\n return this.serviceLocator;\n }\n\n protected buildMultiTenantServiceLocator(\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n return new MultiTenantServiceLocator(clusterSupplier);\n }\n\n protected buildSingleTenantServiceLocator(\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n return new SingleTenantServiceLocator(clusterSupplier);\n }\n\n protected buildCatalogRelationServiceLocator(\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n return new CatalogRelationServiceLocator(clusterSupplier);\n }\n\n protected buildHttpServiceLocator(\n _clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n throw new Error('not implemented');\n }\n\n protected buildProxy(\n logger: Logger,\n clusterSupplier: KubernetesClustersSupplier,\n discovery: DiscoveryService,\n httpAuth: HttpAuthService,\n ): KubernetesProxy {\n const authStrategyMap = this.getAuthStrategyMap();\n const authStrategy = new DispatchStrategy({\n authStrategyMap,\n });\n this.proxy = new KubernetesProxy({\n logger,\n clusterSupplier,\n authStrategy,\n discovery,\n httpAuth,\n });\n return this.proxy;\n }\n\n protected buildRouter(\n objectsProvider: KubernetesObjectsProvider,\n clusterSupplier: KubernetesClustersSupplier,\n catalogApi: CatalogApi,\n proxy: KubernetesProxy,\n permissionApi: PermissionEvaluator,\n authService: AuthService,\n httpAuth: HttpAuthService,\n ): express.Router {\n const logger = this.env.logger;\n const router = Router();\n router.use('/proxy', proxy.createRequestHandler({ permissionApi }));\n router.use(express.json());\n router.use(\n createPermissionIntegrationRouter({\n permissions: kubernetesPermissions,\n }),\n );\n // @deprecated\n router.post('/services/:serviceId', async (req, res) => {\n const serviceId = req.params.serviceId;\n const requestBody: ObjectsByEntityRequest = req.body;\n try {\n const response = await objectsProvider.getKubernetesObjectsByEntity(\n {\n entity: requestBody.entity,\n auth: requestBody.auth || {},\n },\n { credentials: await httpAuth.credentials(req) },\n );\n res.json(response);\n } catch (e) {\n logger.error(\n `action=retrieveObjectsByServiceId service=${serviceId}, error=${e}`,\n );\n res.status(500).json({ error: e.message });\n }\n });\n\n router.get('/clusters', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const clusterDetails = await this.fetchClusterDetails(clusterSupplier, {\n credentials,\n });\n res.json({\n items: clusterDetails.map(cd => {\n const oidcTokenProvider =\n cd.authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];\n const authProvider =\n cd.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n const strategy = this.getAuthStrategyMap()[authProvider];\n let auth: AuthMetadata = {};\n if (strategy) {\n auth = strategy.presentAuthMetadata(cd.authMetadata);\n }\n\n return {\n name: cd.name,\n title: cd.title,\n dashboardUrl: cd.dashboardUrl,\n authProvider,\n ...(oidcTokenProvider && { oidcTokenProvider }),\n ...(auth && Object.keys(auth).length !== 0 && { auth }),\n };\n }),\n });\n });\n\n addResourceRoutesToRouter(\n router,\n catalogApi,\n objectsProvider,\n authService,\n httpAuth,\n );\n\n return router;\n }\n\n protected buildAuthStrategyMap() {\n this.authStrategyMap = {\n aks: new AksStrategy(),\n aws: new AwsIamStrategy({ config: this.env.config }),\n azure: new AzureIdentityStrategy(this.env.logger),\n google: new GoogleStrategy(),\n googleServiceAccount: new GoogleServiceAccountStrategy(),\n localKubectlProxy: new AnonymousStrategy(),\n oidc: new OidcStrategy(),\n serviceAccount: new ServiceAccountStrategy(),\n };\n return this.authStrategyMap;\n }\n\n protected async fetchClusterDetails(\n clusterSupplier: KubernetesClustersSupplier,\n options: { credentials: BackstageCredentials },\n ) {\n const clusterDetails = await clusterSupplier.getClusters(options);\n\n this.env.logger.info(\n `action=loadClusterDetails numOfClustersLoaded=${clusterDetails.length}`,\n );\n\n return clusterDetails;\n }\n\n protected getServiceLocatorMethod() {\n return this.env.config.getString(\n 'kubernetes.serviceLocatorMethod.type',\n ) as ServiceLocatorMethod;\n }\n\n protected getFetcher(): KubernetesFetcher {\n return this.fetcher ?? this.buildFetcher();\n }\n\n protected getClusterSupplier() {\n return (\n this.clusterSupplier ??\n this.buildClusterSupplier(this.defaultClusterRefreshInterval)\n );\n }\n\n protected getServiceLocator(): KubernetesServiceLocator {\n return (\n this.serviceLocator ??\n this.buildServiceLocator(\n this.getServiceLocatorMethod(),\n this.getClusterSupplier(),\n )\n );\n }\n\n protected getObjectsProvider(options: KubernetesObjectsProviderOptions) {\n return this.objectsProvider ?? this.buildObjectsProvider(options);\n }\n\n protected getObjectTypesToFetch() {\n const objectTypesToFetchStrings = this.env.config.getOptionalStringArray(\n 'kubernetes.objectTypes',\n ) as KubernetesObjectTypes[];\n\n const apiVersionOverrides = this.env.config.getOptionalConfig(\n 'kubernetes.apiVersionOverrides',\n );\n\n let objectTypesToFetch;\n\n if (objectTypesToFetchStrings) {\n objectTypesToFetch = DEFAULT_OBJECTS.filter(obj =>\n objectTypesToFetchStrings.includes(obj.objectType),\n );\n }\n\n if (apiVersionOverrides) {\n objectTypesToFetch = objectTypesToFetch ?? DEFAULT_OBJECTS;\n\n for (const obj of objectTypesToFetch) {\n if (apiVersionOverrides.has(obj.objectType)) {\n obj.apiVersion = apiVersionOverrides.getString(obj.objectType);\n }\n }\n }\n\n return objectTypesToFetch;\n }\n\n protected getProxy(\n logger: Logger,\n clusterSupplier: KubernetesClustersSupplier,\n discovery: DiscoveryService,\n httpAuth: HttpAuthService,\n ) {\n return (\n this.proxy ??\n this.buildProxy(logger, clusterSupplier, discovery, httpAuth)\n );\n }\n\n protected getAuthStrategyMap() {\n return this.authStrategyMap ?? this.buildAuthStrategyMap();\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { Logger } from 'winston';\nimport { KubernetesClustersSupplier } from '../types/types';\nimport express from 'express';\nimport { KubernetesBuilder } from './KubernetesBuilder';\nimport { PluginEndpointDiscovery } from '@backstage/backend-common';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\n\n/**\n *\n * @public\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n catalogApi: CatalogApi;\n clusterSupplier?: KubernetesClustersSupplier;\n discovery: PluginEndpointDiscovery;\n permissions: PermissionEvaluator;\n}\n\n/**\n * creates and configure a new router for handling the kubernetes backend APIs\n * @param options - specifies the options required by this plugin\n * @returns a new router\n * @deprecated Please use the new KubernetesBuilder instead like this\n * ```\n * import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';\n * const { router } = await KubernetesBuilder.createBuilder({\n * logger,\n * config,\n * }).build();\n * ```\n *\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { router } = await KubernetesBuilder.createBuilder(options)\n .setClusterSupplier(options.clusterSupplier)\n .build();\n return router;\n}\n"],"names":["__publicField","DefaultAwsCredentialsManager","ANNOTATION_KUBERNETES_AWS_CLUSTER_ID","ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE","ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID","fromTemporaryCredentials","SignatureV4","Sha256","_a","DefaultAzureCredential","container","ANNOTATION_KUBERNETES_AUTH_PROVIDER","KubeConfig","fs","ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER","ForwardedError","ANNOTATION_KUBERNETES_API_SERVER","ANNOTATION_KUBERNETES_API_SERVER_CA","CATALOG_FILTER_EXISTS","ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP","ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY","ANNOTATION_KUBERNETES_DASHBOARD_URL","ANNOTATION_KUBERNETES_DASHBOARD_APP","ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS","dns","InputError","parseEntityRef","stringifyEntityRef","_b","lodash","topPods","fetch","Config","https","bufferFromFileOrString","createLegacyAuthAdapters","kubernetesProxyPermission","AuthorizeResult","NotAllowedError","createProxyMiddleware","serializeError","NotFoundError","Duration","Router","express","createPermissionIntegrationRouter","kubernetesPermissions"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/auth/AksStrategy.ts","../src/auth/AnonymousStrategy.ts","../src/auth/AwsIamStrategy.ts","../src/auth/AzureIdentityStrategy.ts","../src/auth/GoogleStrategy.ts","../src/auth/GoogleServiceAccountStrategy.ts","../src/auth/DispatchStrategy.ts","../src/auth/ServiceAccountStrategy.ts","../src/auth/OidcStrategy.ts","../src/cluster-locator/ConfigClusterLocator.ts","../src/service/runPeriodically.ts","../src/cluster-locator/GkeClusterLocator.ts","../src/cluster-locator/CatalogClusterLocator.ts","../src/cluster-locator/LocalKubectlProxyLocator.ts","../src/cluster-locator/index.ts","../src/routes/resourcesRoutes.ts","../src/service-locator/CatalogRelationServiceLocator.ts","../src/service-locator/MultiTenantServiceLocator.ts","../src/service-locator/SingleTenantServiceLocator.ts","../src/service/KubernetesFanOutHandler.ts","../src/service/KubernetesFetcher.ts","../src/service/KubernetesProxy.ts","../src/service/KubernetesBuilder.ts","../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';\n\n/**\n *\n * @public\n */\nexport class AksStrategy implements AuthenticationStrategy {\n public async getCredential(\n _: ClusterDetails,\n requestAuth: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const token = requestAuth.aks;\n return token\n ? { type: 'bearer token', token: token as string }\n : { type: 'anonymous' };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport class AnonymousStrategy implements AuthenticationStrategy {\n public async getCredential(): Promise<KubernetesCredential> {\n return { type: 'anonymous' };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { fromTemporaryCredentials } from '@aws-sdk/credential-providers';\nimport { SignatureV4 } from '@aws-sdk/signature-v4';\nimport { Sha256 } from '@aws-crypto/sha256-js';\nimport {\n AwsCredentialsManager,\n DefaultAwsCredentialsManager,\n} from '@backstage/integration-aws-node';\nimport { Config } from '@backstage/config';\nimport {\n ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,\n ANNOTATION_KUBERNETES_AWS_CLUSTER_ID,\n ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport type SigningCreds = {\n accessKeyId: string | undefined;\n secretAccessKey: string | undefined;\n sessionToken: string | undefined;\n};\n\nconst defaultRegion = 'us-east-1';\n\n/**\n *\n * @public\n */\nexport class AwsIamStrategy implements AuthenticationStrategy {\n private readonly credsManager: AwsCredentialsManager;\n\n constructor(opts: { config: Config }) {\n this.credsManager = DefaultAwsCredentialsManager.fromConfig(opts.config);\n }\n\n public async getCredential(\n clusterDetails: ClusterDetails,\n ): Promise<KubernetesCredential> {\n return {\n type: 'bearer token',\n token: await this.getBearerToken(\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_CLUSTER_ID] ??\n clusterDetails.name,\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE],\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID],\n ),\n };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n private async getBearerToken(\n clusterId: string,\n assumeRole?: string,\n externalId?: string,\n ): Promise<string> {\n const region = process.env.AWS_REGION ?? defaultRegion;\n\n let credentials = (await this.credsManager.getCredentialProvider())\n .sdkCredentialProvider;\n if (assumeRole) {\n credentials = fromTemporaryCredentials({\n masterCredentials: credentials,\n clientConfig: {\n region,\n },\n params: {\n RoleArn: assumeRole,\n ExternalId: externalId,\n },\n });\n }\n\n const signer = new SignatureV4({\n credentials,\n region,\n service: 'sts',\n sha256: Sha256,\n });\n\n const request = await signer.presign(\n {\n headers: {\n host: `sts.${region}.amazonaws.com`,\n 'x-k8s-aws-id': clusterId,\n },\n hostname: `sts.${region}.amazonaws.com`,\n method: 'GET',\n path: '/',\n protocol: 'https:',\n query: {\n Action: 'GetCallerIdentity',\n Version: '2011-06-15',\n },\n },\n { expiresIn: 0 },\n );\n\n const query = Object.keys(request?.query ?? {})\n .map(\n q =>\n `${encodeURIComponent(q)}=${encodeURIComponent(\n request.query?.[q] as string,\n )}`,\n )\n .join('&');\n\n const url = `https://${request.hostname}${request.path}?${query}`;\n\n return `k8s-aws-v1.${Buffer.from(url).toString('base64url')}`;\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AccessToken,\n DefaultAzureCredential,\n TokenCredential,\n} from '@azure/identity';\nimport {\n AuthenticationStrategy,\n AuthMetadata,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nconst aksScope = '6dae42f8-4368-4678-94ff-3960e28e3630/.default'; // This scope is the same for all Azure Managed Kubernetes\n\n/**\n *\n * @public\n */\nexport class AzureIdentityStrategy implements AuthenticationStrategy {\n private accessToken: AccessToken = { token: '', expiresOnTimestamp: 0 };\n private newTokenPromise: Promise<string> | undefined;\n\n constructor(\n private readonly logger: LoggerService,\n private readonly tokenCredential: TokenCredential = new DefaultAzureCredential(),\n ) {}\n\n public async getCredential(): Promise<KubernetesCredential> {\n if (!this.tokenRequiresRefresh()) {\n return { type: 'bearer token', token: this.accessToken.token };\n }\n\n if (!this.newTokenPromise) {\n this.newTokenPromise = this.fetchNewToken();\n }\n\n return this.newTokenPromise\n ? { type: 'bearer token', token: await this.newTokenPromise }\n : { type: 'anonymous' };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n private async fetchNewToken(): Promise<string> {\n try {\n this.logger.info('Fetching new Azure token for AKS');\n\n const newAccessToken = await this.tokenCredential.getToken(aksScope, {\n requestOptions: { timeout: 10_000 }, // 10 seconds\n });\n if (!newAccessToken) {\n throw new Error('AccessToken is null');\n }\n\n this.accessToken = newAccessToken;\n } catch (err) {\n this.logger.error('Unable to fetch Azure token', err);\n\n // only throw the error if the token has already expired, otherwise re-use existing until we're able to fetch a new token\n if (this.tokenExpired()) {\n throw err;\n }\n }\n\n this.newTokenPromise = undefined;\n return this.accessToken.token;\n }\n\n private tokenRequiresRefresh(): boolean {\n // Set tokens to expire 15 minutes before its actual expiry time\n const expiresOn = this.accessToken.expiresOnTimestamp - 15 * 60 * 1000;\n return Date.now() >= expiresOn;\n }\n\n private tokenExpired(): boolean {\n return Date.now() >= this.accessToken.expiresOnTimestamp;\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport class GoogleStrategy implements AuthenticationStrategy {\n public async getCredential(\n _: ClusterDetails,\n requestAuth: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const token = requestAuth.google;\n if (!token) {\n throw new Error(\n 'Google token not found under auth.google in request body',\n );\n }\n return { type: 'bearer token', token: token as string };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport * as container from '@google-cloud/container';\n\n/**\n *\n * @public\n */\nexport class GoogleServiceAccountStrategy implements AuthenticationStrategy {\n public async getCredential(): Promise<KubernetesCredential> {\n const client = new container.v1.ClusterManagerClient();\n const token = await client.auth.getAccessToken();\n\n if (!token) {\n throw new Error(\n 'Unable to obtain access token for the current Google Application Default Credentials',\n );\n }\n return { type: 'bearer token', token };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n KubernetesRequestAuth,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport type DispatchStrategyOptions = {\n authStrategyMap: {\n [key: string]: AuthenticationStrategy;\n };\n};\n/**\n * used to direct a KubernetesAuthProvider to its corresponding AuthenticationStrategy\n * @public\n */\nexport class DispatchStrategy implements AuthenticationStrategy {\n private readonly strategyMap: { [key: string]: AuthenticationStrategy };\n\n constructor(options: DispatchStrategyOptions) {\n this.strategyMap = options.authStrategyMap;\n }\n\n public getCredential(\n clusterDetails: ClusterDetails,\n auth: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const authProvider =\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n if (this.strategyMap[authProvider]) {\n return this.strategyMap[authProvider].getCredential(clusterDetails, auth);\n }\n throw new Error(\n `authProvider \"${authProvider}\" has no AuthenticationStrategy associated with it`,\n );\n }\n\n public validateCluster(authMetadata: AuthMetadata): Error[] {\n const authProvider = authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n const strategy = this.strategyMap[authProvider];\n if (!strategy) {\n return [\n new Error(\n `authProvider \"${authProvider}\" has no config associated with it`,\n ),\n ];\n }\n return strategy.validateCluster(authMetadata);\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport { KubeConfig, User } from '@kubernetes/client-node';\nimport fs from 'fs-extra';\n\n/**\n *\n * @public\n */\nexport class ServiceAccountStrategy implements AuthenticationStrategy {\n public async getCredential(\n clusterDetails: ClusterDetails,\n ): Promise<KubernetesCredential> {\n const token = clusterDetails.authMetadata.serviceAccountToken;\n if (token) {\n return { type: 'bearer token', token };\n }\n const kc = new KubeConfig();\n kc.loadFromCluster();\n // loadFromCluster is guaranteed to populate the user\n const user = kc.getCurrentUser() as User;\n\n return {\n type: 'bearer token',\n token: fs.readFileSync(user.authProvider.config.tokenFile).toString(),\n };\n }\n\n public validateCluster(): Error[] {\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { JsonObject } from '@backstage/types';\nimport {\n ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,\n KubernetesRequestAuth,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n AuthMetadata,\n AuthenticationStrategy,\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\n\n/**\n *\n * @public\n */\nexport class OidcStrategy implements AuthenticationStrategy {\n public async getCredential(\n clusterDetails: ClusterDetails,\n authConfig: KubernetesRequestAuth,\n ): Promise<KubernetesCredential> {\n const oidcTokenProvider =\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];\n\n if (!oidcTokenProvider || oidcTokenProvider === '') {\n throw new Error(\n `oidc authProvider requires a configured oidcTokenProvider`,\n );\n }\n\n const token = (authConfig.oidc as JsonObject | null)?.[oidcTokenProvider];\n\n if (!token) {\n throw new Error(\n `Auth token not found under oidc.${oidcTokenProvider} in request body`,\n );\n }\n return { type: 'bearer token', token: token as string };\n }\n\n public validateCluster(authMetadata: AuthMetadata): Error[] {\n const oidcTokenProvider =\n authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];\n if (!oidcTokenProvider || oidcTokenProvider === '') {\n return [new Error(`Must specify a token provider for 'oidc' strategy`)];\n }\n return [];\n }\n\n public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata {\n return {};\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE,\n ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID,\n ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,\n} from '@backstage/plugin-kubernetes-common';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport { AuthenticationStrategy } from '../auth';\n\nexport class ConfigClusterLocator implements KubernetesClustersSupplier {\n private readonly clusterDetails: ClusterDetails[];\n\n constructor(clusterDetails: ClusterDetails[]) {\n this.clusterDetails = clusterDetails;\n }\n\n static fromConfig(\n config: Config,\n authStrategy: AuthenticationStrategy,\n ): ConfigClusterLocator {\n const clusterNames = new Set();\n return new ConfigClusterLocator(\n config.getConfigArray('clusters').map(c => {\n const authMetadataBlock = c.getOptional<{\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]?: string;\n }>('authMetadata');\n const name = c.getString('name');\n if (clusterNames.has(name)) {\n throw new Error(`Duplicate cluster name '${name}'`);\n }\n clusterNames.add(name);\n const authProvider =\n authMetadataBlock?.[ANNOTATION_KUBERNETES_AUTH_PROVIDER] ??\n c.getOptionalString('authProvider');\n if (!authProvider) {\n throw new Error(\n `cluster '${name}' has no auth provider configured; this must be ` +\n `specified via the 'authProvider' or ` +\n `'authMetadata.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}' parameter`,\n );\n }\n const title = c.getOptionalString('title');\n const clusterDetails: ClusterDetails = {\n name,\n ...(title && { title }),\n url: c.getString('url'),\n skipTLSVerify: c.getOptionalBoolean('skipTLSVerify') ?? false,\n skipMetricsLookup: c.getOptionalBoolean('skipMetricsLookup') ?? false,\n caData: c.getOptionalString('caData'),\n caFile: c.getOptionalString('caFile'),\n authMetadata: {\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider,\n ...ConfigClusterLocator.parseAuthMetadata(c),\n ...authMetadataBlock,\n },\n };\n\n const customResources = c.getOptionalConfigArray('customResources');\n if (customResources) {\n clusterDetails.customResources = customResources.map(cr => {\n return {\n group: cr.getString('group'),\n apiVersion: cr.getString('apiVersion'),\n plural: cr.getString('plural'),\n };\n });\n }\n\n const dashboardUrl = c.getOptionalString('dashboardUrl');\n if (dashboardUrl) {\n clusterDetails.dashboardUrl = dashboardUrl;\n }\n const dashboardApp = c.getOptionalString('dashboardApp');\n if (dashboardApp) {\n clusterDetails.dashboardApp = dashboardApp;\n }\n if (c.has('dashboardParameters')) {\n clusterDetails.dashboardParameters = c.get('dashboardParameters');\n }\n\n const validationErrors = authStrategy.validateCluster(\n clusterDetails.authMetadata,\n );\n if (validationErrors.length !== 0) {\n throw new Error(\n `Invalid cluster '${clusterDetails.name}': ${validationErrors\n .map(e => e.message)\n .join(', ')}`,\n );\n }\n return clusterDetails;\n }),\n );\n }\n\n private static parseAuthMetadata(\n clusterConfig: Config,\n ): Record<string, string> | undefined {\n const serviceAccountToken = clusterConfig.getOptionalString(\n 'serviceAccountToken',\n );\n const assumeRole = clusterConfig.getOptionalString('assumeRole');\n const externalId = clusterConfig.getOptionalString('externalId');\n const oidcTokenProvider =\n clusterConfig.getOptionalString('oidcTokenProvider');\n\n return serviceAccountToken || assumeRole || externalId || oidcTokenProvider\n ? {\n ...(serviceAccountToken && { serviceAccountToken }),\n ...(assumeRole && {\n [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: assumeRole,\n }),\n ...(externalId && {\n [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: externalId,\n }),\n ...(oidcTokenProvider && {\n [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: oidcTokenProvider,\n }),\n }\n : undefined;\n }\n\n async getClusters(): Promise<ClusterDetails[]> {\n return this.clusterDetails;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Runs a function repeatedly, with a fixed wait between invocations.\n *\n * Supports async functions, and silently ignores exceptions and rejections.\n *\n * @param fn - The function to run. May return a Promise.\n * @param delayMs - The delay between a completed function invocation and the\n * next.\n * @returns A function that, when called, stops the invocation loop.\n */\nexport function runPeriodically(fn: () => any, delayMs: number): () => void {\n let cancel: () => void;\n let cancelled = false;\n const cancellationPromise = new Promise<void>(resolve => {\n cancel = () => {\n resolve();\n cancelled = true;\n };\n });\n\n const startRefresh = async () => {\n while (!cancelled) {\n try {\n await fn();\n } catch {\n // ignore intentionally\n }\n\n await Promise.race([\n new Promise(resolve => setTimeout(resolve, delayMs)),\n cancellationPromise,\n ]);\n }\n };\n startRefresh();\n\n return cancel!;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ANNOTATION_KUBERNETES_AUTH_PROVIDER } from '@backstage/plugin-kubernetes-common';\nimport { Config } from '@backstage/config';\nimport { ForwardedError } from '@backstage/errors';\nimport * as container from '@google-cloud/container';\nimport { Duration } from 'luxon';\nimport { runPeriodically } from '../service/runPeriodically';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport packageinfo from '../../package.json';\n\ninterface MatchResourceLabelEntry {\n key: string;\n value: string;\n}\n\ntype GkeClusterLocatorOptions = {\n projectId: string;\n authProvider: string;\n region?: string;\n skipTLSVerify?: boolean;\n skipMetricsLookup?: boolean;\n exposeDashboard?: boolean;\n matchingResourceLabels?: MatchResourceLabelEntry[];\n};\n\nexport class GkeClusterLocator implements KubernetesClustersSupplier {\n constructor(\n private readonly options: GkeClusterLocatorOptions,\n private readonly client: container.v1.ClusterManagerClient,\n private clusterDetails: ClusterDetails[] | undefined = undefined,\n private hasClusterDetails: boolean = false,\n ) {}\n\n static fromConfigWithClient(\n config: Config,\n client: container.v1.ClusterManagerClient,\n refreshInterval?: Duration,\n ): GkeClusterLocator {\n const matchingResourceLabels: MatchResourceLabelEntry[] =\n config.getOptionalConfigArray('matchingResourceLabels')?.map(mrl => {\n return { key: mrl.getString('key'), value: mrl.getString('value') };\n }) ?? [];\n\n const storeAuthProviderString =\n config.getOptionalString('authProvider') === 'googleServiceAccount'\n ? 'googleServiceAccount'\n : 'google';\n\n const options = {\n projectId: config.getString('projectId'),\n authProvider: storeAuthProviderString,\n region: config.getOptionalString('region') ?? '-',\n skipTLSVerify: config.getOptionalBoolean('skipTLSVerify') ?? false,\n skipMetricsLookup:\n config.getOptionalBoolean('skipMetricsLookup') ?? false,\n exposeDashboard: config.getOptionalBoolean('exposeDashboard') ?? false,\n matchingResourceLabels,\n };\n const gkeClusterLocator = new GkeClusterLocator(options, client);\n if (refreshInterval) {\n runPeriodically(\n () => gkeClusterLocator.refreshClusters(),\n refreshInterval.toMillis(),\n );\n }\n return gkeClusterLocator;\n }\n\n // Added an `x-goog-api-client` header to API requests made by the GKE cluster locator to clearly identify API requests from this plugin.\n static fromConfig(\n config: Config,\n refreshInterval: Duration | undefined = undefined,\n ): GkeClusterLocator {\n return GkeClusterLocator.fromConfigWithClient(\n config,\n new container.v1.ClusterManagerClient({\n libName: `backstage/kubernetes-backend.GkeClusterLocator`,\n libVersion: packageinfo.version,\n }),\n refreshInterval,\n );\n }\n\n async getClusters(): Promise<ClusterDetails[]> {\n if (!this.hasClusterDetails) {\n // refresh at least once when first called, when retries are disabled and in tests\n await this.refreshClusters();\n }\n return this.clusterDetails ?? [];\n }\n\n // TODO pass caData into the object\n async refreshClusters(): Promise<void> {\n const {\n projectId,\n region,\n authProvider,\n skipTLSVerify,\n skipMetricsLookup,\n exposeDashboard,\n matchingResourceLabels,\n } = this.options;\n const request = {\n parent: `projects/${projectId}/locations/${region}`,\n };\n\n try {\n const [response] = await this.client.listClusters(request);\n this.clusterDetails = (response.clusters ?? [])\n .filter(r => {\n return matchingResourceLabels?.every(mrl => {\n if (!r.resourceLabels) {\n return false;\n }\n return r.resourceLabels[mrl.key] === mrl.value;\n });\n })\n .map(r => ({\n // TODO filter out clusters which don't have name or endpoint\n name: r.name ?? 'unknown',\n url: `https://${r.endpoint ?? ''}`,\n authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider },\n skipTLSVerify,\n skipMetricsLookup,\n ...(exposeDashboard\n ? {\n dashboardApp: 'gke',\n dashboardParameters: {\n projectId,\n region,\n clusterName: r.name,\n },\n }\n : {}),\n }));\n this.hasClusterDetails = true;\n } catch (e) {\n throw new ForwardedError(\n `There was an error retrieving clusters from GKE for projectId=${projectId} region=${region}`,\n e,\n );\n }\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthService,\n BackstageCredentials,\n} from '@backstage/backend-plugin-api';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client';\nimport {\n ANNOTATION_KUBERNETES_API_SERVER,\n ANNOTATION_KUBERNETES_API_SERVER_CA,\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP,\n ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY,\n ANNOTATION_KUBERNETES_DASHBOARD_URL,\n ANNOTATION_KUBERNETES_DASHBOARD_APP,\n ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS,\n} from '@backstage/plugin-kubernetes-common';\nimport { JsonObject } from '@backstage/types';\n\nfunction isObject(obj: unknown): obj is JsonObject {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj);\n}\n\nexport class CatalogClusterLocator implements KubernetesClustersSupplier {\n private catalogClient: CatalogApi;\n private auth: AuthService;\n\n constructor(catalogClient: CatalogApi, auth: AuthService) {\n this.catalogClient = catalogClient;\n this.auth = auth;\n }\n\n static fromConfig(\n catalogApi: CatalogApi,\n auth: AuthService,\n ): CatalogClusterLocator {\n return new CatalogClusterLocator(catalogApi, auth);\n }\n\n async getClusters(options?: {\n credentials: BackstageCredentials;\n }): Promise<ClusterDetails[]> {\n const apiServerKey = `metadata.annotations.${ANNOTATION_KUBERNETES_API_SERVER}`;\n const apiServerCaKey = `metadata.annotations.${ANNOTATION_KUBERNETES_API_SERVER_CA}`;\n const authProviderKey = `metadata.annotations.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}`;\n\n const filter: Record<string, symbol | string> = {\n kind: 'Resource',\n 'spec.type': 'kubernetes-cluster',\n [apiServerKey]: CATALOG_FILTER_EXISTS,\n [apiServerCaKey]: CATALOG_FILTER_EXISTS,\n [authProviderKey]: CATALOG_FILTER_EXISTS,\n };\n\n const clusters = await this.catalogClient.getEntities(\n {\n filter: [filter],\n },\n options?.credentials\n ? {\n token: (\n await this.auth.getPluginRequestToken({\n onBehalfOf: options.credentials,\n targetPluginId: 'catalog',\n })\n ).token,\n }\n : undefined,\n );\n return clusters.items.map(entity => {\n const annotations = entity.metadata.annotations!;\n const clusterDetails: ClusterDetails = {\n name: entity.metadata.name,\n title: entity.metadata.title,\n url: annotations[ANNOTATION_KUBERNETES_API_SERVER],\n authMetadata: annotations,\n caData: annotations[ANNOTATION_KUBERNETES_API_SERVER_CA],\n skipMetricsLookup:\n annotations[ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP] === 'true',\n skipTLSVerify:\n annotations[ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY] === 'true',\n dashboardUrl: annotations[ANNOTATION_KUBERNETES_DASHBOARD_URL],\n dashboardApp: annotations[ANNOTATION_KUBERNETES_DASHBOARD_APP],\n dashboardParameters: this.getDashboardParameters(annotations),\n };\n\n return clusterDetails;\n });\n }\n\n private getDashboardParameters(\n annotations: Record<string, string>,\n ): JsonObject | undefined {\n const dashboardParamsString =\n annotations[ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS];\n if (dashboardParamsString) {\n try {\n const dashboardParams = JSON.parse(dashboardParamsString);\n return isObject(dashboardParams) ? dashboardParams : undefined;\n } catch {\n return undefined;\n }\n }\n return undefined;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ANNOTATION_KUBERNETES_AUTH_PROVIDER } from '@backstage/plugin-kubernetes-common';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n} from '@backstage/plugin-kubernetes-node';\nimport dns from 'node:dns';\n\nexport class LocalKubectlProxyClusterLocator\n implements KubernetesClustersSupplier\n{\n private readonly clusterDetails: ClusterDetails[];\n // verbatim: when false, IPv4 addresses are placed before IPv6 addresses, ignoring the order from the DNS resolver\n // By default kubectl proxy listens on 127.0.0.1 instead of [::1]\n private lookupPromise = dns.promises.lookup('localhost', { verbatim: false });\n\n public constructor() {\n this.clusterDetails = [\n {\n name: 'local',\n url: 'http://localhost:8001',\n authMetadata: {\n [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'localKubectlProxy',\n },\n skipMetricsLookup: true,\n },\n ];\n }\n\n async getClusters(): Promise<ClusterDetails[]> {\n const lookupResolution = await this.lookupPromise;\n this.clusterDetails[0].url = `http://${lookupResolution.address}:8001`;\n return this.clusterDetails;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport { Duration } from 'luxon';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\nimport { AuthenticationStrategy } from '../auth/types';\nimport { ConfigClusterLocator } from './ConfigClusterLocator';\nimport { GkeClusterLocator } from './GkeClusterLocator';\nimport { CatalogClusterLocator } from './CatalogClusterLocator';\nimport { LocalKubectlProxyClusterLocator } from './LocalKubectlProxyLocator';\nimport {\n AuthService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\n\nclass CombinedClustersSupplier implements KubernetesClustersSupplier {\n constructor(\n readonly clusterSuppliers: KubernetesClustersSupplier[],\n readonly logger: LoggerService,\n ) {}\n\n async getClusters(options: {\n credentials: BackstageCredentials;\n }): Promise<ClusterDetails[]> {\n const clusters = await Promise.all(\n this.clusterSuppliers.map(supplier => supplier.getClusters(options)),\n )\n .then(res => {\n return res.flat();\n })\n .catch(e => {\n throw e;\n });\n return this.warnDuplicates(clusters);\n }\n\n private warnDuplicates(clusters: ClusterDetails[]): ClusterDetails[] {\n const clusterNames = new Set<string>();\n const duplicatedNames = new Set<string>();\n for (const clusterName of clusters.map(c => c.name)) {\n if (clusterNames.has(clusterName)) {\n duplicatedNames.add(clusterName);\n } else {\n clusterNames.add(clusterName);\n }\n }\n for (const clusterName of duplicatedNames) {\n this.logger.warn(`Duplicate cluster name '${clusterName}'`);\n }\n return clusters;\n }\n}\n\nexport const getCombinedClusterSupplier = (\n rootConfig: Config,\n catalogClient: CatalogApi,\n authStrategy: AuthenticationStrategy,\n logger: LoggerService,\n refreshInterval: Duration | undefined = undefined,\n auth: AuthService,\n): KubernetesClustersSupplier => {\n const clusterSuppliers = rootConfig\n .getConfigArray('kubernetes.clusterLocatorMethods')\n .map(clusterLocatorMethod => {\n const type = clusterLocatorMethod.getString('type');\n switch (type) {\n case 'catalog':\n return CatalogClusterLocator.fromConfig(catalogClient, auth);\n case 'localKubectlProxy':\n return new LocalKubectlProxyClusterLocator();\n case 'config':\n return ConfigClusterLocator.fromConfig(\n clusterLocatorMethod,\n authStrategy,\n );\n case 'gke':\n return GkeClusterLocator.fromConfig(\n clusterLocatorMethod,\n refreshInterval,\n );\n default:\n throw new Error(\n `Unsupported kubernetes.clusterLocatorMethods: \"${type}\"`,\n );\n }\n });\n\n return new CombinedClustersSupplier(clusterSuppliers, logger);\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n CompoundEntityRef,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { InputError } from '@backstage/errors';\nimport express, { Request } from 'express';\nimport { KubernetesObjectsProvider } from '@backstage/plugin-kubernetes-node';\nimport { AuthService, HttpAuthService } from '@backstage/backend-plugin-api';\n\nexport const addResourceRoutesToRouter = (\n router: express.Router,\n catalogApi: CatalogApi,\n objectsProvider: KubernetesObjectsProvider,\n auth: AuthService,\n httpAuth: HttpAuthService,\n) => {\n const getEntityByReq = async (req: Request<any>) => {\n const rawEntityRef = req.body.entityRef;\n if (rawEntityRef && typeof rawEntityRef !== 'string') {\n throw new InputError(`entity query must be a string`);\n } else if (!rawEntityRef) {\n throw new InputError('entity is a required field');\n }\n let entityRef: CompoundEntityRef | undefined = undefined;\n\n try {\n entityRef = parseEntityRef(rawEntityRef);\n } catch (error) {\n throw new InputError(`Invalid entity ref, ${error}`);\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(req),\n targetPluginId: 'catalog',\n });\n\n const entity = await catalogApi.getEntityByRef(entityRef, { token });\n if (!entity) {\n throw new InputError(\n `Entity ref missing, ${stringifyEntityRef(entityRef)}`,\n );\n }\n\n return entity;\n };\n\n router.post('/resources/workloads/query', async (req, res) => {\n const entity = await getEntityByReq(req);\n const response = await objectsProvider.getKubernetesObjectsByEntity(\n {\n entity,\n auth: req.body.auth,\n },\n { credentials: await httpAuth.credentials(req) },\n );\n res.json(response);\n });\n\n router.post('/resources/custom/query', async (req, res) => {\n const entity = await getEntityByReq(req);\n\n if (!req.body.customResources) {\n throw new InputError('customResources is a required field');\n } else if (!Array.isArray(req.body.customResources)) {\n throw new InputError('customResources must be an array');\n } else if (req.body.customResources.length === 0) {\n throw new InputError('at least 1 customResource is required');\n }\n\n const response = await objectsProvider.getCustomResourcesByEntity(\n {\n entity,\n customResources: req.body.customResources,\n auth: req.body.auth,\n },\n { credentials: await httpAuth.credentials(req) },\n );\n res.json(response);\n });\n};\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n KubernetesServiceLocator,\n ServiceLocatorRequestContext,\n} from '@backstage/plugin-kubernetes-node';\n\n// This locator assumes that service is located on the clusters it depends on\n// Therefore it will return the clusters based on the relations it has or none otherwise\nexport class CatalogRelationServiceLocator implements KubernetesServiceLocator {\n private readonly clusterSupplier: KubernetesClustersSupplier;\n\n constructor(clusterSupplier: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n }\n\n // As this implementation always returns all clusters serviceId is ignored here\n getClustersByEntity(\n entity: Entity,\n requestContext: ServiceLocatorRequestContext,\n ): Promise<{ clusters: ClusterDetails[] }> {\n if (\n entity.relations &&\n entity.relations.some(\n r => r.type === 'dependsOn' && r.targetRef.includes('resource:'),\n )\n ) {\n return this.clusterSupplier\n .getClusters({ credentials: requestContext.credentials })\n .then(clusters => {\n return {\n clusters: clusters.filter(c =>\n this.doesEntityDependOnCluster(entity, c),\n ),\n };\n });\n }\n return Promise.resolve({ clusters: [] });\n }\n\n protected doesEntityDependOnCluster(\n entity: Entity,\n cluster: ClusterDetails,\n ): boolean {\n return entity.relations!.some(\n rel =>\n rel.type === 'dependsOn' &&\n rel.targetRef ===\n `resource:${entity.metadata.namespace ?? 'default'}/${cluster.name}`,\n );\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n KubernetesServiceLocator,\n ServiceLocatorRequestContext,\n} from '../types/types';\n\n// This locator assumes that every service is located on every cluster\n// Therefore it will always return all clusters provided\nexport class MultiTenantServiceLocator implements KubernetesServiceLocator {\n private readonly clusterSupplier: KubernetesClustersSupplier;\n\n constructor(clusterSupplier: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n }\n\n // As this implementation always returns all clusters serviceId is ignored here\n getClustersByEntity(\n _entity: Entity,\n requestContext: ServiceLocatorRequestContext,\n ): Promise<{ clusters: ClusterDetails[] }> {\n return this.clusterSupplier\n .getClusters({ credentials: requestContext.credentials })\n .then(clusters => ({ clusters }));\n }\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport {\n ClusterDetails,\n KubernetesClustersSupplier,\n KubernetesServiceLocator,\n ServiceLocatorRequestContext,\n} from '../types/types';\n\n// This locator assumes that service is located on one cluster\n// Therefore it will always return specified cluster provided in backstage.io/kubernetes-cluster annotation\n// If backstage.io/kubernetes-cluster annotation not provided will always return all cluster provided\nexport class SingleTenantServiceLocator implements KubernetesServiceLocator {\n private readonly clusterSupplier: KubernetesClustersSupplier;\n\n constructor(clusterSupplier: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n }\n\n // As this implementation always returns all clusters serviceId is ignored here\n getClustersByEntity(\n _entity: Entity,\n requestContext: ServiceLocatorRequestContext,\n ): Promise<{ clusters: ClusterDetails[] }> {\n return this.clusterSupplier\n .getClusters({ credentials: requestContext.credentials })\n .then(clusters => {\n if (\n _entity.metadata?.annotations?.['backstage.io/kubernetes-cluster']\n ) {\n return {\n clusters: clusters.filter(\n c =>\n c.name ===\n _entity.metadata?.annotations?.[\n 'backstage.io/kubernetes-cluster'\n ],\n ),\n };\n }\n return { clusters };\n });\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport {\n CustomResource,\n FetchResponseWrapper,\n KubernetesFetcher,\n KubernetesObjectsProviderOptions,\n KubernetesServiceLocator,\n ObjectsByEntityRequest,\n ObjectToFetch,\n} from '../types/types';\nimport {\n ClientContainerStatus,\n ClientCurrentResourceUsage,\n ClientPodStatus,\n ClusterObjects,\n CustomResourceMatcher,\n FetchResponse,\n KubernetesRequestAuth,\n ObjectsByEntityResponse,\n PodFetchResponse,\n PodStatusFetchResponse,\n} from '@backstage/plugin-kubernetes-common';\nimport {\n ContainerStatus,\n CurrentResourceUsage,\n PodStatus,\n} from '@kubernetes/client-node';\nimport {\n AuthenticationStrategy,\n ClusterDetails,\n CustomResourcesByEntity,\n KubernetesCredential,\n KubernetesObjectsByEntity,\n KubernetesObjectsProvider,\n} from '@backstage/plugin-kubernetes-node';\nimport {\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\n\n/**\n *\n * @public\n */\nexport const DEFAULT_OBJECTS: ObjectToFetch[] = [\n {\n group: '',\n apiVersion: 'v1',\n plural: 'pods',\n objectType: 'pods',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'services',\n objectType: 'services',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'configmaps',\n objectType: 'configmaps',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'limitranges',\n objectType: 'limitranges',\n },\n {\n group: '',\n apiVersion: 'v1',\n plural: 'resourcequotas',\n objectType: 'resourcequotas',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'deployments',\n objectType: 'deployments',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'replicasets',\n objectType: 'replicasets',\n },\n {\n group: 'autoscaling',\n apiVersion: 'v1',\n plural: 'horizontalpodautoscalers',\n objectType: 'horizontalpodautoscalers',\n },\n {\n group: 'batch',\n apiVersion: 'v1',\n plural: 'jobs',\n objectType: 'jobs',\n },\n {\n group: 'batch',\n apiVersion: 'v1',\n plural: 'cronjobs',\n objectType: 'cronjobs',\n },\n {\n group: 'networking.k8s.io',\n apiVersion: 'v1',\n plural: 'ingresses',\n objectType: 'ingresses',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'statefulsets',\n objectType: 'statefulsets',\n },\n {\n group: 'apps',\n apiVersion: 'v1',\n plural: 'daemonsets',\n objectType: 'daemonsets',\n },\n];\n\nexport interface KubernetesFanOutHandlerOptions\n extends KubernetesObjectsProviderOptions {\n authStrategy: AuthenticationStrategy;\n}\n\nexport interface KubernetesRequestBody extends ObjectsByEntityRequest {}\n\nconst isPodFetchResponse = (fr: FetchResponse): fr is PodFetchResponse =>\n fr.type === 'pods';\nconst isString = (str: string | undefined): str is string => str !== undefined;\n\nconst numberOrBigIntToNumberOrString = (\n value: number | BigInt,\n): number | string => {\n return typeof value === 'bigint' ? value.toString() : (value as number);\n};\n\nconst toClientSafeResource = (\n current: CurrentResourceUsage,\n): ClientCurrentResourceUsage => {\n return {\n currentUsage: numberOrBigIntToNumberOrString(current.CurrentUsage),\n requestTotal: numberOrBigIntToNumberOrString(current.RequestTotal),\n limitTotal: numberOrBigIntToNumberOrString(current.LimitTotal),\n };\n};\n\nconst toClientSafeContainer = (\n container: ContainerStatus,\n): ClientContainerStatus => {\n return {\n container: container.Container,\n cpuUsage: toClientSafeResource(container.CPUUsage),\n memoryUsage: toClientSafeResource(container.MemoryUsage),\n };\n};\n\nconst toClientSafePodMetrics = (\n podMetrics: PodStatusFetchResponse[],\n): ClientPodStatus[] => {\n return podMetrics\n .map(r => r.resources)\n .flat()\n .map((pd: PodStatus): ClientPodStatus => {\n return {\n pod: pd.Pod,\n memory: toClientSafeResource(pd.Memory),\n cpu: toClientSafeResource(pd.CPU),\n containers: pd.Containers.map(toClientSafeContainer),\n };\n });\n};\n\ntype responseWithMetrics = [FetchResponseWrapper, PodStatusFetchResponse[]];\n\nexport class KubernetesFanOutHandler implements KubernetesObjectsProvider {\n private readonly logger: LoggerService;\n private readonly fetcher: KubernetesFetcher;\n private readonly serviceLocator: KubernetesServiceLocator;\n private readonly customResources: CustomResource[];\n private readonly objectTypesToFetch: Set<ObjectToFetch>;\n private readonly authStrategy: AuthenticationStrategy;\n\n constructor({\n logger,\n fetcher,\n serviceLocator,\n customResources,\n objectTypesToFetch = DEFAULT_OBJECTS,\n authStrategy,\n }: KubernetesFanOutHandlerOptions) {\n this.logger = logger;\n this.fetcher = fetcher;\n this.serviceLocator = serviceLocator;\n this.customResources = customResources;\n this.objectTypesToFetch = new Set(objectTypesToFetch);\n this.authStrategy = authStrategy;\n }\n\n async getCustomResourcesByEntity(\n { entity, auth, customResources }: CustomResourcesByEntity,\n options: { credentials: BackstageCredentials },\n ): Promise<ObjectsByEntityResponse> {\n // Don't fetch the default object types only the provided custom resources\n return this.fanOutRequests(\n entity,\n auth,\n { credentials: options.credentials },\n new Set<ObjectToFetch>(),\n customResources,\n );\n }\n\n async getKubernetesObjectsByEntity(\n { entity, auth }: KubernetesObjectsByEntity,\n options: { credentials: BackstageCredentials },\n ): Promise<ObjectsByEntityResponse> {\n return this.fanOutRequests(\n entity,\n auth,\n {\n credentials: options.credentials,\n },\n this.objectTypesToFetch,\n );\n }\n\n private async fanOutRequests(\n entity: Entity,\n auth: KubernetesRequestAuth,\n options: { credentials: BackstageCredentials },\n objectTypesToFetch: Set<ObjectToFetch>,\n customResources?: CustomResourceMatcher[],\n ) {\n const entityName =\n entity.metadata?.annotations?.['backstage.io/kubernetes-id'] ||\n entity.metadata?.name;\n\n const { clusters } = await this.serviceLocator.getClustersByEntity(entity, {\n objectTypesToFetch: objectTypesToFetch,\n customResources: customResources ?? [],\n credentials: options.credentials,\n });\n\n this.logger.info(\n `entity.metadata.name=${entityName} clusterDetails=[${clusters\n .map(c => c.name)\n .join(', ')}]`,\n );\n\n const labelSelector: string =\n entity.metadata?.annotations?.[\n 'backstage.io/kubernetes-label-selector'\n ] || `backstage.io/kubernetes-id=${entityName}`;\n\n const namespace =\n entity.metadata?.annotations?.['backstage.io/kubernetes-namespace'];\n\n return Promise.all(\n clusters.map(async clusterDetails => {\n const credential = await this.authStrategy.getCredential(\n clusterDetails,\n auth,\n );\n return this.fetcher\n .fetchObjectsForService({\n serviceId: entityName,\n clusterDetails,\n credential,\n objectTypesToFetch,\n labelSelector,\n customResources: (\n customResources ||\n clusterDetails.customResources ||\n this.customResources\n ).map(c => ({\n ...c,\n objectType: 'customresources',\n })),\n namespace,\n })\n .then(result =>\n this.getMetricsForPods(\n clusterDetails,\n credential,\n labelSelector,\n result,\n ),\n )\n .catch(\n (e): Promise<responseWithMetrics> =>\n e.name === 'FetchError'\n ? Promise.resolve([\n {\n errors: [\n { errorType: 'FETCH_ERROR', message: e.message },\n ],\n responses: [],\n },\n [],\n ])\n : Promise.reject(e),\n )\n .then(r => this.toClusterObjects(clusterDetails, r));\n }),\n ).then(this.toObjectsByEntityResponse);\n }\n\n toObjectsByEntityResponse(\n clusterObjects: ClusterObjects[],\n ): ObjectsByEntityResponse {\n return {\n items: clusterObjects.filter(\n item =>\n (item.errors !== undefined && item.errors.length >= 1) ||\n (item.resources !== undefined &&\n item.resources.length >= 1 &&\n item.resources.some(fr => fr.resources?.length >= 1)),\n ),\n };\n }\n\n toClusterObjects(\n clusterDetails: ClusterDetails,\n [result, metrics]: responseWithMetrics,\n ): ClusterObjects {\n const objects: ClusterObjects = {\n cluster: {\n name: clusterDetails.name,\n ...(clusterDetails.title && { title: clusterDetails.title }),\n },\n podMetrics: toClientSafePodMetrics(metrics),\n resources: result.responses,\n errors: result.errors,\n };\n if (clusterDetails.dashboardUrl) {\n objects.cluster.dashboardUrl = clusterDetails.dashboardUrl;\n }\n if (clusterDetails.dashboardApp) {\n objects.cluster.dashboardApp = clusterDetails.dashboardApp;\n }\n if (clusterDetails.dashboardParameters) {\n objects.cluster.dashboardParameters = clusterDetails.dashboardParameters;\n }\n return objects;\n }\n\n async getMetricsForPods(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n labelSelector: string,\n result: FetchResponseWrapper,\n ): Promise<responseWithMetrics> {\n if (clusterDetails.skipMetricsLookup) {\n return [result, []];\n }\n const namespaces: Set<string> = new Set<string>(\n result.responses\n .filter(isPodFetchResponse)\n .flatMap(r => r.resources)\n .map(p => p.metadata?.namespace)\n .filter(isString),\n );\n\n if (namespaces.size === 0) {\n return [result, []];\n }\n\n const podMetrics = await this.fetcher.fetchPodMetricsByNamespaces(\n clusterDetails,\n credential,\n namespaces,\n labelSelector,\n );\n\n result.errors.push(...podMetrics.errors);\n return [result, podMetrics.responses as PodStatusFetchResponse[]];\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n bufferFromFileOrString,\n Cluster,\n Config,\n CoreV1Api,\n KubeConfig,\n Metrics,\n topPods,\n} from '@kubernetes/client-node';\nimport lodash, { Dictionary } from 'lodash';\nimport {\n FetchResponseWrapper,\n KubernetesFetcher,\n ObjectFetchParams,\n} from '../types/types';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n FetchResponse,\n KubernetesErrorTypes,\n KubernetesFetchError,\n PodStatusFetchResponse,\n} from '@backstage/plugin-kubernetes-common';\nimport fetch, { RequestInit, Response } from 'node-fetch';\nimport * as https from 'https';\nimport fs from 'fs-extra';\nimport { JsonObject } from '@backstage/types';\nimport {\n ClusterDetails,\n KubernetesCredential,\n} from '@backstage/plugin-kubernetes-node';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nexport interface KubernetesClientBasedFetcherOptions {\n logger: LoggerService;\n}\n\ntype FetchResult = FetchResponse | KubernetesFetchError;\n\nconst isError = (fr: FetchResult): fr is KubernetesFetchError =>\n fr.hasOwnProperty('errorType');\n\nfunction fetchResultsToResponseWrapper(\n results: FetchResult[],\n): FetchResponseWrapper {\n const groupBy: Dictionary<FetchResult[]> = lodash.groupBy(results, value => {\n return isError(value) ? 'errors' : 'responses';\n });\n\n return {\n errors: groupBy.errors ?? [],\n responses: groupBy.responses ?? [],\n } as FetchResponseWrapper; // TODO would be nice to get rid of this 'as'\n}\n\nconst statusCodeToErrorType = (statusCode: number): KubernetesErrorTypes => {\n switch (statusCode) {\n case 400:\n return 'BAD_REQUEST';\n case 401:\n return 'UNAUTHORIZED_ERROR';\n case 404:\n return 'NOT_FOUND';\n case 500:\n return 'SYSTEM_ERROR';\n default:\n return 'UNKNOWN_ERROR';\n }\n};\n\nexport class KubernetesClientBasedFetcher implements KubernetesFetcher {\n private readonly logger: LoggerService;\n\n constructor({ logger }: KubernetesClientBasedFetcherOptions) {\n this.logger = logger;\n }\n\n fetchObjectsForService(\n params: ObjectFetchParams,\n ): Promise<FetchResponseWrapper> {\n const fetchResults = Array.from(params.objectTypesToFetch)\n .concat(params.customResources)\n .map(({ objectType, group, apiVersion, plural }) =>\n this.fetchResource(\n params.clusterDetails,\n params.credential,\n group,\n apiVersion,\n plural,\n params.namespace,\n params.labelSelector,\n ).then(\n (r: Response): Promise<FetchResult> =>\n r.ok\n ? r.json().then(\n ({ kind, items }): FetchResponse => ({\n type: objectType,\n resources:\n objectType === 'customresources'\n ? items.map((item: JsonObject) => ({\n ...item,\n kind: kind.replace(/(List)$/, ''),\n }))\n : items,\n }),\n )\n : this.handleUnsuccessfulResponse(params.clusterDetails.name, r),\n ),\n );\n\n return Promise.all(fetchResults).then(fetchResultsToResponseWrapper);\n }\n\n fetchPodMetricsByNamespaces(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n namespaces: Set<string>,\n labelSelector?: string,\n ): Promise<FetchResponseWrapper> {\n const fetchResults = Array.from(namespaces).map(async ns => {\n const [podMetrics, podList] = await Promise.all([\n this.fetchResource(\n clusterDetails,\n credential,\n 'metrics.k8s.io',\n 'v1beta1',\n 'pods',\n ns,\n labelSelector,\n ),\n this.fetchResource(\n clusterDetails,\n credential,\n '',\n 'v1',\n 'pods',\n ns,\n labelSelector,\n ),\n ]);\n if (podMetrics.ok && podList.ok) {\n return topPods(\n {\n listPodForAllNamespaces: () =>\n podList.json().then(b => ({ body: b })),\n } as unknown as CoreV1Api,\n {\n getPodMetrics: () => podMetrics.json(),\n } as unknown as Metrics,\n ).then(\n (resources): PodStatusFetchResponse => ({\n type: 'podstatus',\n resources,\n }),\n );\n } else if (podMetrics.ok) {\n return this.handleUnsuccessfulResponse(clusterDetails.name, podList);\n }\n return this.handleUnsuccessfulResponse(clusterDetails.name, podMetrics);\n });\n\n return Promise.all(fetchResults).then(fetchResultsToResponseWrapper);\n }\n\n private async handleUnsuccessfulResponse(\n clusterName: string,\n res: Response,\n ): Promise<KubernetesFetchError> {\n const resourcePath = new URL(res.url).pathname;\n this.logger.warn(\n `Received ${\n res.status\n } status when fetching \"${resourcePath}\" from cluster \"${clusterName}\"; body=[${await res.text()}]`,\n );\n return {\n errorType: statusCodeToErrorType(res.status),\n statusCode: res.status,\n resourcePath,\n };\n }\n\n private fetchResource(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n group: string,\n apiVersion: string,\n plural: string,\n namespace?: string,\n labelSelector?: string,\n ): Promise<Response> {\n const encode = (s: string) => encodeURIComponent(s);\n let resourcePath = group\n ? `/apis/${encode(group)}/${encode(apiVersion)}`\n : `/api/${encode(apiVersion)}`;\n if (namespace) {\n resourcePath += `/namespaces/${encode(namespace)}`;\n }\n resourcePath += `/${encode(plural)}`;\n\n let url: URL;\n let requestInit: RequestInit;\n const authProvider =\n clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n\n if (this.isServiceAccountAuthentication(authProvider, clusterDetails)) {\n [url, requestInit] = this.fetchArgsInCluster(credential);\n } else if (!this.isCredentialMissing(authProvider, credential)) {\n [url, requestInit] = this.fetchArgs(clusterDetails, credential);\n } else {\n return Promise.reject(\n new Error(\n `no bearer token or client cert for cluster '${clusterDetails.name}' and not running in Kubernetes`,\n ),\n );\n }\n\n if (url.pathname === '/') {\n url.pathname = resourcePath;\n } else {\n url.pathname += resourcePath;\n }\n\n if (labelSelector) {\n url.search = `labelSelector=${encode(labelSelector)}`;\n }\n\n return fetch(url, requestInit);\n }\n\n private isServiceAccountAuthentication(\n authProvider: string,\n clusterDetails: ClusterDetails,\n ) {\n return (\n authProvider === 'serviceAccount' &&\n !clusterDetails.authMetadata.serviceAccountToken &&\n fs.pathExistsSync(Config.SERVICEACCOUNT_CA_PATH)\n );\n }\n\n private isCredentialMissing(\n authProvider: string,\n credential: KubernetesCredential,\n ) {\n return (\n authProvider !== 'localKubectlProxy' && credential.type === 'anonymous'\n );\n }\n\n private fetchArgs(\n clusterDetails: ClusterDetails,\n credential: KubernetesCredential,\n ): [URL, RequestInit] {\n const requestInit: RequestInit = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n ...(credential.type === 'bearer token' && {\n Authorization: `Bearer ${credential.token}`,\n }),\n },\n };\n\n const url: URL = new URL(clusterDetails.url);\n if (url.protocol === 'https:') {\n requestInit.agent = new https.Agent({\n ca:\n bufferFromFileOrString(\n clusterDetails.caFile,\n clusterDetails.caData,\n ) ?? undefined,\n rejectUnauthorized: !clusterDetails.skipTLSVerify,\n ...(credential.type === 'x509 client certificate' && {\n cert: credential.cert,\n key: credential.key,\n }),\n });\n }\n return [url, requestInit];\n }\n private fetchArgsInCluster(\n credential: KubernetesCredential,\n ): [URL, RequestInit] {\n const requestInit: RequestInit = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n ...(credential.type === 'bearer token' && {\n Authorization: `Bearer ${credential.token}`,\n }),\n },\n };\n\n const kc = new KubeConfig();\n kc.loadFromCluster();\n // loadFromCluster is guaranteed to populate the cluster/user/context\n const cluster = kc.getCurrentCluster() as Cluster;\n\n const url = new URL(cluster.server);\n if (url.protocol === 'https:') {\n requestInit.agent = new https.Agent({\n ca: fs.readFileSync(cluster.caFile as string),\n });\n }\n return [url, requestInit];\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ErrorResponseBody,\n ForwardedError,\n NotAllowedError,\n NotFoundError,\n serializeError,\n} from '@backstage/errors';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n kubernetesProxyPermission,\n KubernetesRequestAuth,\n} from '@backstage/plugin-kubernetes-common';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport {\n bufferFromFileOrString,\n Cluster,\n Config,\n KubeConfig,\n} from '@kubernetes/client-node';\nimport { createProxyMiddleware, RequestHandler } from 'http-proxy-middleware';\nimport fs from 'fs-extra';\n\nimport { AuthenticationStrategy } from '../auth';\nimport { ClusterDetails, KubernetesClustersSupplier } from '../types/types';\n\nimport type { Request } from 'express';\nimport { IncomingHttpHeaders } from 'http';\nimport {\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport {\n createLegacyAuthAdapters,\n loggerToWinstonLogger,\n} from '@backstage/backend-common';\n\nexport const APPLICATION_JSON: string = 'application/json';\n\n/**\n * The header that is used to specify the cluster name.\n *\n * @public\n */\nexport const HEADER_KUBERNETES_CLUSTER: string = 'Backstage-Kubernetes-Cluster';\n\n/**\n * The header that is used to specify the Authentication Authorities token.\n * e.x if using the google auth provider as your authentication authority then this field would be the google provided bearer token.\n * @public\n */\nexport const HEADER_KUBERNETES_AUTH: string =\n 'Backstage-Kubernetes-Authorization';\n\n/**\n * The options object expected to be passed as a parameter to KubernetesProxy.createRequestHandler().\n *\n * @public\n */\nexport type KubernetesProxyCreateRequestHandlerOptions = {\n permissionApi: PermissionsService;\n};\n\n/**\n * Options accepted as a parameter by the KubernetesProxy\n *\n * @public\n */\nexport type KubernetesProxyOptions = {\n logger: LoggerService;\n clusterSupplier: KubernetesClustersSupplier;\n authStrategy: AuthenticationStrategy;\n discovery: DiscoveryService;\n httpAuth?: HttpAuthService;\n};\n\n/**\n * A proxy that routes requests to the Kubernetes API.\n *\n * @public\n */\nexport class KubernetesProxy {\n private readonly middlewareForClusterName = new Map<string, RequestHandler>();\n private readonly logger: LoggerService;\n private readonly clusterSupplier: KubernetesClustersSupplier;\n private readonly authStrategy: AuthenticationStrategy;\n private readonly httpAuth: HttpAuthService;\n\n constructor(options: KubernetesProxyOptions) {\n this.logger = options.logger;\n this.clusterSupplier = options.clusterSupplier;\n this.authStrategy = options.authStrategy;\n\n const legacy = createLegacyAuthAdapters({\n discovery: options.discovery,\n httpAuth: options.httpAuth,\n });\n\n this.httpAuth = legacy.httpAuth;\n }\n\n public createRequestHandler(\n options: KubernetesProxyCreateRequestHandlerOptions,\n ): RequestHandler {\n const { permissionApi } = options;\n return async (req, res, next) => {\n const authorizeResponse = await permissionApi.authorize(\n [{ permission: kubernetesProxyPermission }],\n {\n credentials: await this.httpAuth.credentials(req),\n },\n );\n const auth = authorizeResponse[0];\n\n if (auth.result === AuthorizeResult.DENY) {\n res.status(403).json({ error: new NotAllowedError('Unauthorized') });\n return;\n }\n\n const middleware = await this.getMiddleware(req);\n\n // If req is an upgrade handshake, use middleware upgrade instead of http request handler https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade\n if (\n req.header('connection')?.toLowerCase() === 'upgrade' &&\n req.header('upgrade')?.toLowerCase() === 'websocket'\n ) {\n // Missing the `head`, since it's optional we pass undefined to avoid type issues\n middleware.upgrade!(req, req.socket, undefined);\n } else {\n middleware(req, res, next);\n }\n };\n }\n\n // We create one middleware per remote cluster and hold on to them, because\n // the secure property isn't possible to decide on a per-request basis with a\n // single middleware instance - and we don't expect it to change over time.\n private async getMiddleware(originalReq: Request): Promise<RequestHandler> {\n const originalCluster = await this.getClusterForRequest(originalReq);\n let middleware = this.middlewareForClusterName.get(originalCluster.name);\n if (!middleware) {\n const logger = this.logger.child({ cluster: originalCluster.name });\n middleware = createProxyMiddleware({\n // TODO: Add 'log' to LoggerService\n logProvider: () => loggerToWinstonLogger(logger),\n ws: true,\n secure: !originalCluster.skipTLSVerify,\n changeOrigin: true,\n pathRewrite: async (path, req) => {\n // Re-evaluate the cluster on each request, in case it has changed\n const cluster = await this.getClusterForRequest(req);\n const url = new URL(cluster.url);\n return path.replace(\n new RegExp(`^${originalReq.baseUrl}`),\n url.pathname || '',\n );\n },\n router: async req => {\n // Re-evaluate the cluster on each request, in case it has changed\n const cluster = await this.getClusterForRequest(req);\n const url = new URL(cluster.url);\n\n const target: any = {\n protocol: url.protocol,\n host: url.hostname,\n port: url.port,\n ca: bufferFromFileOrString(\n cluster.caFile,\n cluster.caData,\n )?.toString(),\n };\n\n const authHeader =\n req.headers[HEADER_KUBERNETES_AUTH.toLocaleLowerCase('en-US')];\n if (typeof authHeader === 'string') {\n req.headers.authorization = authHeader;\n } else {\n // Map Backstage-Kubernetes-Authorization-X-X headers to a KubernetesRequestAuth object\n const authObj = KubernetesProxy.authHeadersToKubernetesRequestAuth(\n req.headers,\n );\n\n const credential = await this.getClusterForRequest(req).then(cd => {\n return this.authStrategy.getCredential(cd, authObj);\n });\n\n if (credential.type === 'bearer token') {\n req.headers.authorization = `Bearer ${credential.token}`;\n } else if (credential.type === 'x509 client certificate') {\n target.key = credential.key;\n target.cert = credential.cert;\n }\n }\n\n return target;\n },\n onError: (error, req, res) => {\n const wrappedError = new ForwardedError(\n `Cluster '${originalCluster.name}' request error`,\n error,\n );\n\n logger.error('Kubernetes proxy error', wrappedError);\n\n const body: ErrorResponseBody = {\n error: serializeError(wrappedError, {\n includeStack: process.env.NODE_ENV === 'development',\n }),\n request: { method: req.method, url: req.originalUrl },\n response: { statusCode: 500 },\n };\n res.status(500).json(body);\n },\n });\n this.middlewareForClusterName.set(originalCluster.name, middleware);\n }\n return middleware;\n }\n\n private async getClusterForRequest(req: Request): Promise<ClusterDetails> {\n const clusterName = req.headers[HEADER_KUBERNETES_CLUSTER.toLowerCase()];\n const clusters = await this.clusterSupplier.getClusters({\n credentials: await this.httpAuth.credentials(req),\n });\n\n if (!clusters || clusters.length <= 0) {\n throw new NotFoundError(`No Clusters configured`);\n }\n\n const hasClusterNameHeader =\n typeof clusterName === 'string' && clusterName.length > 0;\n\n let cluster: ClusterDetails | undefined;\n\n if (hasClusterNameHeader) {\n cluster = clusters.find(c => c.name === clusterName);\n } else if (clusters.length === 1) {\n cluster = clusters.at(0);\n }\n\n if (!cluster) {\n throw new NotFoundError(`Cluster '${clusterName}' not found`);\n }\n\n const authProvider =\n cluster.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n\n if (\n authProvider === 'serviceAccount' &&\n fs.pathExistsSync(Config.SERVICEACCOUNT_CA_PATH) &&\n !cluster.authMetadata.serviceAccountToken\n ) {\n const kc = new KubeConfig();\n kc.loadFromCluster();\n const clusterFromKubeConfig = kc.getCurrentCluster() as Cluster;\n\n const url = new URL(clusterFromKubeConfig.server);\n cluster.url = clusterFromKubeConfig.server;\n if (url.protocol === 'https:') {\n cluster.caFile = clusterFromKubeConfig.caFile;\n }\n }\n\n return cluster;\n }\n\n private static authHeadersToKubernetesRequestAuth(\n originalHeaders: IncomingHttpHeaders,\n ): KubernetesRequestAuth {\n return Object.keys(originalHeaders)\n .filter(header => header.startsWith('backstage-kubernetes-authorization'))\n .map(header =>\n KubernetesProxy.headerToDictionary(header, originalHeaders),\n )\n .filter(headerAsDic => Object.keys(headerAsDic).length !== 0)\n .reduce(KubernetesProxy.combineHeaders, {});\n }\n\n private static headerToDictionary(\n header: string,\n originalHeaders: IncomingHttpHeaders,\n ): KubernetesRequestAuth {\n const obj: KubernetesRequestAuth = {};\n const headerSplitted = header.split('-');\n if (headerSplitted.length >= 4) {\n const framework = headerSplitted[3].toLowerCase();\n if (headerSplitted.length >= 5) {\n const provider = headerSplitted.slice(4).join('-').toLowerCase();\n obj[framework] = { [provider]: originalHeaders[header] };\n } else {\n obj[framework] = originalHeaders[header];\n }\n }\n return obj;\n }\n\n private static combineHeaders(\n authObj: any,\n header: any,\n ): KubernetesRequestAuth {\n const framework = Object.keys(header)[0];\n\n if (authObj[framework]) {\n authObj[framework] = {\n ...authObj[framework],\n ...header[framework],\n };\n } else {\n authObj[framework] = header[framework];\n }\n\n return authObj;\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport {\n ANNOTATION_KUBERNETES_AUTH_PROVIDER,\n ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER,\n kubernetesPermissions,\n} from '@backstage/plugin-kubernetes-common';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Duration } from 'luxon';\n\nimport {\n AksStrategy,\n AnonymousStrategy,\n AwsIamStrategy,\n AzureIdentityStrategy,\n DispatchStrategy,\n GoogleServiceAccountStrategy,\n GoogleStrategy,\n OidcStrategy,\n ServiceAccountStrategy,\n} from '../auth';\nimport { getCombinedClusterSupplier } from '../cluster-locator';\n\nimport { createLegacyAuthAdapters } from '@backstage/backend-common';\nimport {\n AuthService,\n BackstageCredentials,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport {\n AuthenticationStrategy,\n AuthMetadata,\n CustomResource,\n KubernetesClustersSupplier,\n KubernetesFetcher,\n KubernetesObjectsProvider,\n KubernetesObjectTypes,\n KubernetesServiceLocator,\n} from '@backstage/plugin-kubernetes-node';\nimport { addResourceRoutesToRouter } from '../routes/resourcesRoutes';\nimport { CatalogRelationServiceLocator } from '../service-locator/CatalogRelationServiceLocator';\nimport { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator';\nimport { SingleTenantServiceLocator } from '../service-locator/SingleTenantServiceLocator';\nimport {\n KubernetesObjectsProviderOptions,\n ObjectsByEntityRequest,\n ServiceLocatorMethod,\n} from '../types/types';\nimport {\n DEFAULT_OBJECTS,\n KubernetesFanOutHandler,\n} from './KubernetesFanOutHandler';\nimport { KubernetesClientBasedFetcher } from './KubernetesFetcher';\nimport { KubernetesProxy } from './KubernetesProxy';\n\n/**\n *\n * @public\n */\nexport interface KubernetesEnvironment {\n logger: LoggerService;\n config: Config;\n catalogApi: CatalogApi;\n discovery: DiscoveryService;\n permissions: PermissionEvaluator;\n auth?: AuthService;\n httpAuth?: HttpAuthService;\n}\n\n/**\n * The return type of the `KubernetesBuilder.build` method\n *\n * @public\n */\nexport type KubernetesBuilderReturn = Promise<{\n router: express.Router;\n clusterSupplier: KubernetesClustersSupplier;\n customResources: CustomResource[];\n fetcher: KubernetesFetcher;\n proxy: KubernetesProxy;\n objectsProvider: KubernetesObjectsProvider;\n serviceLocator: KubernetesServiceLocator;\n authStrategyMap: { [key: string]: AuthenticationStrategy };\n}>;\n\n/**\n *\n * @public\n */\nexport class KubernetesBuilder {\n private clusterSupplier?: KubernetesClustersSupplier;\n private defaultClusterRefreshInterval: Duration = Duration.fromObject({\n minutes: 60,\n });\n private objectsProvider?: KubernetesObjectsProvider;\n private fetcher?: KubernetesFetcher;\n private serviceLocator?: KubernetesServiceLocator;\n private proxy?: KubernetesProxy;\n private authStrategyMap?: { [key: string]: AuthenticationStrategy };\n\n static createBuilder(env: KubernetesEnvironment) {\n return new KubernetesBuilder(env);\n }\n\n constructor(protected readonly env: KubernetesEnvironment) {}\n\n public async build(): KubernetesBuilderReturn {\n const logger = this.env.logger;\n const config = this.env.config;\n const permissions = this.env.permissions;\n\n logger.info('Initializing Kubernetes backend');\n\n if (!config.has('kubernetes')) {\n if (process.env.NODE_ENV !== 'development') {\n throw new Error('Kubernetes configuration is missing');\n }\n logger.warn(\n 'Failed to initialize kubernetes backend: kubernetes config is missing',\n );\n return {\n router: Router(),\n } as unknown as KubernetesBuilderReturn;\n }\n\n const { auth, httpAuth } = createLegacyAuthAdapters({\n auth: this.env.auth,\n httpAuth: this.env.httpAuth,\n discovery: this.env.discovery,\n });\n\n const customResources = this.buildCustomResources();\n\n const fetcher = this.getFetcher();\n\n const clusterSupplier = this.getClusterSupplier();\n\n const authStrategyMap = this.getAuthStrategyMap();\n\n const proxy = this.getProxy(\n logger,\n clusterSupplier,\n this.env.discovery,\n httpAuth,\n );\n\n const serviceLocator = this.getServiceLocator();\n\n const objectsProvider = this.getObjectsProvider({\n logger,\n fetcher,\n config,\n serviceLocator,\n customResources,\n objectTypesToFetch: this.getObjectTypesToFetch(),\n });\n\n const router = this.buildRouter(\n objectsProvider,\n clusterSupplier,\n this.env.catalogApi,\n proxy,\n permissions,\n auth,\n httpAuth,\n );\n\n return {\n clusterSupplier,\n customResources,\n fetcher,\n proxy,\n objectsProvider,\n router,\n serviceLocator,\n authStrategyMap,\n };\n }\n\n public setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier) {\n this.clusterSupplier = clusterSupplier;\n return this;\n }\n\n public setDefaultClusterRefreshInterval(refreshInterval: Duration) {\n this.defaultClusterRefreshInterval = refreshInterval;\n return this;\n }\n\n public setObjectsProvider(objectsProvider?: KubernetesObjectsProvider) {\n this.objectsProvider = objectsProvider;\n return this;\n }\n\n public setFetcher(fetcher?: KubernetesFetcher) {\n this.fetcher = fetcher;\n return this;\n }\n\n public setServiceLocator(serviceLocator?: KubernetesServiceLocator) {\n this.serviceLocator = serviceLocator;\n return this;\n }\n\n public setProxy(proxy?: KubernetesProxy) {\n this.proxy = proxy;\n return this;\n }\n\n public setAuthStrategyMap(authStrategyMap: {\n [key: string]: AuthenticationStrategy;\n }) {\n this.authStrategyMap = authStrategyMap;\n }\n\n public addAuthStrategy(key: string, strategy: AuthenticationStrategy) {\n if (key.includes('-')) {\n throw new Error('Strategy name can not include dashes');\n }\n this.getAuthStrategyMap()[key] = strategy;\n return this;\n }\n\n protected buildCustomResources() {\n const customResources: CustomResource[] = (\n this.env.config.getOptionalConfigArray('kubernetes.customResources') ?? []\n ).map(\n c =>\n ({\n group: c.getString('group'),\n apiVersion: c.getString('apiVersion'),\n plural: c.getString('plural'),\n objectType: 'customresources',\n } as CustomResource),\n );\n\n this.env.logger.info(\n `action=LoadingCustomResources numOfCustomResources=${customResources.length}`,\n );\n return customResources;\n }\n\n protected buildClusterSupplier(\n refreshInterval: Duration,\n ): KubernetesClustersSupplier {\n const config = this.env.config;\n const { auth } = createLegacyAuthAdapters(this.env);\n this.clusterSupplier = getCombinedClusterSupplier(\n config,\n this.env.catalogApi,\n new DispatchStrategy({ authStrategyMap: this.getAuthStrategyMap() }),\n this.env.logger,\n refreshInterval,\n auth,\n );\n\n return this.clusterSupplier;\n }\n\n protected buildObjectsProvider(\n options: KubernetesObjectsProviderOptions,\n ): KubernetesObjectsProvider {\n const authStrategyMap = this.getAuthStrategyMap();\n this.objectsProvider = new KubernetesFanOutHandler({\n ...options,\n authStrategy: new DispatchStrategy({\n authStrategyMap,\n }),\n });\n\n return this.objectsProvider;\n }\n\n protected buildFetcher(): KubernetesFetcher {\n this.fetcher = new KubernetesClientBasedFetcher({\n logger: this.env.logger,\n });\n\n return this.fetcher;\n }\n\n protected buildServiceLocator(\n method: ServiceLocatorMethod,\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n switch (method) {\n case 'multiTenant':\n this.serviceLocator =\n this.buildMultiTenantServiceLocator(clusterSupplier);\n break;\n case 'singleTenant':\n this.serviceLocator =\n this.buildSingleTenantServiceLocator(clusterSupplier);\n break;\n case 'catalogRelation':\n this.serviceLocator =\n this.buildCatalogRelationServiceLocator(clusterSupplier);\n break;\n case 'http':\n this.serviceLocator = this.buildHttpServiceLocator(clusterSupplier);\n break;\n default:\n throw new Error(\n `Unsupported kubernetes.serviceLocatorMethod \"${method}\"`,\n );\n }\n\n return this.serviceLocator;\n }\n\n protected buildMultiTenantServiceLocator(\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n return new MultiTenantServiceLocator(clusterSupplier);\n }\n\n protected buildSingleTenantServiceLocator(\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n return new SingleTenantServiceLocator(clusterSupplier);\n }\n\n protected buildCatalogRelationServiceLocator(\n clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n return new CatalogRelationServiceLocator(clusterSupplier);\n }\n\n protected buildHttpServiceLocator(\n _clusterSupplier: KubernetesClustersSupplier,\n ): KubernetesServiceLocator {\n throw new Error('not implemented');\n }\n\n protected buildProxy(\n logger: LoggerService,\n clusterSupplier: KubernetesClustersSupplier,\n discovery: DiscoveryService,\n httpAuth: HttpAuthService,\n ): KubernetesProxy {\n const authStrategyMap = this.getAuthStrategyMap();\n const authStrategy = new DispatchStrategy({\n authStrategyMap,\n });\n this.proxy = new KubernetesProxy({\n logger,\n clusterSupplier,\n authStrategy,\n discovery,\n httpAuth,\n });\n return this.proxy;\n }\n\n protected buildRouter(\n objectsProvider: KubernetesObjectsProvider,\n clusterSupplier: KubernetesClustersSupplier,\n catalogApi: CatalogApi,\n proxy: KubernetesProxy,\n permissionApi: PermissionEvaluator,\n authService: AuthService,\n httpAuth: HttpAuthService,\n ): express.Router {\n const logger = this.env.logger;\n const router = Router();\n router.use('/proxy', proxy.createRequestHandler({ permissionApi }));\n router.use(express.json());\n router.use(\n createPermissionIntegrationRouter({\n permissions: kubernetesPermissions,\n }),\n );\n // @deprecated\n router.post('/services/:serviceId', async (req, res) => {\n const serviceId = req.params.serviceId;\n const requestBody: ObjectsByEntityRequest = req.body;\n try {\n const response = await objectsProvider.getKubernetesObjectsByEntity(\n {\n entity: requestBody.entity,\n auth: requestBody.auth || {},\n },\n { credentials: await httpAuth.credentials(req) },\n );\n res.json(response);\n } catch (e) {\n logger.error(\n `action=retrieveObjectsByServiceId service=${serviceId}, error=${e}`,\n );\n res.status(500).json({ error: e.message });\n }\n });\n\n router.get('/clusters', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const clusterDetails = await this.fetchClusterDetails(clusterSupplier, {\n credentials,\n });\n res.json({\n items: clusterDetails.map(cd => {\n const oidcTokenProvider =\n cd.authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];\n const authProvider =\n cd.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER];\n const strategy = this.getAuthStrategyMap()[authProvider];\n let auth: AuthMetadata = {};\n if (strategy) {\n auth = strategy.presentAuthMetadata(cd.authMetadata);\n }\n\n return {\n name: cd.name,\n title: cd.title,\n dashboardUrl: cd.dashboardUrl,\n authProvider,\n ...(oidcTokenProvider && { oidcTokenProvider }),\n ...(auth && Object.keys(auth).length !== 0 && { auth }),\n };\n }),\n });\n });\n\n addResourceRoutesToRouter(\n router,\n catalogApi,\n objectsProvider,\n authService,\n httpAuth,\n );\n\n return router;\n }\n\n protected buildAuthStrategyMap() {\n this.authStrategyMap = {\n aks: new AksStrategy(),\n aws: new AwsIamStrategy({ config: this.env.config }),\n azure: new AzureIdentityStrategy(this.env.logger),\n google: new GoogleStrategy(),\n googleServiceAccount: new GoogleServiceAccountStrategy(),\n localKubectlProxy: new AnonymousStrategy(),\n oidc: new OidcStrategy(),\n serviceAccount: new ServiceAccountStrategy(),\n };\n return this.authStrategyMap;\n }\n\n protected async fetchClusterDetails(\n clusterSupplier: KubernetesClustersSupplier,\n options: { credentials: BackstageCredentials },\n ) {\n const clusterDetails = await clusterSupplier.getClusters(options);\n\n this.env.logger.info(\n `action=loadClusterDetails numOfClustersLoaded=${clusterDetails.length}`,\n );\n\n return clusterDetails;\n }\n\n protected getServiceLocatorMethod() {\n return this.env.config.getString(\n 'kubernetes.serviceLocatorMethod.type',\n ) as ServiceLocatorMethod;\n }\n\n protected getFetcher(): KubernetesFetcher {\n return this.fetcher ?? this.buildFetcher();\n }\n\n protected getClusterSupplier() {\n return (\n this.clusterSupplier ??\n this.buildClusterSupplier(this.defaultClusterRefreshInterval)\n );\n }\n\n protected getServiceLocator(): KubernetesServiceLocator {\n return (\n this.serviceLocator ??\n this.buildServiceLocator(\n this.getServiceLocatorMethod(),\n this.getClusterSupplier(),\n )\n );\n }\n\n protected getObjectsProvider(options: KubernetesObjectsProviderOptions) {\n return this.objectsProvider ?? this.buildObjectsProvider(options);\n }\n\n protected getObjectTypesToFetch() {\n const objectTypesToFetchStrings = this.env.config.getOptionalStringArray(\n 'kubernetes.objectTypes',\n ) as KubernetesObjectTypes[];\n\n const apiVersionOverrides = this.env.config.getOptionalConfig(\n 'kubernetes.apiVersionOverrides',\n );\n\n let objectTypesToFetch;\n\n if (objectTypesToFetchStrings) {\n objectTypesToFetch = DEFAULT_OBJECTS.filter(obj =>\n objectTypesToFetchStrings.includes(obj.objectType),\n );\n }\n\n if (apiVersionOverrides) {\n objectTypesToFetch = objectTypesToFetch ?? DEFAULT_OBJECTS;\n\n for (const obj of objectTypesToFetch) {\n if (apiVersionOverrides.has(obj.objectType)) {\n obj.apiVersion = apiVersionOverrides.getString(obj.objectType);\n }\n }\n }\n\n return objectTypesToFetch;\n }\n\n protected getProxy(\n logger: LoggerService,\n clusterSupplier: KubernetesClustersSupplier,\n discovery: DiscoveryService,\n httpAuth: HttpAuthService,\n ) {\n return (\n this.proxy ??\n this.buildProxy(logger, clusterSupplier, discovery, httpAuth)\n );\n }\n\n protected getAuthStrategyMap() {\n return this.authStrategyMap ?? this.buildAuthStrategyMap();\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { Logger } from 'winston';\nimport { KubernetesClustersSupplier } from '../types/types';\nimport express from 'express';\nimport { KubernetesBuilder } from './KubernetesBuilder';\nimport { PluginEndpointDiscovery } from '@backstage/backend-common';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\n\n/**\n *\n * @public\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n catalogApi: CatalogApi;\n clusterSupplier?: KubernetesClustersSupplier;\n discovery: PluginEndpointDiscovery;\n permissions: PermissionEvaluator;\n}\n\n/**\n * creates and configure a new router for handling the kubernetes backend APIs\n * @param options - specifies the options required by this plugin\n * @returns a new router\n * @deprecated Please use the new KubernetesBuilder instead like this\n * ```\n * import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';\n * const { router } = await KubernetesBuilder.createBuilder({\n * logger,\n * config,\n * }).build();\n * ```\n *\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { router } = await KubernetesBuilder.createBuilder(options)\n .setClusterSupplier(options.clusterSupplier)\n .build();\n return router;\n}\n"],"names":["__publicField","DefaultAwsCredentialsManager","ANNOTATION_KUBERNETES_AWS_CLUSTER_ID","ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE","ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID","fromTemporaryCredentials","SignatureV4","Sha256","_a","DefaultAzureCredential","container","ANNOTATION_KUBERNETES_AUTH_PROVIDER","KubeConfig","fs","ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER","ForwardedError","ANNOTATION_KUBERNETES_API_SERVER","ANNOTATION_KUBERNETES_API_SERVER_CA","CATALOG_FILTER_EXISTS","ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP","ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY","ANNOTATION_KUBERNETES_DASHBOARD_URL","ANNOTATION_KUBERNETES_DASHBOARD_APP","ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS","dns","InputError","parseEntityRef","stringifyEntityRef","_b","lodash","topPods","fetch","Config","https","bufferFromFileOrString","createLegacyAuthAdapters","kubernetesProxyPermission","AuthorizeResult","NotAllowedError","createProxyMiddleware","loggerToWinstonLogger","serializeError","NotFoundError","Duration","Router","express","createPermissionIntegrationRouter","kubernetesPermissions"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,14 +2,14 @@ import * as k8sTypes from '@backstage/plugin-kubernetes-node';
2
2
  import { AuthenticationStrategy as AuthenticationStrategy$1, ClusterDetails as ClusterDetails$1, KubernetesCredential as KubernetesCredential$1, AuthMetadata as AuthMetadata$1, KubernetesClustersSupplier as KubernetesClustersSupplier$1, CustomResource as CustomResource$1, KubernetesFetcher as KubernetesFetcher$1, KubernetesObjectsProvider as KubernetesObjectsProvider$1, KubernetesServiceLocator as KubernetesServiceLocator$1 } from '@backstage/plugin-kubernetes-node';
3
3
  import { KubernetesRequestAuth, KubernetesRequestBody } from '@backstage/plugin-kubernetes-common';
4
4
  import { Config } from '@backstage/config';
5
- import { Logger } from 'winston';
6
5
  import { TokenCredential } from '@azure/identity';
6
+ import { LoggerService, PermissionsService, DiscoveryService, HttpAuthService, AuthService, BackstageCredentials } from '@backstage/backend-plugin-api';
7
7
  import { CatalogApi } from '@backstage/catalog-client';
8
8
  import { PermissionEvaluator } from '@backstage/plugin-permission-common';
9
9
  import express from 'express';
10
10
  import { Duration } from 'luxon';
11
- import { PermissionsService, DiscoveryService, HttpAuthService, AuthService, BackstageCredentials } from '@backstage/backend-plugin-api';
12
11
  import { RequestHandler } from 'http-proxy-middleware';
12
+ import { Logger } from 'winston';
13
13
  import { PluginEndpointDiscovery } from '@backstage/backend-common';
14
14
 
15
15
  /**
@@ -65,7 +65,7 @@ declare class AzureIdentityStrategy implements AuthenticationStrategy$1 {
65
65
  private readonly tokenCredential;
66
66
  private accessToken;
67
67
  private newTokenPromise;
68
- constructor(logger: Logger, tokenCredential?: TokenCredential);
68
+ constructor(logger: LoggerService, tokenCredential?: TokenCredential);
69
69
  getCredential(): Promise<KubernetesCredential$1>;
70
70
  validateCluster(): Error[];
71
71
  private fetchNewToken;
@@ -154,7 +154,7 @@ type ServiceLocatorMethod = 'multiTenant' | 'singleTenant' | 'catalogRelation' |
154
154
  * @public
155
155
  */
156
156
  interface KubernetesObjectsProviderOptions {
157
- logger: Logger;
157
+ logger: LoggerService;
158
158
  config: Config;
159
159
  fetcher: k8sTypes.KubernetesFetcher;
160
160
  serviceLocator: k8sTypes.KubernetesServiceLocator;
@@ -248,7 +248,7 @@ type KubernetesProxyCreateRequestHandlerOptions = {
248
248
  * @public
249
249
  */
250
250
  type KubernetesProxyOptions = {
251
- logger: Logger;
251
+ logger: LoggerService;
252
252
  clusterSupplier: KubernetesClustersSupplier;
253
253
  authStrategy: AuthenticationStrategy;
254
254
  discovery: DiscoveryService;
@@ -279,7 +279,7 @@ declare class KubernetesProxy {
279
279
  * @public
280
280
  */
281
281
  interface KubernetesEnvironment {
282
- logger: Logger;
282
+ logger: LoggerService;
283
283
  config: Config;
284
284
  catalogApi: CatalogApi;
285
285
  discovery: DiscoveryService;
@@ -339,7 +339,7 @@ declare class KubernetesBuilder {
339
339
  protected buildSingleTenantServiceLocator(clusterSupplier: KubernetesClustersSupplier$1): KubernetesServiceLocator$1;
340
340
  protected buildCatalogRelationServiceLocator(clusterSupplier: KubernetesClustersSupplier$1): KubernetesServiceLocator$1;
341
341
  protected buildHttpServiceLocator(_clusterSupplier: KubernetesClustersSupplier$1): KubernetesServiceLocator$1;
342
- protected buildProxy(logger: Logger, clusterSupplier: KubernetesClustersSupplier$1, discovery: DiscoveryService, httpAuth: HttpAuthService): KubernetesProxy;
342
+ protected buildProxy(logger: LoggerService, clusterSupplier: KubernetesClustersSupplier$1, discovery: DiscoveryService, httpAuth: HttpAuthService): KubernetesProxy;
343
343
  protected buildRouter(objectsProvider: KubernetesObjectsProvider$1, clusterSupplier: KubernetesClustersSupplier$1, catalogApi: CatalogApi, proxy: KubernetesProxy, permissionApi: PermissionEvaluator, authService: AuthService, httpAuth: HttpAuthService): express.Router;
344
344
  protected buildAuthStrategyMap(): {
345
345
  [key: string]: AuthenticationStrategy$1;
@@ -353,7 +353,7 @@ declare class KubernetesBuilder {
353
353
  protected getServiceLocator(): KubernetesServiceLocator$1;
354
354
  protected getObjectsProvider(options: KubernetesObjectsProviderOptions): KubernetesObjectsProvider$1;
355
355
  protected getObjectTypesToFetch(): k8sTypes.ObjectToFetch[] | undefined;
356
- protected getProxy(logger: Logger, clusterSupplier: KubernetesClustersSupplier$1, discovery: DiscoveryService, httpAuth: HttpAuthService): KubernetesProxy;
356
+ protected getProxy(logger: LoggerService, clusterSupplier: KubernetesClustersSupplier$1, discovery: DiscoveryService, httpAuth: HttpAuthService): KubernetesProxy;
357
357
  protected getAuthStrategyMap(): {
358
358
  [key: string]: AuthenticationStrategy$1;
359
359
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-kubernetes-backend",
3
3
  "description": "A Backstage backend plugin that integrates towards Kubernetes",
4
- "version": "0.17.0-next.1",
4
+ "version": "0.17.1-next.0",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -49,25 +49,25 @@
49
49
  "@aws-sdk/credential-providers": "^3.350.0",
50
50
  "@aws-sdk/signature-v4": "^3.347.0",
51
51
  "@azure/identity": "^4.0.0",
52
- "@backstage/backend-common": "^0.21.7-next.1",
53
- "@backstage/backend-plugin-api": "^0.6.17-next.1",
54
- "@backstage/catalog-client": "^1.6.4-next.0",
55
- "@backstage/catalog-model": "^1.4.5",
52
+ "@backstage/backend-common": "^0.21.8-next.0",
53
+ "@backstage/backend-plugin-api": "^0.6.18-next.0",
54
+ "@backstage/catalog-client": "^1.6.5-next.0",
55
+ "@backstage/catalog-model": "^1.5.0-next.0",
56
56
  "@backstage/config": "^1.2.0",
57
57
  "@backstage/errors": "^1.2.4",
58
58
  "@backstage/integration-aws-node": "^0.1.12",
59
- "@backstage/plugin-auth-node": "^0.4.12-next.1",
60
- "@backstage/plugin-catalog-node": "^1.11.1-next.1",
61
- "@backstage/plugin-kubernetes-common": "^0.7.5",
62
- "@backstage/plugin-kubernetes-node": "^0.1.11-next.1",
59
+ "@backstage/plugin-auth-node": "^0.4.13-next.0",
60
+ "@backstage/plugin-catalog-node": "^1.11.2-next.0",
61
+ "@backstage/plugin-kubernetes-common": "^0.7.6-next.0",
62
+ "@backstage/plugin-kubernetes-node": "^0.1.12-next.0",
63
63
  "@backstage/plugin-permission-common": "^0.7.13",
64
- "@backstage/plugin-permission-node": "^0.7.28-next.1",
64
+ "@backstage/plugin-permission-node": "^0.7.29-next.0",
65
65
  "@backstage/types": "^1.1.1",
66
66
  "@google-cloud/container": "^5.0.0",
67
67
  "@jest-mock/express": "^2.0.1",
68
68
  "@kubernetes/client-node": "0.20.0",
69
69
  "@types/express": "^4.17.6",
70
- "@types/http-proxy-middleware": "^0.19.3",
70
+ "@types/http-proxy-middleware": "^1.0.0",
71
71
  "@types/luxon": "^3.0.0",
72
72
  "compression": "^1.7.4",
73
73
  "cors": "^2.8.5",
@@ -85,11 +85,11 @@
85
85
  "yn": "^4.0.0"
86
86
  },
87
87
  "devDependencies": {
88
- "@backstage/backend-app-api": "^0.7.0-next.1",
89
- "@backstage/backend-test-utils": "^0.3.7-next.1",
90
- "@backstage/cli": "^0.26.3-next.1",
91
- "@backstage/plugin-permission-backend": "^0.5.41-next.1",
92
- "@backstage/plugin-permission-backend-module-allow-all-policy": "^0.1.14-next.1",
88
+ "@backstage/backend-app-api": "^0.7.1-next.0",
89
+ "@backstage/backend-test-utils": "^0.3.8-next.0",
90
+ "@backstage/cli": "^0.26.5-next.0",
91
+ "@backstage/plugin-permission-backend": "^0.5.42-next.0",
92
+ "@backstage/plugin-permission-backend-module-allow-all-policy": "^0.1.15-next.0",
93
93
  "@types/aws4": "^1.5.1",
94
94
  "msw": "^1.0.0",
95
95
  "supertest": "^6.1.3",