@backstage/plugin-kubernetes 0.7.0 → 0.7.1-next.2

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.esm.js CHANGED
@@ -52,7 +52,10 @@ class KubernetesBackendClient {
52
52
  return this.handleResponse(response);
53
53
  }
54
54
  async getObjectsByEntity(requestBody) {
55
- return await this.postRequired(`/services/${requestBody.entity.metadata.name}`, requestBody);
55
+ return await this.postRequired(
56
+ `/services/${requestBody.entity.metadata.name}`,
57
+ requestBody
58
+ );
56
59
  }
57
60
  async getClusters() {
58
61
  const { token: idToken } = await this.identityApi.getCredentials();
@@ -80,7 +83,9 @@ class GoogleKubernetesAuthProvider {
80
83
  this.authProvider = authProvider;
81
84
  }
82
85
  async decorateRequestBodyForAuth(requestBody) {
83
- const googleAuthToken = await this.authProvider.getAccessToken("https://www.googleapis.com/auth/cloud-platform");
86
+ const googleAuthToken = await this.authProvider.getAccessToken(
87
+ "https://www.googleapis.com/auth/cloud-platform"
88
+ );
84
89
  if ("auth" in requestBody) {
85
90
  requestBody.auth.google = googleAuthToken;
86
91
  } else {
@@ -117,27 +122,57 @@ class OidcKubernetesAuthProvider {
117
122
  class KubernetesAuthProviders {
118
123
  constructor(options) {
119
124
  this.kubernetesAuthProviderMap = /* @__PURE__ */ new Map();
120
- this.kubernetesAuthProviderMap.set("google", new GoogleKubernetesAuthProvider(options.googleAuthApi));
121
- this.kubernetesAuthProviderMap.set("serviceAccount", new ServerSideKubernetesAuthProvider());
122
- this.kubernetesAuthProviderMap.set("googleServiceAccount", new ServerSideKubernetesAuthProvider());
123
- this.kubernetesAuthProviderMap.set("aws", new ServerSideKubernetesAuthProvider());
124
- this.kubernetesAuthProviderMap.set("azure", new ServerSideKubernetesAuthProvider());
125
- this.kubernetesAuthProviderMap.set("localKubectlProxy", new ServerSideKubernetesAuthProvider());
125
+ this.kubernetesAuthProviderMap.set(
126
+ "google",
127
+ new GoogleKubernetesAuthProvider(options.googleAuthApi)
128
+ );
129
+ this.kubernetesAuthProviderMap.set(
130
+ "serviceAccount",
131
+ new ServerSideKubernetesAuthProvider()
132
+ );
133
+ this.kubernetesAuthProviderMap.set(
134
+ "googleServiceAccount",
135
+ new ServerSideKubernetesAuthProvider()
136
+ );
137
+ this.kubernetesAuthProviderMap.set(
138
+ "aws",
139
+ new ServerSideKubernetesAuthProvider()
140
+ );
141
+ this.kubernetesAuthProviderMap.set(
142
+ "azure",
143
+ new ServerSideKubernetesAuthProvider()
144
+ );
145
+ this.kubernetesAuthProviderMap.set(
146
+ "localKubectlProxy",
147
+ new ServerSideKubernetesAuthProvider()
148
+ );
126
149
  if (options.oidcProviders) {
127
150
  Object.keys(options.oidcProviders).forEach((provider) => {
128
- this.kubernetesAuthProviderMap.set(`oidc.${provider}`, new OidcKubernetesAuthProvider(provider, options.oidcProviders[provider]));
151
+ this.kubernetesAuthProviderMap.set(
152
+ `oidc.${provider}`,
153
+ new OidcKubernetesAuthProvider(
154
+ provider,
155
+ options.oidcProviders[provider]
156
+ )
157
+ );
129
158
  });
130
159
  }
131
160
  }
132
161
  async decorateRequestBodyForAuth(authProvider, requestBody) {
133
162
  const kubernetesAuthProvider = this.kubernetesAuthProviderMap.get(authProvider);
134
163
  if (kubernetesAuthProvider) {
135
- return await kubernetesAuthProvider.decorateRequestBodyForAuth(requestBody);
164
+ return await kubernetesAuthProvider.decorateRequestBodyForAuth(
165
+ requestBody
166
+ );
136
167
  }
137
168
  if (authProvider.startsWith("oidc.")) {
138
- throw new Error(`KubernetesAuthProviders has no oidcProvider configured for ${authProvider}`);
169
+ throw new Error(
170
+ `KubernetesAuthProviders has no oidcProvider configured for ${authProvider}`
171
+ );
139
172
  }
140
- throw new Error(`authProvider "${authProvider}" has no KubernetesAuthProvider defined for it`);
173
+ throw new Error(
174
+ `authProvider "${authProvider}" has no KubernetesAuthProvider defined for it`
175
+ );
141
176
  }
142
177
  }
143
178
 
@@ -183,11 +218,13 @@ const kubernetesPlugin = createPlugin({
183
218
  entityContent: rootCatalogKubernetesRouteRef
184
219
  }
185
220
  });
186
- const EntityKubernetesContent = kubernetesPlugin.provide(createRoutableExtension({
187
- name: "EntityKubernetesContent",
188
- component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router),
189
- mountPoint: rootCatalogKubernetesRouteRef
190
- }));
221
+ const EntityKubernetesContent = kubernetesPlugin.provide(
222
+ createRoutableExtension({
223
+ name: "EntityKubernetesContent",
224
+ component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router),
225
+ mountPoint: rootCatalogKubernetesRouteRef
226
+ })
227
+ );
191
228
 
192
229
  const clustersWithErrorsToErrorMessage = (clustersWithErrors) => {
193
230
  return clustersWithErrors.map((c, i) => {
@@ -217,12 +254,17 @@ const ErrorPanel$1 = ({
217
254
  const columns = [
218
255
  {
219
256
  title: "cluster",
220
- width: "15%",
257
+ width: "10%",
221
258
  render: (detectedError) => detectedError.cluster
222
259
  },
260
+ {
261
+ title: "namespace",
262
+ width: "10%",
263
+ render: (detectedError) => detectedError.namespace
264
+ },
223
265
  {
224
266
  title: "kind",
225
- width: "15%",
267
+ width: "10%",
226
268
  render: (detectedError) => detectedError.kind
227
269
  },
228
270
  {
@@ -291,56 +333,59 @@ const ErrorReporting = ({ detectedErrors }) => {
291
333
  };
292
334
 
293
335
  const groupResponses = (fetchResponse) => {
294
- return fetchResponse.reduce((prev, next) => {
295
- switch (next.type) {
296
- case "deployments":
297
- prev.deployments.push(...next.resources);
298
- break;
299
- case "pods":
300
- prev.pods.push(...next.resources);
301
- break;
302
- case "replicasets":
303
- prev.replicaSets.push(...next.resources);
304
- break;
305
- case "services":
306
- prev.services.push(...next.resources);
307
- break;
308
- case "configmaps":
309
- prev.configMaps.push(...next.resources);
310
- break;
311
- case "horizontalpodautoscalers":
312
- prev.horizontalPodAutoscalers.push(...next.resources);
313
- break;
314
- case "ingresses":
315
- prev.ingresses.push(...next.resources);
316
- break;
317
- case "jobs":
318
- prev.jobs.push(...next.resources);
319
- break;
320
- case "cronjobs":
321
- prev.cronJobs.push(...next.resources);
322
- break;
323
- case "customresources":
324
- prev.customResources.push(...next.resources);
325
- break;
326
- case "statefulsets":
327
- prev.statefulsets.push(...next.resources);
328
- break;
336
+ return fetchResponse.reduce(
337
+ (prev, next) => {
338
+ switch (next.type) {
339
+ case "deployments":
340
+ prev.deployments.push(...next.resources);
341
+ break;
342
+ case "pods":
343
+ prev.pods.push(...next.resources);
344
+ break;
345
+ case "replicasets":
346
+ prev.replicaSets.push(...next.resources);
347
+ break;
348
+ case "services":
349
+ prev.services.push(...next.resources);
350
+ break;
351
+ case "configmaps":
352
+ prev.configMaps.push(...next.resources);
353
+ break;
354
+ case "horizontalpodautoscalers":
355
+ prev.horizontalPodAutoscalers.push(...next.resources);
356
+ break;
357
+ case "ingresses":
358
+ prev.ingresses.push(...next.resources);
359
+ break;
360
+ case "jobs":
361
+ prev.jobs.push(...next.resources);
362
+ break;
363
+ case "cronjobs":
364
+ prev.cronJobs.push(...next.resources);
365
+ break;
366
+ case "customresources":
367
+ prev.customResources.push(...next.resources);
368
+ break;
369
+ case "statefulsets":
370
+ prev.statefulsets.push(...next.resources);
371
+ break;
372
+ }
373
+ return prev;
374
+ },
375
+ {
376
+ pods: [],
377
+ replicaSets: [],
378
+ deployments: [],
379
+ services: [],
380
+ configMaps: [],
381
+ horizontalPodAutoscalers: [],
382
+ ingresses: [],
383
+ jobs: [],
384
+ cronJobs: [],
385
+ customResources: [],
386
+ statefulsets: []
329
387
  }
330
- return prev;
331
- }, {
332
- pods: [],
333
- replicaSets: [],
334
- deployments: [],
335
- services: [],
336
- configMaps: [],
337
- horizontalPodAutoscalers: [],
338
- ingresses: [],
339
- jobs: [],
340
- cronJobs: [],
341
- customResources: [],
342
- statefulsets: []
343
- });
388
+ );
344
389
  };
345
390
 
346
391
  const imageChips = (pod) => {
@@ -433,8 +478,14 @@ const podStatusToCpuUtil = (podStatus) => {
433
478
  currentUsage = cpuUtil.currentUsage / 10;
434
479
  }
435
480
  return /* @__PURE__ */ React__default.createElement(SubvalueCell, {
436
- value: `requests: ${currentToDeclaredResourceToPerc(currentUsage, cpuUtil.requestTotal)} of ${formatMilicores(cpuUtil.requestTotal)}`,
437
- subvalue: `limits: ${currentToDeclaredResourceToPerc(currentUsage, cpuUtil.limitTotal)} of ${formatMilicores(cpuUtil.limitTotal)}`
481
+ value: `requests: ${currentToDeclaredResourceToPerc(
482
+ currentUsage,
483
+ cpuUtil.requestTotal
484
+ )} of ${formatMilicores(cpuUtil.requestTotal)}`,
485
+ subvalue: `limits: ${currentToDeclaredResourceToPerc(
486
+ currentUsage,
487
+ cpuUtil.limitTotal
488
+ )} of ${formatMilicores(cpuUtil.limitTotal)}`
438
489
  });
439
490
  };
440
491
  const bytesToMiB = (value) => {
@@ -443,13 +494,19 @@ const bytesToMiB = (value) => {
443
494
  const podStatusToMemoryUtil = (podStatus) => {
444
495
  const memUtil = podStatus.memory;
445
496
  return /* @__PURE__ */ React__default.createElement(SubvalueCell, {
446
- value: `requests: ${currentToDeclaredResourceToPerc(memUtil.currentUsage, memUtil.requestTotal)} of ${bytesToMiB(memUtil.requestTotal)}`,
447
- subvalue: `limits: ${currentToDeclaredResourceToPerc(memUtil.currentUsage, memUtil.limitTotal)} of ${bytesToMiB(memUtil.limitTotal)}`
497
+ value: `requests: ${currentToDeclaredResourceToPerc(
498
+ memUtil.currentUsage,
499
+ memUtil.requestTotal
500
+ )} of ${bytesToMiB(memUtil.requestTotal)}`,
501
+ subvalue: `limits: ${currentToDeclaredResourceToPerc(
502
+ memUtil.currentUsage,
503
+ memUtil.limitTotal
504
+ )} of ${bytesToMiB(memUtil.limitTotal)}`
448
505
  });
449
506
  };
450
507
 
451
508
  const detectErrorsInObjects = (objects, kind, clusterName, errorMappers) => {
452
- var _a, _b;
509
+ var _a, _b, _c, _d;
453
510
  const errors = /* @__PURE__ */ new Map();
454
511
  for (const object of objects) {
455
512
  for (const errorMapper of errorMappers) {
@@ -458,6 +515,7 @@ const detectErrorsInObjects = (objects, kind, clusterName, errorMappers) => {
458
515
  const dedupKey = message.join("");
459
516
  const value = errors.get(dedupKey);
460
517
  const name = (_b = (_a = object.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown";
518
+ const namespace = (_d = (_c = object.metadata) == null ? void 0 : _c.namespace) != null ? _d : "unknown";
461
519
  if (value !== void 0) {
462
520
  value.names.push(name);
463
521
  errors.set(dedupKey, value);
@@ -467,7 +525,8 @@ const detectErrorsInObjects = (objects, kind, clusterName, errorMappers) => {
467
525
  kind,
468
526
  names: [name],
469
527
  message,
470
- severity: errorMapper.severity
528
+ severity: errorMapper.severity,
529
+ namespace
471
530
  });
472
531
  }
473
532
  }
@@ -520,10 +579,12 @@ const podErrorMappers = [
520
579
  errorExplanation: "container-waiting",
521
580
  errorExists: (pod) => {
522
581
  var _a, _b;
523
- return ((_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : []).some((cs) => {
524
- var _a2, _b2;
525
- return ((_b2 = (_a2 = cs.state) == null ? void 0 : _a2.waiting) == null ? void 0 : _b2.message) !== void 0;
526
- });
582
+ return ((_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : []).some(
583
+ (cs) => {
584
+ var _a2, _b2;
585
+ return ((_b2 = (_a2 = cs.state) == null ? void 0 : _a2.waiting) == null ? void 0 : _b2.message) !== void 0;
586
+ }
587
+ );
527
588
  },
528
589
  messageAccessor: (pod) => {
529
590
  var _a, _b;
@@ -541,20 +602,24 @@ const podErrorMappers = [
541
602
  errorExplanation: "container-last-state-error",
542
603
  errorExists: (pod) => {
543
604
  var _a, _b;
544
- return ((_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : []).some((cs) => {
545
- var _a2, _b2, _c;
546
- return ((_c = (_b2 = (_a2 = cs.lastState) == null ? void 0 : _a2.terminated) == null ? void 0 : _b2.reason) != null ? _c : "") === "Error";
547
- });
605
+ return ((_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : []).some(
606
+ (cs) => {
607
+ var _a2, _b2, _c;
608
+ return ((_c = (_b2 = (_a2 = cs.lastState) == null ? void 0 : _a2.terminated) == null ? void 0 : _b2.reason) != null ? _c : "") === "Error";
609
+ }
610
+ );
548
611
  },
549
612
  messageAccessor: (pod) => {
550
613
  var _a, _b;
551
614
  return ((_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : []).filter((cs) => {
552
615
  var _a2, _b2, _c;
553
616
  return ((_c = (_b2 = (_a2 = cs.lastState) == null ? void 0 : _a2.terminated) == null ? void 0 : _b2.reason) != null ? _c : "") === "Error";
554
- }).map((cs) => {
555
- var _a2, _b2;
556
- return `container=${cs.name} exited with error code (${(_b2 = (_a2 = cs.lastState) == null ? void 0 : _a2.terminated) == null ? void 0 : _b2.exitCode})`;
557
- });
617
+ }).map(
618
+ (cs) => {
619
+ var _a2, _b2;
620
+ return `container=${cs.name} exited with error code (${(_b2 = (_a2 = cs.lastState) == null ? void 0 : _a2.terminated) == null ? void 0 : _b2.exitCode})`;
621
+ }
622
+ );
558
623
  }
559
624
  }
560
625
  ];
@@ -577,7 +642,12 @@ const deploymentErrorMappers = [
577
642
  }
578
643
  }
579
644
  ];
580
- const detectErrorsInDeployments = (deployments, clusterName) => detectErrorsInObjects(deployments, "Deployment", clusterName, deploymentErrorMappers);
645
+ const detectErrorsInDeployments = (deployments, clusterName) => detectErrorsInObjects(
646
+ deployments,
647
+ "Deployment",
648
+ clusterName,
649
+ deploymentErrorMappers
650
+ );
581
651
 
582
652
  const hpaErrorMappers = [
583
653
  {
@@ -595,16 +665,33 @@ const hpaErrorMappers = [
595
665
  }
596
666
  }
597
667
  ];
598
- const detectErrorsInHpa = (hpas, clusterName) => detectErrorsInObjects(hpas, "HorizontalPodAutoscaler", clusterName, hpaErrorMappers);
668
+ const detectErrorsInHpa = (hpas, clusterName) => detectErrorsInObjects(
669
+ hpas,
670
+ "HorizontalPodAutoscaler",
671
+ clusterName,
672
+ hpaErrorMappers
673
+ );
599
674
 
600
675
  const detectErrors = (objects) => {
601
676
  const errors = /* @__PURE__ */ new Map();
602
677
  for (const clusterResponse of objects.items) {
603
678
  let clusterErrors = [];
604
679
  const groupedResponses = groupResponses(clusterResponse.resources);
605
- clusterErrors = clusterErrors.concat(detectErrorsInPods(groupedResponses.pods, clusterResponse.cluster.name));
606
- clusterErrors = clusterErrors.concat(detectErrorsInDeployments(groupedResponses.deployments, clusterResponse.cluster.name));
607
- clusterErrors = clusterErrors.concat(detectErrorsInHpa(groupedResponses.horizontalPodAutoscalers, clusterResponse.cluster.name));
680
+ clusterErrors = clusterErrors.concat(
681
+ detectErrorsInPods(groupedResponses.pods, clusterResponse.cluster.name)
682
+ );
683
+ clusterErrors = clusterErrors.concat(
684
+ detectErrorsInDeployments(
685
+ groupedResponses.deployments,
686
+ clusterResponse.cluster.name
687
+ )
688
+ );
689
+ clusterErrors = clusterErrors.concat(
690
+ detectErrorsInHpa(
691
+ groupedResponses.horizontalPodAutoscalers,
692
+ clusterResponse.cluster.name
693
+ )
694
+ );
608
695
  errors.set(clusterResponse.cluster.name, clusterErrors);
609
696
  }
610
697
  return errors;
@@ -624,14 +711,21 @@ const useKubernetesObjects = (entity, intervalMs = 1e4) => {
624
711
  return;
625
712
  }
626
713
  const authProviders = [
627
- ...new Set(clusters.map((c) => `${c.authProvider}${c.oidcTokenProvider ? `.${c.oidcTokenProvider}` : ""}`))
714
+ ...new Set(
715
+ clusters.map(
716
+ (c) => `${c.authProvider}${c.oidcTokenProvider ? `.${c.oidcTokenProvider}` : ""}`
717
+ )
718
+ )
628
719
  ];
629
720
  let requestBody = {
630
721
  entity
631
722
  };
632
723
  for (const authProviderStr of authProviders) {
633
724
  try {
634
- requestBody = await kubernetesAuthProvidersApi.decorateRequestBodyForAuth(authProviderStr, requestBody);
725
+ requestBody = await kubernetesAuthProvidersApi.decorateRequestBodyForAuth(
726
+ authProviderStr,
727
+ requestBody
728
+ );
635
729
  } catch (e) {
636
730
  setError(e.message);
637
731
  return;
@@ -656,7 +750,9 @@ const useKubernetesObjects = (entity, intervalMs = 1e4) => {
656
750
  };
657
751
  };
658
752
 
659
- const PodNamesWithErrorsContext = React__default.createContext(/* @__PURE__ */ new Set());
753
+ const PodNamesWithErrorsContext = React__default.createContext(
754
+ /* @__PURE__ */ new Set()
755
+ );
660
756
 
661
757
  const PodNamesWithMetricsContext = React__default.createContext(/* @__PURE__ */ new Map());
662
758
 
@@ -693,7 +789,9 @@ function standardFormatter(options) {
693
789
  }
694
790
  const result = new URL(options.dashboardUrl.href);
695
791
  const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
696
- const namespace = encodeURIComponent((_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : "");
792
+ const namespace = encodeURIComponent(
793
+ (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
794
+ );
697
795
  const validKind = kindMappings$3[options.kind.toLocaleLowerCase("en-US")];
698
796
  if (!result.pathname.endsWith("/")) {
699
797
  result.pathname += "/";
@@ -722,7 +820,9 @@ function rancherFormatter(options) {
722
820
  }
723
821
  const basePath = new URL(options.dashboardUrl.href);
724
822
  const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
725
- const namespace = encodeURIComponent((_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : "");
823
+ const namespace = encodeURIComponent(
824
+ (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
825
+ );
726
826
  const validKind = kindMappings$2[options.kind.toLocaleLowerCase("en-US")];
727
827
  if (!basePath.pathname.endsWith("/")) {
728
828
  basePath.pathname += "/";
@@ -750,7 +850,9 @@ function openshiftFormatter(options) {
750
850
  }
751
851
  const basePath = new URL(options.dashboardUrl.href);
752
852
  const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
753
- const namespace = encodeURIComponent((_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : "");
853
+ const namespace = encodeURIComponent(
854
+ (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
855
+ );
754
856
  const validKind = kindMappings$1[options.kind.toLocaleLowerCase("en-US")];
755
857
  if (!basePath.pathname.endsWith("/")) {
756
858
  basePath.pathname += "/";
@@ -780,7 +882,9 @@ function aksFormatter(options) {
780
882
  const args = options.dashboardParameters;
781
883
  for (const param of requiredParams) {
782
884
  if (typeof args[param] !== "string") {
783
- throw new Error(`AKS dashboard requires a "${param}" of type string in the dashboardParameters option`);
885
+ throw new Error(
886
+ `AKS dashboard requires a "${param}" of type string in the dashboardParameters option`
887
+ );
784
888
  }
785
889
  }
786
890
  const path = `/subscriptions/${args.subscriptionId}/resourceGroups/${args.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${args.clusterName}`;
@@ -793,7 +897,11 @@ function aksFormatter(options) {
793
897
  selector
794
898
  }
795
899
  };
796
- return new URL(`${basePath}/${encodeURIComponent(path)}/resource/${encodeURIComponent(JSON.stringify(params))}`);
900
+ return new URL(
901
+ `${basePath}/${encodeURIComponent(path)}/resource/${encodeURIComponent(
902
+ JSON.stringify(params)
903
+ )}`
904
+ );
797
905
  }
798
906
 
799
907
  function eksFormatter(_options) {
@@ -814,19 +922,27 @@ function gkeFormatter(options) {
814
922
  }
815
923
  const args = options.dashboardParameters;
816
924
  if (typeof args.projectId !== "string") {
817
- throw new Error('GKE dashboard requires a "projectId" of type string in the dashboardParameters option');
925
+ throw new Error(
926
+ 'GKE dashboard requires a "projectId" of type string in the dashboardParameters option'
927
+ );
818
928
  }
819
929
  if (typeof args.region !== "string") {
820
- throw new Error('GKE dashboard requires a "region" of type string in the dashboardParameters option');
930
+ throw new Error(
931
+ 'GKE dashboard requires a "region" of type string in the dashboardParameters option'
932
+ );
821
933
  }
822
934
  if (typeof args.clusterName !== "string") {
823
- throw new Error('GKE dashboard requires a "clusterName" of type string in the dashboardParameters option');
935
+ throw new Error(
936
+ 'GKE dashboard requires a "clusterName" of type string in the dashboardParameters option'
937
+ );
824
938
  }
825
939
  const basePath = new URL("https://console.cloud.google.com/");
826
940
  const region = encodeURIComponent(args.region);
827
941
  const clusterName = encodeURIComponent(args.clusterName);
828
942
  const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
829
- const namespace = encodeURIComponent((_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : "");
943
+ const namespace = encodeURIComponent(
944
+ (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
945
+ );
830
946
  const validKind = kindMappings[options.kind.toLocaleLowerCase("en-US")];
831
947
  let path = "";
832
948
  if (namespace && name && validKind) {
@@ -872,35 +988,39 @@ function formatClusterLink(options) {
872
988
  return url.toString();
873
989
  }
874
990
 
875
- const useDrawerStyles = makeStyles((theme) => createStyles({
876
- paper: {
877
- width: "50%",
878
- justifyContent: "space-between",
879
- padding: theme.spacing(2.5)
880
- }
881
- }));
882
- const useDrawerContentStyles = makeStyles((_) => createStyles({
883
- header: {
884
- display: "flex",
885
- flexDirection: "row",
886
- justifyContent: "space-between"
887
- },
888
- errorMessage: {
889
- marginTop: "1em",
890
- marginBottom: "1em"
891
- },
892
- options: {
893
- display: "flex",
894
- flexDirection: "row",
895
- justifyContent: "space-between"
896
- },
897
- icon: {
898
- fontSize: 20
899
- },
900
- content: {
901
- height: "80%"
902
- }
903
- }));
991
+ const useDrawerStyles = makeStyles(
992
+ (theme) => createStyles({
993
+ paper: {
994
+ width: "50%",
995
+ justifyContent: "space-between",
996
+ padding: theme.spacing(2.5)
997
+ }
998
+ })
999
+ );
1000
+ const useDrawerContentStyles = makeStyles(
1001
+ (_) => createStyles({
1002
+ header: {
1003
+ display: "flex",
1004
+ flexDirection: "row",
1005
+ justifyContent: "space-between"
1006
+ },
1007
+ errorMessage: {
1008
+ marginTop: "1em",
1009
+ marginBottom: "1em"
1010
+ },
1011
+ options: {
1012
+ display: "flex",
1013
+ flexDirection: "row",
1014
+ justifyContent: "space-between"
1015
+ },
1016
+ icon: {
1017
+ fontSize: 20
1018
+ },
1019
+ content: {
1020
+ height: "80%"
1021
+ }
1022
+ })
1023
+ );
904
1024
  const PodDrawerButton = withStyles({
905
1025
  root: {
906
1026
  padding: "6px 5px"
@@ -1223,16 +1343,23 @@ const HorizontalPodAutoscalerDrawer = ({
1223
1343
  };
1224
1344
 
1225
1345
  function getOwnedResources(potentialOwner, possiblyOwned) {
1226
- return possiblyOwned.filter((p) => {
1227
- var _a, _b, _c;
1228
- return (_c = (_b = (_a = p.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some((o) => {
1229
- var _a2;
1230
- return o.uid === ((_a2 = potentialOwner.metadata) == null ? void 0 : _a2.uid);
1231
- })) != null ? _c : false;
1232
- });
1346
+ return possiblyOwned.filter(
1347
+ (p) => {
1348
+ var _a, _b, _c;
1349
+ return (_c = (_b = (_a = p.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some(
1350
+ (o) => {
1351
+ var _a2;
1352
+ return o.uid === ((_a2 = potentialOwner.metadata) == null ? void 0 : _a2.uid);
1353
+ }
1354
+ )) != null ? _c : false;
1355
+ }
1356
+ );
1233
1357
  }
1234
1358
  const getOwnedPodsThroughReplicaSets = (potentialOwner, replicaSets, pods) => {
1235
- return getOwnedResources(potentialOwner, replicaSets.filter((rs) => rs.status && rs.status.replicas > 0)).reduce((accum, rs) => {
1359
+ return getOwnedResources(
1360
+ potentialOwner,
1361
+ replicaSets.filter((rs) => rs.status && rs.status.replicas > 0)
1362
+ ).reduce((accum, rs) => {
1236
1363
  return accum.concat(getOwnedResources(rs, pods));
1237
1364
  }, []);
1238
1365
  };
@@ -1309,10 +1436,12 @@ const DeploymentAccordion = ({
1309
1436
  matchingHpa
1310
1437
  }) => {
1311
1438
  const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
1312
- const podsWithErrors = ownedPods.filter((p) => {
1313
- var _a, _b;
1314
- return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
1315
- });
1439
+ const podsWithErrors = ownedPods.filter(
1440
+ (p) => {
1441
+ var _a, _b;
1442
+ return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
1443
+ }
1444
+ );
1316
1445
  return /* @__PURE__ */ React__default.createElement(Accordion, {
1317
1446
  TransitionProps: { unmountOnExit: true }
1318
1447
  }, /* @__PURE__ */ React__default.createElement(AccordionSummary, {
@@ -1345,12 +1474,19 @@ const DeploymentsAccordions = ({}) => {
1345
1474
  item: true,
1346
1475
  xs: true
1347
1476
  }, /* @__PURE__ */ React__default.createElement(DeploymentAccordion, {
1348
- matchingHpa: getMatchingHpa({
1349
- name: (_a = deployment.metadata) == null ? void 0 : _a.name,
1350
- namespace: (_b = deployment.metadata) == null ? void 0 : _b.namespace,
1351
- kind: "deployment"
1352
- }, groupedResponses.horizontalPodAutoscalers),
1353
- ownedPods: getOwnedPodsThroughReplicaSets(deployment, groupedResponses.replicaSets, groupedResponses.pods),
1477
+ matchingHpa: getMatchingHpa(
1478
+ {
1479
+ name: (_a = deployment.metadata) == null ? void 0 : _a.name,
1480
+ namespace: (_b = deployment.metadata) == null ? void 0 : _b.namespace,
1481
+ kind: "deployment"
1482
+ },
1483
+ groupedResponses.horizontalPodAutoscalers
1484
+ ),
1485
+ ownedPods: getOwnedPodsThroughReplicaSets(
1486
+ deployment,
1487
+ groupedResponses.replicaSets,
1488
+ groupedResponses.pods
1489
+ ),
1354
1490
  deployment
1355
1491
  })));
1356
1492
  }));
@@ -1470,10 +1606,12 @@ const StatefulSetAccordion = ({
1470
1606
  matchingHpa
1471
1607
  }) => {
1472
1608
  const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
1473
- const podsWithErrors = ownedPods.filter((p) => {
1474
- var _a, _b;
1475
- return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
1476
- });
1609
+ const podsWithErrors = ownedPods.filter(
1610
+ (p) => {
1611
+ var _a, _b;
1612
+ return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
1613
+ }
1614
+ );
1477
1615
  return /* @__PURE__ */ React__default.createElement(Accordion, {
1478
1616
  TransitionProps: { unmountOnExit: true }
1479
1617
  }, /* @__PURE__ */ React__default.createElement(AccordionSummary, {
@@ -1506,11 +1644,14 @@ const StatefulSetsAccordions = ({}) => {
1506
1644
  item: true,
1507
1645
  xs: true
1508
1646
  }, /* @__PURE__ */ React__default.createElement(StatefulSetAccordion, {
1509
- matchingHpa: getMatchingHpa({
1510
- name: (_a = statefulset.metadata) == null ? void 0 : _a.name,
1511
- namespace: (_b = statefulset.metadata) == null ? void 0 : _b.namespace,
1512
- kind: "statefulset"
1513
- }, groupedResponses.horizontalPodAutoscalers),
1647
+ matchingHpa: getMatchingHpa(
1648
+ {
1649
+ name: (_a = statefulset.metadata) == null ? void 0 : _a.name,
1650
+ namespace: (_b = statefulset.metadata) == null ? void 0 : _b.namespace,
1651
+ kind: "statefulset"
1652
+ },
1653
+ groupedResponses.horizontalPodAutoscalers
1654
+ ),
1514
1655
  ownedPods: getOwnedResources(statefulset, groupedResponses.pods),
1515
1656
  statefulset
1516
1657
  })));
@@ -1844,6 +1985,24 @@ const CronJobDrawer = ({
1844
1985
  }))));
1845
1986
  };
1846
1987
 
1988
+ const k8sCronAliases = /* @__PURE__ */ new Map([
1989
+ ["@yearly", "0 0 1 1 *"],
1990
+ ["@annually", "0 0 1 1 *"],
1991
+ ["@monthly", "0 0 1 * *"],
1992
+ ["@weekly", "0 0 * * 0"],
1993
+ ["@daily", "0 0 * * *"],
1994
+ ["@midnight", "0 0 * * *"],
1995
+ ["@hourly", "0 * * * *"]
1996
+ ]);
1997
+ const humanizeCron = (schedule) => {
1998
+ const deAliasedSchedule = k8sCronAliases.get(schedule) || schedule;
1999
+ try {
2000
+ return cronstrue.toString(deAliasedSchedule);
2001
+ } catch (e) {
2002
+ return deAliasedSchedule;
2003
+ }
2004
+ };
2005
+
1847
2006
  const CronJobSummary = ({ cronJob }) => {
1848
2007
  var _a, _b;
1849
2008
  return /* @__PURE__ */ React__default.createElement(Grid, {
@@ -1875,7 +2034,9 @@ const CronJobSummary = ({ cronJob }) => {
1875
2034
  item: true
1876
2035
  }, /* @__PURE__ */ React__default.createElement(Typography, {
1877
2036
  variant: "body1"
1878
- }, "Schedule:", " ", ((_b = cronJob.spec) == null ? void 0 : _b.schedule) ? `${cronJob.spec.schedule} (${cronstrue.toString(cronJob.spec.schedule)})` : "N/A"))));
2037
+ }, "Schedule:", " ", ((_b = cronJob.spec) == null ? void 0 : _b.schedule) ? `${cronJob.spec.schedule} (${humanizeCron(
2038
+ cronJob.spec.schedule
2039
+ )})` : "N/A"))));
1879
2040
  };
1880
2041
  const CronJobAccordion = ({ cronJob, ownedJobs }) => {
1881
2042
  return /* @__PURE__ */ React__default.createElement(Accordion, {
@@ -1965,11 +2126,13 @@ const StepsProgress = ({
1965
2126
  key: i
1966
2127
  }, /* @__PURE__ */ React__default.createElement(StepLabel, {
1967
2128
  "data-testid": `step-${i}`
1968
- }, createLabelForStep(step)))).concat(/* @__PURE__ */ React__default.createElement(Step, {
1969
- key: "-1"
1970
- }, /* @__PURE__ */ React__default.createElement(StepLabel, {
1971
- "data-testid": "step--1"
1972
- }, "Canary promoted"))));
2129
+ }, createLabelForStep(step)))).concat(
2130
+ /* @__PURE__ */ React__default.createElement(Step, {
2131
+ key: "-1"
2132
+ }, /* @__PURE__ */ React__default.createElement(StepLabel, {
2133
+ "data-testid": "step--1"
2134
+ }, "Canary promoted"))
2135
+ ));
1973
2136
  };
1974
2137
 
1975
2138
  const AbortedTitle = /* @__PURE__ */ React__default.createElement("div", {
@@ -1983,7 +2146,9 @@ const AbortedTitle = /* @__PURE__ */ React__default.createElement("div", {
1983
2146
  }, "Aborted"));
1984
2147
  const findAbortedMessage = (rollout) => {
1985
2148
  var _a, _b, _c;
1986
- return (_c = (_b = (_a = rollout.status) == null ? void 0 : _a.conditions) == null ? void 0 : _b.find((c) => c.type === "Progressing" && c.status === "False" && c.reason === "RolloutAborted")) == null ? void 0 : _c.message;
2149
+ return (_c = (_b = (_a = rollout.status) == null ? void 0 : _a.conditions) == null ? void 0 : _b.find(
2150
+ (c) => c.type === "Progressing" && c.status === "False" && c.reason === "RolloutAborted"
2151
+ )) == null ? void 0 : _c.message;
1987
2152
  };
1988
2153
  const RolloutSummary = ({
1989
2154
  rollout,
@@ -1992,7 +2157,9 @@ const RolloutSummary = ({
1992
2157
  hpa
1993
2158
  }) => {
1994
2159
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1995
- const pauseTime = (_c = (_b = (_a = rollout.status) == null ? void 0 : _a.pauseConditions) == null ? void 0 : _b.find((p) => p.reason === "CanaryPauseStep")) == null ? void 0 : _c.startTime;
2160
+ const pauseTime = (_c = (_b = (_a = rollout.status) == null ? void 0 : _a.pauseConditions) == null ? void 0 : _b.find(
2161
+ (p) => p.reason === "CanaryPauseStep"
2162
+ )) == null ? void 0 : _c.startTime;
1996
2163
  const abortedMessage = findAbortedMessage(rollout);
1997
2164
  return /* @__PURE__ */ React__default.createElement(Grid, {
1998
2165
  container: true,
@@ -2069,10 +2236,12 @@ const RolloutAccordion = ({
2069
2236
  }) => {
2070
2237
  var _a, _b, _c, _d, _e, _f;
2071
2238
  const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
2072
- const podsWithErrors = ownedPods.filter((p) => {
2073
- var _a2, _b2;
2074
- return podNamesWithErrors.has((_b2 = (_a2 = p.metadata) == null ? void 0 : _a2.name) != null ? _b2 : "");
2075
- });
2239
+ const podsWithErrors = ownedPods.filter(
2240
+ (p) => {
2241
+ var _a2, _b2;
2242
+ return podNamesWithErrors.has((_b2 = (_a2 = p.metadata) == null ? void 0 : _a2.name) != null ? _b2 : "");
2243
+ }
2244
+ );
2076
2245
  const currentStepIndex = (_b = (_a = rollout.status) == null ? void 0 : _a.currentStepIndex) != null ? _b : 0;
2077
2246
  const abortedMessage = findAbortedMessage(rollout);
2078
2247
  return /* @__PURE__ */ React__default.createElement(Accordion, {
@@ -2124,12 +2293,19 @@ const RolloutAccordions = ({
2124
2293
  xs: true
2125
2294
  }, /* @__PURE__ */ React__default.createElement(RolloutAccordion, {
2126
2295
  defaultExpanded,
2127
- matchingHpa: getMatchingHpa({
2128
- name: (_a = rollout.metadata) == null ? void 0 : _a.name,
2129
- namespace: (_b = rollout.metadata) == null ? void 0 : _b.namespace,
2130
- kind: "rollout"
2131
- }, groupedResponses.horizontalPodAutoscalers),
2132
- ownedPods: getOwnedPodsThroughReplicaSets(rollout, groupedResponses.replicaSets, groupedResponses.pods),
2296
+ matchingHpa: getMatchingHpa(
2297
+ {
2298
+ name: (_a = rollout.metadata) == null ? void 0 : _a.name,
2299
+ namespace: (_b = rollout.metadata) == null ? void 0 : _b.namespace,
2300
+ kind: "rollout"
2301
+ },
2302
+ groupedResponses.horizontalPodAutoscalers
2303
+ ),
2304
+ ownedPods: getOwnedPodsThroughReplicaSets(
2305
+ rollout,
2306
+ groupedResponses.replicaSets,
2307
+ groupedResponses.pods
2308
+ ),
2133
2309
  rollout
2134
2310
  })));
2135
2311
  }));
@@ -2350,7 +2526,10 @@ const KubernetesContent = ({
2350
2526
  refreshIntervalMs
2351
2527
  }) => {
2352
2528
  var _a;
2353
- const { kubernetesObjects, error } = useKubernetesObjects(entity, refreshIntervalMs);
2529
+ const { kubernetesObjects, error } = useKubernetesObjects(
2530
+ entity,
2531
+ refreshIntervalMs
2532
+ );
2354
2533
  const clustersWithErrors = (_a = kubernetesObjects == null ? void 0 : kubernetesObjects.items.filter((r) => r.errors.length > 0)) != null ? _a : [];
2355
2534
  const detectedErrors = kubernetesObjects !== void 0 ? detectErrors(kubernetesObjects) : /* @__PURE__ */ new Map();
2356
2535
  return /* @__PURE__ */ React__default.createElement(Page, {
@@ -2410,7 +2589,9 @@ const KubernetesContent = ({
2410
2589
  "data-testid": "emptyStateImg"
2411
2590
  }))), (kubernetesObjects == null ? void 0 : kubernetesObjects.items.length) > 0 && (kubernetesObjects == null ? void 0 : kubernetesObjects.items.map((item, i) => {
2412
2591
  var _a2, _b;
2413
- const podsWithErrors = new Set((_b = (_a2 = detectedErrors.get(item.cluster.name)) == null ? void 0 : _a2.filter((de) => de.kind === "Pod").map((de) => de.names).flat()) != null ? _b : []);
2592
+ const podsWithErrors = new Set(
2593
+ (_b = (_a2 = detectedErrors.get(item.cluster.name)) == null ? void 0 : _a2.filter((de) => de.kind === "Pod").map((de) => de.names).flat()) != null ? _b : []
2594
+ );
2414
2595
  return /* @__PURE__ */ React__default.createElement(Grid, {
2415
2596
  item: true,
2416
2597
  key: i,
@@ -2426,7 +2607,9 @@ const KUBERNETES_ANNOTATION = "backstage.io/kubernetes-id";
2426
2607
  const KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION = "backstage.io/kubernetes-label-selector";
2427
2608
  const isKubernetesAvailable = (entity) => {
2428
2609
  var _a, _b;
2429
- return Boolean((_a = entity.metadata.annotations) == null ? void 0 : _a[KUBERNETES_ANNOTATION]) || Boolean((_b = entity.metadata.annotations) == null ? void 0 : _b[KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION]);
2610
+ return Boolean((_a = entity.metadata.annotations) == null ? void 0 : _a[KUBERNETES_ANNOTATION]) || Boolean(
2611
+ (_b = entity.metadata.annotations) == null ? void 0 : _b[KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION]
2612
+ );
2430
2613
  };
2431
2614
  const Router = (props) => {
2432
2615
  var _a, _b;