@backstage/plugin-kubernetes-backend 0.7.0-next.3 → 0.7.1-next.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/dist/index.cjs.js CHANGED
@@ -7,12 +7,13 @@ var Router = require('express-promise-router');
7
7
  var luxon = require('luxon');
8
8
  var errors = require('@backstage/errors');
9
9
  var container = require('@google-cloud/container');
10
+ var catalogClient = require('@backstage/catalog-client');
11
+ var catalogModel = require('@backstage/catalog-model');
10
12
  var clientNode = require('@kubernetes/client-node');
11
13
  var AWS = require('aws-sdk');
12
14
  var aws4 = require('aws4');
13
15
  var identity = require('@azure/identity');
14
16
  var lodash = require('lodash');
15
- var catalogModel = require('@backstage/catalog-model');
16
17
  var pluginAuthNode = require('@backstage/plugin-auth-node');
17
18
 
18
19
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -46,56 +47,60 @@ class ConfigClusterLocator {
46
47
  this.clusterDetails = clusterDetails;
47
48
  }
48
49
  static fromConfig(config) {
49
- return new ConfigClusterLocator(config.getConfigArray("clusters").map((c) => {
50
- var _a, _b;
51
- const authProvider = c.getString("authProvider");
52
- const clusterDetails = {
53
- name: c.getString("name"),
54
- url: c.getString("url"),
55
- serviceAccountToken: c.getOptionalString("serviceAccountToken"),
56
- skipTLSVerify: (_a = c.getOptionalBoolean("skipTLSVerify")) != null ? _a : false,
57
- skipMetricsLookup: (_b = c.getOptionalBoolean("skipMetricsLookup")) != null ? _b : false,
58
- caData: c.getOptionalString("caData"),
59
- authProvider
60
- };
61
- const dashboardUrl = c.getOptionalString("dashboardUrl");
62
- if (dashboardUrl) {
63
- clusterDetails.dashboardUrl = dashboardUrl;
64
- }
65
- const dashboardApp = c.getOptionalString("dashboardApp");
66
- if (dashboardApp) {
67
- clusterDetails.dashboardApp = dashboardApp;
68
- }
69
- if (c.has("dashboardParameters")) {
70
- clusterDetails.dashboardParameters = c.get("dashboardParameters");
71
- }
72
- switch (authProvider) {
73
- case "google": {
74
- return clusterDetails;
75
- }
76
- case "aws": {
77
- const assumeRole = c.getOptionalString("assumeRole");
78
- const externalId = c.getOptionalString("externalId");
79
- return { assumeRole, externalId, ...clusterDetails };
80
- }
81
- case "azure": {
82
- return clusterDetails;
83
- }
84
- case "oidc": {
85
- const oidcTokenProvider = c.getString("oidcTokenProvider");
86
- return { oidcTokenProvider, ...clusterDetails };
50
+ return new ConfigClusterLocator(
51
+ config.getConfigArray("clusters").map((c) => {
52
+ var _a, _b;
53
+ const authProvider = c.getString("authProvider");
54
+ const clusterDetails = {
55
+ name: c.getString("name"),
56
+ url: c.getString("url"),
57
+ serviceAccountToken: c.getOptionalString("serviceAccountToken"),
58
+ skipTLSVerify: (_a = c.getOptionalBoolean("skipTLSVerify")) != null ? _a : false,
59
+ skipMetricsLookup: (_b = c.getOptionalBoolean("skipMetricsLookup")) != null ? _b : false,
60
+ caData: c.getOptionalString("caData"),
61
+ authProvider
62
+ };
63
+ const dashboardUrl = c.getOptionalString("dashboardUrl");
64
+ if (dashboardUrl) {
65
+ clusterDetails.dashboardUrl = dashboardUrl;
87
66
  }
88
- case "serviceAccount": {
89
- return clusterDetails;
67
+ const dashboardApp = c.getOptionalString("dashboardApp");
68
+ if (dashboardApp) {
69
+ clusterDetails.dashboardApp = dashboardApp;
90
70
  }
91
- case "googleServiceAccount": {
92
- return clusterDetails;
71
+ if (c.has("dashboardParameters")) {
72
+ clusterDetails.dashboardParameters = c.get("dashboardParameters");
93
73
  }
94
- default: {
95
- throw new Error(`authProvider "${authProvider}" has no config associated with it`);
74
+ switch (authProvider) {
75
+ case "google": {
76
+ return clusterDetails;
77
+ }
78
+ case "aws": {
79
+ const assumeRole = c.getOptionalString("assumeRole");
80
+ const externalId = c.getOptionalString("externalId");
81
+ return { assumeRole, externalId, ...clusterDetails };
82
+ }
83
+ case "azure": {
84
+ return clusterDetails;
85
+ }
86
+ case "oidc": {
87
+ const oidcTokenProvider = c.getString("oidcTokenProvider");
88
+ return { oidcTokenProvider, ...clusterDetails };
89
+ }
90
+ case "serviceAccount": {
91
+ return clusterDetails;
92
+ }
93
+ case "googleServiceAccount": {
94
+ return clusterDetails;
95
+ }
96
+ default: {
97
+ throw new Error(
98
+ `authProvider "${authProvider}" has no config associated with it`
99
+ );
100
+ }
96
101
  }
97
- }
98
- }));
102
+ })
103
+ );
99
104
  }
100
105
  async getClusters() {
101
106
  return this.clusterDetails;
@@ -149,12 +154,19 @@ class GkeClusterLocator {
149
154
  };
150
155
  const gkeClusterLocator = new GkeClusterLocator(options, client);
151
156
  if (refreshInterval) {
152
- runPeriodically(() => gkeClusterLocator.refreshClusters(), refreshInterval.toMillis());
157
+ runPeriodically(
158
+ () => gkeClusterLocator.refreshClusters(),
159
+ refreshInterval.toMillis()
160
+ );
153
161
  }
154
162
  return gkeClusterLocator;
155
163
  }
156
164
  static fromConfig(config, refreshInterval = void 0) {
157
- return GkeClusterLocator.fromConfigWithClient(config, new container__namespace.v1.ClusterManagerClient(), refreshInterval);
165
+ return GkeClusterLocator.fromConfigWithClient(
166
+ config,
167
+ new container__namespace.v1.ClusterManagerClient(),
168
+ refreshInterval
169
+ );
158
170
  }
159
171
  async getClusters() {
160
172
  var _a;
@@ -205,11 +217,47 @@ class GkeClusterLocator {
205
217
  });
206
218
  this.hasClusterDetails = true;
207
219
  } catch (e) {
208
- throw new errors.ForwardedError(`There was an error retrieving clusters from GKE for projectId=${projectId} region=${region}`, e);
220
+ throw new errors.ForwardedError(
221
+ `There was an error retrieving clusters from GKE for projectId=${projectId} region=${region}`,
222
+ e
223
+ );
209
224
  }
210
225
  }
211
226
  }
212
227
 
228
+ class CatalogClusterLocator {
229
+ constructor(catalogClient) {
230
+ this.catalogClient = catalogClient;
231
+ }
232
+ static fromConfig(catalogApi) {
233
+ return new CatalogClusterLocator(catalogApi);
234
+ }
235
+ async getClusters() {
236
+ const apiServerKey = `metadata.annotations.${catalogModel.ANNOTATION_KUBERNETES_API_SERVER}`;
237
+ const apiServerCaKey = `metadata.annotations.${catalogModel.ANNOTATION_KUBERNETES_API_SERVER_CA}`;
238
+ const authProviderKey = `metadata.annotations.${catalogModel.ANNOTATION_KUBERNETES_AUTH_PROVIDER}`;
239
+ const filter = {
240
+ kind: "Resource",
241
+ "spec.type": "kubernetes-cluster",
242
+ [apiServerKey]: catalogClient.CATALOG_FILTER_EXISTS,
243
+ [apiServerCaKey]: catalogClient.CATALOG_FILTER_EXISTS,
244
+ [authProviderKey]: catalogClient.CATALOG_FILTER_EXISTS
245
+ };
246
+ const clusters = await this.catalogClient.getEntities({
247
+ filter: [filter]
248
+ });
249
+ return clusters.items.map((entity) => {
250
+ const clusterDetails = {
251
+ name: entity.metadata.name,
252
+ url: entity.metadata.annotations[catalogModel.ANNOTATION_KUBERNETES_API_SERVER],
253
+ caData: entity.metadata.annotations[catalogModel.ANNOTATION_KUBERNETES_API_SERVER_CA],
254
+ authProvider: entity.metadata.annotations[catalogModel.ANNOTATION_KUBERNETES_AUTH_PROVIDER]
255
+ };
256
+ return clusterDetails;
257
+ });
258
+ }
259
+ }
260
+
213
261
  class LocalKubectlProxyClusterLocator {
214
262
  constructor() {
215
263
  this.clusterDetails = [
@@ -231,25 +279,34 @@ class CombinedClustersSupplier {
231
279
  this.clusterSuppliers = clusterSuppliers;
232
280
  }
233
281
  async getClusters() {
234
- return await Promise.all(this.clusterSuppliers.map((supplier) => supplier.getClusters())).then((res) => {
282
+ return await Promise.all(
283
+ this.clusterSuppliers.map((supplier) => supplier.getClusters())
284
+ ).then((res) => {
235
285
  return res.flat();
236
286
  }).catch((e) => {
237
287
  throw e;
238
288
  });
239
289
  }
240
290
  }
241
- const getCombinedClusterSupplier = (rootConfig, refreshInterval = void 0) => {
291
+ const getCombinedClusterSupplier = (rootConfig, catalogClient, refreshInterval = void 0) => {
242
292
  const clusterSuppliers = rootConfig.getConfigArray("kubernetes.clusterLocatorMethods").map((clusterLocatorMethod) => {
243
293
  const type = clusterLocatorMethod.getString("type");
244
294
  switch (type) {
295
+ case "catalog":
296
+ return CatalogClusterLocator.fromConfig(catalogClient);
245
297
  case "localKubectlProxy":
246
298
  return new LocalKubectlProxyClusterLocator();
247
299
  case "config":
248
300
  return ConfigClusterLocator.fromConfig(clusterLocatorMethod);
249
301
  case "gke":
250
- return GkeClusterLocator.fromConfig(clusterLocatorMethod, refreshInterval);
302
+ return GkeClusterLocator.fromConfig(
303
+ clusterLocatorMethod,
304
+ refreshInterval
305
+ );
251
306
  default:
252
- throw new Error(`Unsupported kubernetes.clusterLocatorMethods: "${type}"`);
307
+ throw new Error(
308
+ `Unsupported kubernetes.clusterLocatorMethods: "${type}"`
309
+ );
253
310
  }
254
311
  });
255
312
  return new CombinedClustersSupplier(clusterSuppliers);
@@ -310,12 +367,17 @@ class KubernetesClientProvider {
310
367
 
311
368
  class GoogleKubernetesAuthTranslator {
312
369
  async decorateClusterDetailsWithAuth(clusterDetails, authConfig) {
313
- const clusterDetailsWithAuthToken = Object.assign({}, clusterDetails);
370
+ const clusterDetailsWithAuthToken = Object.assign(
371
+ {},
372
+ clusterDetails
373
+ );
314
374
  const authToken = authConfig.google;
315
375
  if (authToken) {
316
376
  clusterDetailsWithAuthToken.serviceAccountToken = authToken;
317
377
  } else {
318
- throw new Error("Google token not found under auth.google in request body");
378
+ throw new Error(
379
+ "Google token not found under auth.google in request body"
380
+ );
319
381
  }
320
382
  return clusterDetailsWithAuthToken;
321
383
  }
@@ -397,21 +459,33 @@ class AwsIamKubernetesAuthTranslator {
397
459
  return `k8s-aws-v1.${urlSafeBase64Url}`;
398
460
  }
399
461
  async decorateClusterDetailsWithAuth(clusterDetails) {
400
- const clusterDetailsWithAuthToken = Object.assign({}, clusterDetails);
401
- clusterDetailsWithAuthToken.serviceAccountToken = await this.getBearerToken(clusterDetails.name, clusterDetails.assumeRole, clusterDetails.externalId);
462
+ const clusterDetailsWithAuthToken = Object.assign(
463
+ {},
464
+ clusterDetails
465
+ );
466
+ clusterDetailsWithAuthToken.serviceAccountToken = await this.getBearerToken(
467
+ clusterDetails.name,
468
+ clusterDetails.assumeRole,
469
+ clusterDetails.externalId
470
+ );
402
471
  return clusterDetailsWithAuthToken;
403
472
  }
404
473
  }
405
474
 
406
475
  class GoogleServiceAccountAuthTranslator {
407
476
  async decorateClusterDetailsWithAuth(clusterDetails) {
408
- const clusterDetailsWithAuthToken = Object.assign({}, clusterDetails);
477
+ const clusterDetailsWithAuthToken = Object.assign(
478
+ {},
479
+ clusterDetails
480
+ );
409
481
  const client = new container__namespace.v1.ClusterManagerClient();
410
482
  const accessToken = await client.auth.getAccessToken();
411
483
  if (accessToken) {
412
484
  clusterDetailsWithAuthToken.serviceAccountToken = accessToken;
413
485
  } else {
414
- throw new Error("Unable to obtain access token for the current Google Application Default Credentials");
486
+ throw new Error(
487
+ "Unable to obtain access token for the current Google Application Default Credentials"
488
+ );
415
489
  }
416
490
  return clusterDetailsWithAuthToken;
417
491
  }
@@ -425,7 +499,10 @@ class AzureIdentityKubernetesAuthTranslator {
425
499
  this.accessToken = { token: "", expiresOnTimestamp: 0 };
426
500
  }
427
501
  async decorateClusterDetailsWithAuth(clusterDetails) {
428
- const clusterDetailsWithAuthToken = Object.assign({}, clusterDetails);
502
+ const clusterDetailsWithAuthToken = Object.assign(
503
+ {},
504
+ clusterDetails
505
+ );
429
506
  clusterDetailsWithAuthToken.serviceAccountToken = await this.getToken();
430
507
  return clusterDetailsWithAuthToken;
431
508
  }
@@ -469,16 +546,23 @@ class AzureIdentityKubernetesAuthTranslator {
469
546
  class OidcKubernetesAuthTranslator {
470
547
  async decorateClusterDetailsWithAuth(clusterDetails, authConfig) {
471
548
  var _a;
472
- const clusterDetailsWithAuthToken = Object.assign({}, clusterDetails);
549
+ const clusterDetailsWithAuthToken = Object.assign(
550
+ {},
551
+ clusterDetails
552
+ );
473
553
  const { oidcTokenProvider } = clusterDetails;
474
554
  if (!oidcTokenProvider || oidcTokenProvider === "") {
475
- throw new Error(`oidc authProvider requires a configured oidcTokenProvider`);
555
+ throw new Error(
556
+ `oidc authProvider requires a configured oidcTokenProvider`
557
+ );
476
558
  }
477
559
  const authToken = (_a = authConfig.oidc) == null ? void 0 : _a[oidcTokenProvider];
478
560
  if (authToken) {
479
561
  clusterDetailsWithAuthToken.serviceAccountToken = authToken;
480
562
  } else {
481
- throw new Error(`Auth token not found under oidc.${oidcTokenProvider} in request body`);
563
+ throw new Error(
564
+ `Auth token not found under oidc.${oidcTokenProvider} in request body`
565
+ );
482
566
  }
483
567
  return clusterDetailsWithAuthToken;
484
568
  }
@@ -509,7 +593,9 @@ class KubernetesAuthTranslatorGenerator {
509
593
  return new NoopKubernetesAuthTranslator();
510
594
  }
511
595
  default: {
512
- throw new Error(`authProvider "${authProvider}" has no KubernetesAuthTranslator associated with it`);
596
+ throw new Error(
597
+ `authProvider "${authProvider}" has no KubernetesAuthTranslator associated with it`
598
+ );
513
599
  }
514
600
  }
515
601
  }
@@ -632,45 +718,61 @@ class KubernetesFanOutHandler {
632
718
  auth,
633
719
  customResources
634
720
  }) {
635
- return this.fanOutRequests(entity, auth, /* @__PURE__ */ new Set(), customResources);
721
+ return this.fanOutRequests(
722
+ entity,
723
+ auth,
724
+ /* @__PURE__ */ new Set(),
725
+ customResources
726
+ );
636
727
  }
637
728
  async getKubernetesObjectsByEntity({
638
729
  entity,
639
730
  auth
640
731
  }) {
641
- return this.fanOutRequests(entity, auth, this.objectTypesToFetch, this.customResources);
732
+ return this.fanOutRequests(entity, auth, this.objectTypesToFetch);
642
733
  }
643
734
  async fanOutRequests(entity, auth, objectTypesToFetch, customResources) {
644
735
  var _a, _b, _c, _d, _e, _f, _g;
645
736
  const entityName = ((_b = (_a = entity.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["backstage.io/kubernetes-id"]) || ((_c = entity.metadata) == null ? void 0 : _c.name);
646
737
  const clusterDetailsDecoratedForAuth = await this.decorateClusterDetailsWithAuth(entity, auth);
647
- this.logger.info(`entity.metadata.name=${entityName} clusterDetails=[${clusterDetailsDecoratedForAuth.map((c) => c.name).join(", ")}]`);
738
+ this.logger.info(
739
+ `entity.metadata.name=${entityName} clusterDetails=[${clusterDetailsDecoratedForAuth.map((c) => c.name).join(", ")}]`
740
+ );
648
741
  const labelSelector = ((_e = (_d = entity.metadata) == null ? void 0 : _d.annotations) == null ? void 0 : _e["backstage.io/kubernetes-label-selector"]) || `backstage.io/kubernetes-id=${entityName}`;
649
742
  const namespace = (_g = (_f = entity.metadata) == null ? void 0 : _f.annotations) == null ? void 0 : _g["backstage.io/kubernetes-namespace"];
650
- return Promise.all(clusterDetailsDecoratedForAuth.map((clusterDetailsItem) => {
651
- return this.fetcher.fetchObjectsForService({
652
- serviceId: entityName,
653
- clusterDetails: clusterDetailsItem,
654
- objectTypesToFetch,
655
- labelSelector,
656
- customResources: customResources.map((c) => ({
657
- ...c,
658
- objectType: "customresources"
659
- })),
660
- namespace
661
- }).then((result) => this.getMetricsForPods(clusterDetailsItem, result)).then((r) => this.toClusterObjects(clusterDetailsItem, r));
662
- })).then(this.toObjectsByEntityResponse);
743
+ return Promise.all(
744
+ clusterDetailsDecoratedForAuth.map((clusterDetailsItem) => {
745
+ return this.fetcher.fetchObjectsForService({
746
+ serviceId: entityName,
747
+ clusterDetails: clusterDetailsItem,
748
+ objectTypesToFetch,
749
+ labelSelector,
750
+ customResources: (customResources || clusterDetailsItem.customResources || this.customResources).map((c) => ({
751
+ ...c,
752
+ objectType: "customresources"
753
+ })),
754
+ namespace
755
+ }).then((result) => this.getMetricsForPods(clusterDetailsItem, result)).then((r) => this.toClusterObjects(clusterDetailsItem, r));
756
+ })
757
+ ).then(this.toObjectsByEntityResponse);
663
758
  }
664
759
  async decorateClusterDetailsWithAuth(entity, auth) {
665
760
  const clusterDetails = await (await this.serviceLocator.getClustersByEntity(entity)).clusters;
666
- return await Promise.all(clusterDetails.map((cd) => {
667
- const kubernetesAuthTranslator = this.getAuthTranslator(cd.authProvider);
668
- return kubernetesAuthTranslator.decorateClusterDetailsWithAuth(cd, auth);
669
- }));
761
+ return await Promise.all(
762
+ clusterDetails.map((cd) => {
763
+ const kubernetesAuthTranslator = this.getAuthTranslator(cd.authProvider);
764
+ return kubernetesAuthTranslator.decorateClusterDetailsWithAuth(
765
+ cd,
766
+ auth
767
+ );
768
+ })
769
+ );
670
770
  }
671
771
  toObjectsByEntityResponse(clusterObjects) {
672
772
  return {
673
- items: clusterObjects.filter((item) => item.errors !== void 0 && item.errors.length >= 1 || item.resources !== void 0 && item.resources.length >= 1 && item.resources.some((fr) => fr.resources.length >= 1))
773
+ items: clusterObjects.filter(
774
+ (item) => item.errors !== void 0 && item.errors.length >= 1 || item.resources !== void 0 && item.resources.length >= 1 && item.resources.some((fr) => fr.resources.length >= 1)
775
+ )
674
776
  };
675
777
  }
676
778
  toClusterObjects(clusterDetails, [result, metrics]) {
@@ -697,20 +799,27 @@ class KubernetesFanOutHandler {
697
799
  if (clusterDetails.skipMetricsLookup) {
698
800
  return [result, []];
699
801
  }
700
- const namespaces = new Set(result.responses.filter(isPodFetchResponse).flatMap((r) => r.resources).map((p) => {
701
- var _a;
702
- return (_a = p.metadata) == null ? void 0 : _a.namespace;
703
- }).filter(isString));
704
- const podMetrics = Array.from(namespaces).map((ns) => this.fetcher.fetchPodMetricsByNamespace(clusterDetails, ns));
802
+ const namespaces = new Set(
803
+ result.responses.filter(isPodFetchResponse).flatMap((r) => r.resources).map((p) => {
804
+ var _a;
805
+ return (_a = p.metadata) == null ? void 0 : _a.namespace;
806
+ }).filter(isString)
807
+ );
808
+ const podMetrics = Array.from(namespaces).map(
809
+ (ns) => this.fetcher.fetchPodMetricsByNamespace(clusterDetails, ns)
810
+ );
705
811
  return Promise.all([result, Promise.all(podMetrics)]);
706
812
  }
707
813
  getAuthTranslator(provider) {
708
814
  if (this.authTranslators[provider]) {
709
815
  return this.authTranslators[provider];
710
816
  }
711
- this.authTranslators[provider] = KubernetesAuthTranslatorGenerator.getKubernetesAuthTranslatorInstance(provider, {
712
- logger: this.logger
713
- });
817
+ this.authTranslators[provider] = KubernetesAuthTranslatorGenerator.getKubernetesAuthTranslatorInstance(
818
+ provider,
819
+ {
820
+ logger: this.logger
821
+ }
822
+ );
714
823
  return this.authTranslators[provider];
715
824
  }
716
825
  }
@@ -748,18 +857,28 @@ class KubernetesClientBasedFetcher {
748
857
  }
749
858
  fetchObjectsForService(params) {
750
859
  const fetchResults = Array.from(params.objectTypesToFetch).concat(params.customResources).map((toFetch) => {
751
- return this.fetchResource(params.clusterDetails, toFetch, params.labelSelector || `backstage.io/kubernetes-id=${params.serviceId}`, toFetch.objectType, params.namespace).catch(this.captureKubernetesErrorsRethrowOthers.bind(this));
860
+ return this.fetchResource(
861
+ params.clusterDetails,
862
+ toFetch,
863
+ params.labelSelector || `backstage.io/kubernetes-id=${params.serviceId}`,
864
+ toFetch.objectType,
865
+ params.namespace
866
+ ).catch(this.captureKubernetesErrorsRethrowOthers.bind(this));
752
867
  });
753
868
  return Promise.all(fetchResults).then(fetchResultsToResponseWrapper);
754
869
  }
755
870
  fetchPodMetricsByNamespace(clusterDetails, namespace) {
756
871
  const metricsClient = this.kubernetesClientProvider.getMetricsClient(clusterDetails);
757
- const coreApi = this.kubernetesClientProvider.getCoreClientByClusterDetails(clusterDetails);
872
+ const coreApi = this.kubernetesClientProvider.getCoreClientByClusterDetails(
873
+ clusterDetails
874
+ );
758
875
  return clientNode.topPods(coreApi, metricsClient, namespace);
759
876
  }
760
877
  captureKubernetesErrorsRethrowOthers(e) {
761
878
  if (e.response && e.response.statusCode) {
762
- this.logger.warn(`statusCode=${e.response.statusCode} for resource ${e.response.request.uri.pathname} body=[${JSON.stringify(e.response.body)}]`);
879
+ this.logger.warn(
880
+ `statusCode=${e.response.statusCode} for resource ${e.response.request.uri.pathname} body=[${JSON.stringify(e.response.body)}]`
881
+ );
763
882
  return {
764
883
  errorType: statusCodeToErrorType(e.response.statusCode),
765
884
  statusCode: e.response.statusCode,
@@ -774,14 +893,33 @@ class KubernetesClientBasedFetcher {
774
893
  requestOptions.uri = requestOptions.uri.replace("/apis//v1/", "/api/v1/");
775
894
  });
776
895
  if (namespace) {
777
- return customObjects.listNamespacedCustomObject(resource.group, resource.apiVersion, namespace, resource.plural, "", false, "", "", labelSelector).then((r) => {
896
+ return customObjects.listNamespacedCustomObject(
897
+ resource.group,
898
+ resource.apiVersion,
899
+ namespace,
900
+ resource.plural,
901
+ "",
902
+ false,
903
+ "",
904
+ "",
905
+ labelSelector
906
+ ).then((r) => {
778
907
  return {
779
908
  type: objectType,
780
909
  resources: r.body.items
781
910
  };
782
911
  });
783
912
  }
784
- return customObjects.listClusterCustomObject(resource.group, resource.apiVersion, resource.plural, "", false, "", "", labelSelector).then((r) => {
913
+ return customObjects.listClusterCustomObject(
914
+ resource.group,
915
+ resource.apiVersion,
916
+ resource.plural,
917
+ "",
918
+ false,
919
+ "",
920
+ "",
921
+ labelSelector
922
+ ).then((r) => {
785
923
  return {
786
924
  type: objectType,
787
925
  resources: r.body.items
@@ -804,7 +942,9 @@ const addResourceRoutesToRouter = (router, catalogApi, objectsProvider) => {
804
942
  } catch (error) {
805
943
  throw new errors.InputError(`Invalid entity ref, ${error}`);
806
944
  }
807
- const token = pluginAuthNode.getBearerTokenFromAuthorizationHeader(req.headers.authorization);
945
+ const token = pluginAuthNode.getBearerTokenFromAuthorizationHeader(
946
+ req.headers.authorization
947
+ );
808
948
  if (!token) {
809
949
  throw new errors.AuthenticationError("No Backstage token");
810
950
  }
@@ -812,7 +952,9 @@ const addResourceRoutesToRouter = (router, catalogApi, objectsProvider) => {
812
952
  token
813
953
  });
814
954
  if (!entity) {
815
- throw new errors.InputError(`Entity ref missing, ${catalogModel.stringifyEntityRef(entityRef)}`);
955
+ throw new errors.InputError(
956
+ `Entity ref missing, ${catalogModel.stringifyEntityRef(entityRef)}`
957
+ );
816
958
  }
817
959
  return entity;
818
960
  };
@@ -861,7 +1003,9 @@ class KubernetesBuilder {
861
1003
  if (process.env.NODE_ENV !== "development") {
862
1004
  throw new Error("Kubernetes configuration is missing");
863
1005
  }
864
- logger.warn("Failed to initialize kubernetes backend: kubernetes config is missing");
1006
+ logger.warn(
1007
+ "Failed to initialize kubernetes backend: kubernetes config is missing"
1008
+ );
865
1009
  return {
866
1010
  router: Router__default["default"]()
867
1011
  };
@@ -877,7 +1021,11 @@ class KubernetesBuilder {
877
1021
  customResources,
878
1022
  objectTypesToFetch: this.getObjectTypesToFetch()
879
1023
  });
880
- const router = this.buildRouter(objectsProvider, clusterSupplier, this.env.catalogApi);
1024
+ const router = this.buildRouter(
1025
+ objectsProvider,
1026
+ clusterSupplier,
1027
+ this.env.catalogApi
1028
+ );
881
1029
  return {
882
1030
  clusterSupplier,
883
1031
  customResources,
@@ -909,18 +1057,26 @@ class KubernetesBuilder {
909
1057
  }
910
1058
  buildCustomResources() {
911
1059
  var _a;
912
- const customResources = ((_a = this.env.config.getOptionalConfigArray("kubernetes.customResources")) != null ? _a : []).map((c) => ({
913
- group: c.getString("group"),
914
- apiVersion: c.getString("apiVersion"),
915
- plural: c.getString("plural"),
916
- objectType: "customresources"
917
- }));
918
- this.env.logger.info(`action=LoadingCustomResources numOfCustomResources=${customResources.length}`);
1060
+ const customResources = ((_a = this.env.config.getOptionalConfigArray("kubernetes.customResources")) != null ? _a : []).map(
1061
+ (c) => ({
1062
+ group: c.getString("group"),
1063
+ apiVersion: c.getString("apiVersion"),
1064
+ plural: c.getString("plural"),
1065
+ objectType: "customresources"
1066
+ })
1067
+ );
1068
+ this.env.logger.info(
1069
+ `action=LoadingCustomResources numOfCustomResources=${customResources.length}`
1070
+ );
919
1071
  return customResources;
920
1072
  }
921
1073
  buildClusterSupplier(refreshInterval) {
922
1074
  const config = this.env.config;
923
- return getCombinedClusterSupplier(config, refreshInterval);
1075
+ return getCombinedClusterSupplier(
1076
+ config,
1077
+ this.env.catalogApi,
1078
+ refreshInterval
1079
+ );
924
1080
  }
925
1081
  buildObjectsProvider(options) {
926
1082
  return new KubernetesFanOutHandler(options);
@@ -938,7 +1094,9 @@ class KubernetesBuilder {
938
1094
  case "http":
939
1095
  return this.buildHttpServiceLocator(clusterSupplier);
940
1096
  default:
941
- throw new Error(`Unsupported kubernetes.clusterLocatorMethod "${method}"`);
1097
+ throw new Error(
1098
+ `Unsupported kubernetes.clusterLocatorMethod "${method}"`
1099
+ );
942
1100
  }
943
1101
  }
944
1102
  buildMultiTenantServiceLocator(clusterSupplier) {
@@ -961,7 +1119,9 @@ class KubernetesBuilder {
961
1119
  });
962
1120
  res.json(response);
963
1121
  } catch (e) {
964
- logger.error(`action=retrieveObjectsByServiceId service=${serviceId}, error=${e}`);
1122
+ logger.error(
1123
+ `action=retrieveObjectsByServiceId service=${serviceId}, error=${e}`
1124
+ );
965
1125
  res.status(500).json({ error: e.message });
966
1126
  }
967
1127
  });
@@ -981,18 +1141,28 @@ class KubernetesBuilder {
981
1141
  }
982
1142
  async fetchClusterDetails(clusterSupplier) {
983
1143
  const clusterDetails = await clusterSupplier.getClusters();
984
- this.env.logger.info(`action=loadClusterDetails numOfClustersLoaded=${clusterDetails.length}`);
1144
+ this.env.logger.info(
1145
+ `action=loadClusterDetails numOfClustersLoaded=${clusterDetails.length}`
1146
+ );
985
1147
  return clusterDetails;
986
1148
  }
987
1149
  getServiceLocatorMethod() {
988
- return this.env.config.getString("kubernetes.serviceLocatorMethod.type");
1150
+ return this.env.config.getString(
1151
+ "kubernetes.serviceLocatorMethod.type"
1152
+ );
989
1153
  }
990
1154
  getObjectTypesToFetch() {
991
- const objectTypesToFetchStrings = this.env.config.getOptionalStringArray("kubernetes.objectTypes");
992
- const apiVersionOverrides = this.env.config.getOptionalConfig("kubernetes.apiVersionOverrides");
1155
+ const objectTypesToFetchStrings = this.env.config.getOptionalStringArray(
1156
+ "kubernetes.objectTypes"
1157
+ );
1158
+ const apiVersionOverrides = this.env.config.getOptionalConfig(
1159
+ "kubernetes.apiVersionOverrides"
1160
+ );
993
1161
  let objectTypesToFetch;
994
1162
  if (objectTypesToFetchStrings) {
995
- objectTypesToFetch = DEFAULT_OBJECTS.filter((obj) => objectTypesToFetchStrings.includes(obj.objectType));
1163
+ objectTypesToFetch = DEFAULT_OBJECTS.filter(
1164
+ (obj) => objectTypesToFetchStrings.includes(obj.objectType)
1165
+ );
996
1166
  }
997
1167
  if (apiVersionOverrides) {
998
1168
  objectTypesToFetch = objectTypesToFetch != null ? objectTypesToFetch : DEFAULT_OBJECTS;