@backstage/plugin-kubernetes-backend 0.16.0-next.2 → 0.16.1

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,39 @@
1
1
  # @backstage/plugin-kubernetes-backend
2
2
 
3
+ ## 0.16.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/plugin-catalog-node@1.9.0
9
+ - @backstage/plugin-kubernetes-node@0.1.8
10
+
11
+ ## 0.16.0
12
+
13
+ ### Minor Changes
14
+
15
+ - e1e540c: **BREAKING**: The `KubernetesBuilder.createBuilder` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services.
16
+
17
+ ### Patch Changes
18
+
19
+ - b9a0888: Fixed a bug in the proxy endpoint. Now when the `serviceAccount` strategy is used and no `serviceAccountToken` has been provided, the proxy endpoint assumes backstage is running on Kubernetes and gets the URL and CA from the Pod instance.
20
+ - 69d0217: Pass user credentials when calling catalog get entities api.
21
+ - Updated dependencies
22
+ - @backstage/backend-common@0.21.4
23
+ - @backstage/plugin-auth-node@0.4.9
24
+ - @backstage/config@1.2.0
25
+ - @backstage/errors@1.2.4
26
+ - @backstage/backend-plugin-api@0.6.14
27
+ - @backstage/plugin-permission-common@0.7.13
28
+ - @backstage/plugin-catalog-node@1.8.0
29
+ - @backstage/plugin-kubernetes-node@0.1.8
30
+ - @backstage/catalog-client@1.6.1
31
+ - @backstage/plugin-permission-node@0.7.25
32
+ - @backstage/plugin-kubernetes-common@0.7.5
33
+ - @backstage/catalog-model@1.4.5
34
+ - @backstage/integration-aws-node@0.1.10
35
+ - @backstage/types@1.1.1
36
+
3
37
  ## 0.16.0-next.2
4
38
 
5
39
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-kubernetes-backend",
3
- "version": "0.16.0-next.2",
3
+ "version": "0.16.1",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/alpha.cjs.js CHANGED
@@ -163,5 +163,5 @@ const kubernetesPlugin = backendPluginApi.createBackendPlugin({
163
163
  }
164
164
  });
165
165
 
166
- exports["default"] = kubernetesPlugin;
166
+ exports.default = kubernetesPlugin;
167
167
  //# sourceMappingURL=alpha.cjs.js.map
package/dist/index.cjs.js CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var credentialProviders = require('@aws-sdk/credential-providers');
6
4
  var signatureV4 = require('@aws-sdk/signature-v4');
7
5
  var sha256Js = require('@aws-crypto/sha256-js');
@@ -18,6 +16,7 @@ var luxon = require('luxon');
18
16
  var errors = require('@backstage/errors');
19
17
  var catalogClient = require('@backstage/catalog-client');
20
18
  var dns = require('node:dns');
19
+ var backendCommon = require('@backstage/backend-common');
21
20
  var catalogModel = require('@backstage/catalog-model');
22
21
  var lodash = require('lodash');
23
22
  var fetch = require('node-fetch');
@@ -25,12 +24,11 @@ var https = require('https');
25
24
  var pluginAuthNode = require('@backstage/plugin-auth-node');
26
25
  var pluginPermissionCommon = require('@backstage/plugin-permission-common');
27
26
  var httpProxyMiddleware = require('http-proxy-middleware');
28
- var backendCommon = require('@backstage/backend-common');
29
27
 
30
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
28
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
31
29
 
32
- function _interopNamespace(e) {
33
- if (e && e.__esModule) return e;
30
+ function _interopNamespaceCompat(e) {
31
+ if (e && typeof e === 'object' && 'default' in e) return e;
34
32
  var n = Object.create(null);
35
33
  if (e) {
36
34
  Object.keys(e).forEach(function (k) {
@@ -43,18 +41,18 @@ function _interopNamespace(e) {
43
41
  }
44
42
  });
45
43
  }
46
- n["default"] = e;
44
+ n.default = e;
47
45
  return Object.freeze(n);
48
46
  }
49
47
 
50
- var container__namespace = /*#__PURE__*/_interopNamespace(container);
51
- var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
52
- var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
53
- var Router__default = /*#__PURE__*/_interopDefaultLegacy(Router);
54
- var dns__default = /*#__PURE__*/_interopDefaultLegacy(dns);
55
- var lodash__default = /*#__PURE__*/_interopDefaultLegacy(lodash);
56
- var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
57
- var https__namespace = /*#__PURE__*/_interopNamespace(https);
48
+ var container__namespace = /*#__PURE__*/_interopNamespaceCompat(container);
49
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
50
+ var express__default = /*#__PURE__*/_interopDefaultCompat(express);
51
+ var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
52
+ var dns__default = /*#__PURE__*/_interopDefaultCompat(dns);
53
+ var lodash__default = /*#__PURE__*/_interopDefaultCompat(lodash);
54
+ var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
55
+ var https__namespace = /*#__PURE__*/_interopNamespaceCompat(https);
58
56
 
59
57
  class AksStrategy {
60
58
  async getCredential(_, requestAuth) {
@@ -81,16 +79,16 @@ class AnonymousStrategy {
81
79
  }
82
80
  }
83
81
 
84
- var __defProp$b = Object.defineProperty;
85
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
86
- var __publicField$b = (obj, key, value) => {
87
- __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
82
+ var __defProp$c = Object.defineProperty;
83
+ var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
84
+ var __publicField$c = (obj, key, value) => {
85
+ __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
88
86
  return value;
89
87
  };
90
88
  const defaultRegion = "us-east-1";
91
89
  class AwsIamStrategy {
92
90
  constructor(opts) {
93
- __publicField$b(this, "credsManager");
91
+ __publicField$c(this, "credsManager");
94
92
  this.credsManager = integrationAwsNode.DefaultAwsCredentialsManager.fromConfig(opts.config);
95
93
  }
96
94
  async getCredential(clusterDetails) {
@@ -162,10 +160,10 @@ class AwsIamStrategy {
162
160
  }
163
161
  }
164
162
 
165
- var __defProp$a = Object.defineProperty;
166
- var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
167
- var __publicField$a = (obj, key, value) => {
168
- __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
163
+ var __defProp$b = Object.defineProperty;
164
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
165
+ var __publicField$b = (obj, key, value) => {
166
+ __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
169
167
  return value;
170
168
  };
171
169
  const aksScope = "6dae42f8-4368-4678-94ff-3960e28e3630/.default";
@@ -173,8 +171,8 @@ class AzureIdentityStrategy {
173
171
  constructor(logger, tokenCredential = new identity.DefaultAzureCredential()) {
174
172
  this.logger = logger;
175
173
  this.tokenCredential = tokenCredential;
176
- __publicField$a(this, "accessToken", { token: "", expiresOnTimestamp: 0 });
177
- __publicField$a(this, "newTokenPromise");
174
+ __publicField$b(this, "accessToken", { token: "", expiresOnTimestamp: 0 });
175
+ __publicField$b(this, "newTokenPromise");
178
176
  }
179
177
  async getCredential() {
180
178
  if (!this.tokenRequiresRefresh()) {
@@ -257,15 +255,15 @@ class GoogleServiceAccountStrategy {
257
255
  }
258
256
  }
259
257
 
260
- var __defProp$9 = Object.defineProperty;
261
- var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
262
- var __publicField$9 = (obj, key, value) => {
263
- __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
258
+ var __defProp$a = Object.defineProperty;
259
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
260
+ var __publicField$a = (obj, key, value) => {
261
+ __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
264
262
  return value;
265
263
  };
266
264
  class DispatchStrategy {
267
265
  constructor(options) {
268
- __publicField$9(this, "strategyMap");
266
+ __publicField$a(this, "strategyMap");
269
267
  this.strategyMap = options.authStrategyMap;
270
268
  }
271
269
  getCredential(clusterDetails, auth) {
@@ -305,7 +303,7 @@ class ServiceAccountStrategy {
305
303
  const user = kc.getCurrentUser();
306
304
  return {
307
305
  type: "bearer token",
308
- token: fs__default["default"].readFileSync(user.authProvider.config.tokenFile).toString()
306
+ token: fs__default.default.readFileSync(user.authProvider.config.tokenFile).toString()
309
307
  };
310
308
  }
311
309
  validateCluster() {
@@ -345,15 +343,15 @@ class OidcStrategy {
345
343
  }
346
344
  }
347
345
 
348
- var __defProp$8 = Object.defineProperty;
349
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
350
- var __publicField$8 = (obj, key, value) => {
351
- __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
346
+ var __defProp$9 = Object.defineProperty;
347
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
348
+ var __publicField$9 = (obj, key, value) => {
349
+ __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
352
350
  return value;
353
351
  };
354
352
  class ConfigClusterLocator {
355
353
  constructor(clusterDetails) {
356
- __publicField$8(this, "clusterDetails");
354
+ __publicField$9(this, "clusterDetails");
357
355
  this.clusterDetails = clusterDetails;
358
356
  }
359
357
  static fromConfig(config, authStrategy) {
@@ -473,7 +471,7 @@ function runPeriodically(fn, delayMs) {
473
471
 
474
472
  var name = "@backstage/plugin-kubernetes-backend";
475
473
  var description = "A Backstage backend plugin that integrates towards Kubernetes";
476
- var version = "0.16.0-next.2";
474
+ var version = "0.16.1";
477
475
  var main = "src/index.ts";
478
476
  var types = "src/index.ts";
479
477
  var license = "Apache-2.0";
@@ -696,10 +694,10 @@ class GkeClusterLocator {
696
694
  }
697
695
  }
698
696
 
699
- var __defProp$7 = Object.defineProperty;
700
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
701
- var __publicField$7 = (obj, key, value) => {
702
- __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
697
+ var __defProp$8 = Object.defineProperty;
698
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
699
+ var __publicField$8 = (obj, key, value) => {
700
+ __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
703
701
  return value;
704
702
  };
705
703
  function isObject(obj) {
@@ -707,8 +705,8 @@ function isObject(obj) {
707
705
  }
708
706
  class CatalogClusterLocator {
709
707
  constructor(catalogClient, auth) {
710
- __publicField$7(this, "catalogClient");
711
- __publicField$7(this, "auth");
708
+ __publicField$8(this, "catalogClient");
709
+ __publicField$8(this, "auth");
712
710
  this.catalogClient = catalogClient;
713
711
  this.auth = auth;
714
712
  }
@@ -768,18 +766,18 @@ class CatalogClusterLocator {
768
766
  }
769
767
  }
770
768
 
771
- var __defProp$6 = Object.defineProperty;
772
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
773
- var __publicField$6 = (obj, key, value) => {
774
- __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
769
+ var __defProp$7 = Object.defineProperty;
770
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
771
+ var __publicField$7 = (obj, key, value) => {
772
+ __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
775
773
  return value;
776
774
  };
777
775
  class LocalKubectlProxyClusterLocator {
778
776
  constructor() {
779
- __publicField$6(this, "clusterDetails");
777
+ __publicField$7(this, "clusterDetails");
780
778
  // verbatim: when false, IPv4 addresses are placed before IPv6 addresses, ignoring the order from the DNS resolver
781
779
  // By default kubectl proxy listens on 127.0.0.1 instead of [::1]
782
- __publicField$6(this, "lookupPromise", dns__default["default"].promises.lookup("localhost", { verbatim: false }));
780
+ __publicField$7(this, "lookupPromise", dns__default.default.promises.lookup("localhost", { verbatim: false }));
783
781
  this.clusterDetails = [
784
782
  {
785
783
  name: "local",
@@ -908,6 +906,42 @@ const addResourceRoutesToRouter = (router, catalogApi, objectsProvider, auth, ht
908
906
  });
909
907
  };
910
908
 
909
+ var __defProp$6 = Object.defineProperty;
910
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
911
+ var __publicField$6 = (obj, key, value) => {
912
+ __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
913
+ return value;
914
+ };
915
+ class CatalogRelationServiceLocator {
916
+ constructor(clusterSupplier) {
917
+ __publicField$6(this, "clusterSupplier");
918
+ this.clusterSupplier = clusterSupplier;
919
+ }
920
+ // As this implementation always returns all clusters serviceId is ignored here
921
+ getClustersByEntity(entity, _requestContext) {
922
+ if (entity.relations && entity.relations.some(
923
+ (r) => r.type === "dependsOn" && r.targetRef.includes("resource:")
924
+ )) {
925
+ return this.clusterSupplier.getClusters().then((clusters) => {
926
+ return {
927
+ clusters: clusters.filter(
928
+ (c) => this.doesEntityDependOnCluster(entity, c)
929
+ )
930
+ };
931
+ });
932
+ }
933
+ return Promise.resolve({ clusters: [] });
934
+ }
935
+ doesEntityDependOnCluster(entity, cluster) {
936
+ return entity.relations.some(
937
+ (rel) => {
938
+ var _a;
939
+ return rel.type === "dependsOn" && rel.targetRef === `resource:${(_a = entity.metadata.namespace) != null ? _a : "default"}/${cluster.name}`;
940
+ }
941
+ );
942
+ }
943
+ }
944
+
911
945
  var __defProp$5 = Object.defineProperty;
912
946
  var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
913
947
  var __publicField$5 = (obj, key, value) => {
@@ -1224,7 +1258,7 @@ var __publicField$2 = (obj, key, value) => {
1224
1258
  const isError = (fr) => fr.hasOwnProperty("errorType");
1225
1259
  function fetchResultsToResponseWrapper(results) {
1226
1260
  var _a, _b;
1227
- const groupBy = lodash__default["default"].groupBy(results, (value) => {
1261
+ const groupBy = lodash__default.default.groupBy(results, (value) => {
1228
1262
  return isError(value) ? "errors" : "responses";
1229
1263
  });
1230
1264
  return {
@@ -1358,10 +1392,10 @@ class KubernetesClientBasedFetcher {
1358
1392
  if (labelSelector) {
1359
1393
  url.search = `labelSelector=${encode(labelSelector)}`;
1360
1394
  }
1361
- return fetch__default["default"](url, requestInit);
1395
+ return fetch__default.default(url, requestInit);
1362
1396
  }
1363
1397
  isServiceAccountAuthentication(authProvider, clusterDetails) {
1364
- return authProvider === "serviceAccount" && !clusterDetails.authMetadata.serviceAccountToken && fs__default["default"].pathExistsSync(clientNode.Config.SERVICEACCOUNT_CA_PATH);
1398
+ return authProvider === "serviceAccount" && !clusterDetails.authMetadata.serviceAccountToken && fs__default.default.pathExistsSync(clientNode.Config.SERVICEACCOUNT_CA_PATH);
1365
1399
  }
1366
1400
  isCredentialMissing(authProvider, credential) {
1367
1401
  return authProvider !== "localKubectlProxy" && credential.type === "anonymous";
@@ -1411,7 +1445,7 @@ class KubernetesClientBasedFetcher {
1411
1445
  const url = new URL(cluster.server);
1412
1446
  if (url.protocol === "https:") {
1413
1447
  requestInit.agent = new https__namespace.Agent({
1414
- ca: fs__default["default"].readFileSync(cluster.caFile)
1448
+ ca: fs__default.default.readFileSync(cluster.caFile)
1415
1449
  });
1416
1450
  }
1417
1451
  return [url, requestInit];
@@ -1551,7 +1585,7 @@ class KubernetesProxy {
1551
1585
  throw new errors.NotFoundError(`Cluster '${clusterName}' not found`);
1552
1586
  }
1553
1587
  const authProvider = cluster.authMetadata[pluginKubernetesCommon.ANNOTATION_KUBERNETES_AUTH_PROVIDER];
1554
- if (authProvider === "serviceAccount" && fs__default["default"].pathExistsSync(clientNode.Config.SERVICEACCOUNT_CA_PATH) && !cluster.authMetadata.serviceAccountToken) {
1588
+ if (authProvider === "serviceAccount" && fs__default.default.pathExistsSync(clientNode.Config.SERVICEACCOUNT_CA_PATH) && !cluster.authMetadata.serviceAccountToken) {
1555
1589
  const kc = new clientNode.KubeConfig();
1556
1590
  kc.loadFromCluster();
1557
1591
  const clusterFromKubeConfig = kc.getCurrentCluster();
@@ -1631,7 +1665,7 @@ class KubernetesBuilder {
1631
1665
  "Failed to initialize kubernetes backend: kubernetes config is missing"
1632
1666
  );
1633
1667
  return {
1634
- router: Router__default["default"]()
1668
+ router: Router__default.default()
1635
1669
  };
1636
1670
  }
1637
1671
  const { auth, httpAuth } = backendCommon.createLegacyAuthAdapters({
@@ -1759,6 +1793,9 @@ class KubernetesBuilder {
1759
1793
  case "singleTenant":
1760
1794
  this.serviceLocator = this.buildSingleTenantServiceLocator(clusterSupplier);
1761
1795
  break;
1796
+ case "catalogRelation":
1797
+ this.serviceLocator = this.buildCatalogRelationServiceLocator(clusterSupplier);
1798
+ break;
1762
1799
  case "http":
1763
1800
  this.serviceLocator = this.buildHttpServiceLocator(clusterSupplier);
1764
1801
  break;
@@ -1775,6 +1812,9 @@ class KubernetesBuilder {
1775
1812
  buildSingleTenantServiceLocator(clusterSupplier) {
1776
1813
  return new SingleTenantServiceLocator(clusterSupplier);
1777
1814
  }
1815
+ buildCatalogRelationServiceLocator(clusterSupplier) {
1816
+ return new CatalogRelationServiceLocator(clusterSupplier);
1817
+ }
1778
1818
  buildHttpServiceLocator(_clusterSupplier) {
1779
1819
  throw new Error("not implemented");
1780
1820
  }
@@ -1792,9 +1832,9 @@ class KubernetesBuilder {
1792
1832
  }
1793
1833
  buildRouter(objectsProvider, clusterSupplier, catalogApi, proxy, permissionApi, authService, httpAuth) {
1794
1834
  const logger = this.env.logger;
1795
- const router = Router__default["default"]();
1835
+ const router = Router__default.default();
1796
1836
  router.use("/proxy", proxy.createRequestHandler({ permissionApi }));
1797
- router.use(express__default["default"].json());
1837
+ router.use(express__default.default.json());
1798
1838
  router.use(
1799
1839
  pluginPermissionNode.createPermissionIntegrationRouter({
1800
1840
  permissions: pluginKubernetesCommon.kubernetesPermissions