@backstage/plugin-kubernetes 0.6.5-next.3 → 0.6.6-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/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @backstage/plugin-kubernetes
2
2
 
3
+ ## 0.6.6-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - b9b8bbc7d9: show request/limit CPU and Memory on the UI
8
+ - 8f7b1835df: Updated dependency `msw` to `^0.41.0`.
9
+ - Updated dependencies
10
+ - @backstage/core-components@0.9.5-next.1
11
+ - @backstage/core-plugin-api@1.0.3-next.0
12
+ - @backstage/catalog-model@1.0.3-next.0
13
+ - @backstage/plugin-catalog-react@1.1.1-next.1
14
+ - @backstage/plugin-kubernetes-common@0.3.0-next.1
15
+
16
+ ## 0.6.6-next.0
17
+
18
+ ### Patch Changes
19
+
20
+ - 4328737af6: Add support to fetch data for Stateful Sets and display an accordion in the same way as with Deployments
21
+ - 81304e3e91: Fix for HPA matching when deploying same HPA in multiple namespaces
22
+ - Updated dependencies
23
+ - @backstage/plugin-catalog-react@1.1.1-next.0
24
+ - @backstage/core-components@0.9.5-next.0
25
+ - @backstage/plugin-kubernetes-common@0.3.0-next.0
26
+
27
+ ## 0.6.5
28
+
29
+ ### Patch Changes
30
+
31
+ - 1ef98cfe48: add Azure Identity auth provider and AKS dashboard formatter
32
+ - 447e060872: Add support for 'oidc' as authProvider for kubernetes authentication
33
+ and adds optional 'oidcTokenProvider' config value. This will allow
34
+ users to authenticate to kubernetes cluster using id tokens obtained
35
+ from the configured auth provider in their backstage instance.
36
+ - Updated dependencies
37
+ - @backstage/core-components@0.9.4
38
+ - @backstage/plugin-kubernetes-common@0.2.10
39
+ - @backstage/core-plugin-api@1.0.2
40
+ - @backstage/plugin-catalog-react@1.1.0
41
+ - @backstage/config@1.0.1
42
+ - @backstage/catalog-model@1.0.2
43
+
3
44
  ## 0.6.5-next.3
4
45
 
5
46
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { DiscoveryApi, IdentityApi, OAuthApi, OpenIdConnectApi } from '@backstag
4
4
  import { Entity } from '@backstage/catalog-model';
5
5
  import { KubernetesRequestBody, ObjectsByEntityResponse, ClusterObjects, ClientPodStatus, ClusterAttributes } from '@backstage/plugin-kubernetes-common';
6
6
  import { JsonObject } from '@backstage/types';
7
- import { V1Pod, V1ReplicaSet, V1Deployment, V1HorizontalPodAutoscaler, V1Service, V1ConfigMap, V1Ingress, V1Job, V1CronJob, V1ObjectMeta } from '@kubernetes/client-node';
7
+ import { V1Pod, V1ReplicaSet, V1Deployment, V1HorizontalPodAutoscaler, V1Service, V1ConfigMap, V1Ingress, V1Job, V1CronJob, V1StatefulSet, V1ObjectMeta } from '@kubernetes/client-node';
8
8
  import React from 'react';
9
9
 
10
10
  declare const kubernetesPlugin: _backstage_core_plugin_api.BackstagePlugin<{
@@ -101,6 +101,7 @@ interface GroupedResponses extends DeploymentResources {
101
101
  jobs: V1Job[];
102
102
  cronJobs: V1CronJob[];
103
103
  customResources: any[];
104
+ statefulsets: V1StatefulSet[];
104
105
  }
105
106
  interface ClusterLinksFormatterOptions {
106
107
  dashboardUrl?: URL;
package/dist/index.esm.js CHANGED
@@ -340,6 +340,9 @@ const groupResponses = (fetchResponse) => {
340
340
  case "customresources":
341
341
  prev.customResources.push(...next.resources);
342
342
  break;
343
+ case "statefulsets":
344
+ prev.statefulsets.push(...next.resources);
345
+ break;
343
346
  }
344
347
  return prev;
345
348
  }, {
@@ -352,7 +355,8 @@ const groupResponses = (fetchResponse) => {
352
355
  ingresses: [],
353
356
  jobs: [],
354
357
  cronJobs: [],
355
- customResources: []
358
+ customResources: [],
359
+ statefulsets: []
356
360
  });
357
361
  };
358
362
 
@@ -436,6 +440,9 @@ const currentToDeclaredResourceToPerc = (current, resource) => {
436
440
  const denominator = BigInt(resource);
437
441
  return `${numerator * BigInt(100) / denominator}%`;
438
442
  };
443
+ const formatMilicores = (value) => {
444
+ return `${parseFloat(value.toString()) * 1e3}m`;
445
+ };
439
446
  const podStatusToCpuUtil = (podStatus) => {
440
447
  const cpuUtil = podStatus.cpu;
441
448
  let currentUsage = cpuUtil.currentUsage;
@@ -443,15 +450,18 @@ const podStatusToCpuUtil = (podStatus) => {
443
450
  currentUsage = cpuUtil.currentUsage / 10;
444
451
  }
445
452
  return /* @__PURE__ */ React__default.createElement(SubvalueCell, {
446
- value: `requests: ${currentToDeclaredResourceToPerc(currentUsage, cpuUtil.requestTotal)}`,
447
- subvalue: `limits: ${currentToDeclaredResourceToPerc(currentUsage, cpuUtil.limitTotal)}`
453
+ value: `requests: ${currentToDeclaredResourceToPerc(currentUsage, cpuUtil.requestTotal)} of ${formatMilicores(cpuUtil.requestTotal)}`,
454
+ subvalue: `limits: ${currentToDeclaredResourceToPerc(currentUsage, cpuUtil.limitTotal)} of ${formatMilicores(cpuUtil.limitTotal)}`
448
455
  });
449
456
  };
457
+ const bytesToMiB = (value) => {
458
+ return `${parseFloat(value.toString()) / 1024 / 1024}MiB`;
459
+ };
450
460
  const podStatusToMemoryUtil = (podStatus) => {
451
461
  const memUtil = podStatus.memory;
452
462
  return /* @__PURE__ */ React__default.createElement(SubvalueCell, {
453
- value: `requests: ${currentToDeclaredResourceToPerc(memUtil.currentUsage, memUtil.requestTotal)}`,
454
- subvalue: `limits: ${currentToDeclaredResourceToPerc(memUtil.currentUsage, memUtil.limitTotal)}`
463
+ value: `requests: ${currentToDeclaredResourceToPerc(memUtil.currentUsage, memUtil.requestTotal)} of ${bytesToMiB(memUtil.requestTotal)}`,
464
+ subvalue: `limits: ${currentToDeclaredResourceToPerc(memUtil.currentUsage, memUtil.limitTotal)} of ${bytesToMiB(memUtil.limitTotal)}`
455
465
  });
456
466
  };
457
467
 
@@ -677,7 +687,8 @@ const GroupedResponsesContext = React__default.createContext({
677
687
  ingresses: [],
678
688
  jobs: [],
679
689
  cronJobs: [],
680
- customResources: []
690
+ customResources: [],
691
+ statefulsets: []
681
692
  });
682
693
 
683
694
  const ClusterContext = React__default.createContext({
@@ -689,7 +700,8 @@ const kindMappings$3 = {
689
700
  pod: "pod",
690
701
  ingress: "ingress",
691
702
  service: "service",
692
- horizontalpodautoscaler: "deployment"
703
+ horizontalpodautoscaler: "deployment",
704
+ statefulset: "statefulset"
693
705
  };
694
706
  function standardFormatter(options) {
695
707
  var _a, _b, _c, _d;
@@ -1241,10 +1253,10 @@ const getOwnedPodsThroughReplicaSets = (potentialOwner, replicaSets, pods) => {
1241
1253
  return accum.concat(getOwnedResources(rs, pods));
1242
1254
  }, []);
1243
1255
  };
1244
- const getMatchingHpa = (ownerName, ownerKind, hpas) => {
1256
+ const getMatchingHpa = (owner, hpas) => {
1245
1257
  return hpas.find((hpa) => {
1246
- var _a, _b, _c, _d, _e, _f;
1247
- return ((_c = (_b = (_a = hpa.spec) == null ? void 0 : _a.scaleTargetRef) == null ? void 0 : _b.kind) != null ? _c : "").toLocaleLowerCase("en-US") === ownerKind.toLocaleLowerCase("en-US") && ((_f = (_e = (_d = hpa.spec) == null ? void 0 : _d.scaleTargetRef) == null ? void 0 : _e.name) != null ? _f : "") === (ownerName != null ? ownerName : "unknown-deployment");
1258
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1259
+ return ((_c = (_b = (_a = hpa.spec) == null ? void 0 : _a.scaleTargetRef) == null ? void 0 : _b.kind) != null ? _c : "").toLocaleLowerCase("en-US") === owner.kind.toLocaleLowerCase("en-US") && ((_e = (_d = hpa.metadata) == null ? void 0 : _d.namespace) != null ? _e : "") === ((_f = owner.namespace) != null ? _f : "unknown-namespace") && ((_i = (_h = (_g = hpa.spec) == null ? void 0 : _g.scaleTargetRef) == null ? void 0 : _h.name) != null ? _i : "") === ((_j = owner.name) != null ? _j : "unknown-deployment");
1248
1260
  });
1249
1261
  };
1250
1262
 
@@ -1340,7 +1352,7 @@ const DeploymentsAccordions = ({}) => {
1340
1352
  justifyContent: "flex-start",
1341
1353
  alignItems: "flex-start"
1342
1354
  }, groupedResponses.deployments.map((deployment, i) => {
1343
- var _a;
1355
+ var _a, _b;
1344
1356
  return /* @__PURE__ */ React__default.createElement(Grid, {
1345
1357
  container: true,
1346
1358
  item: true,
@@ -1350,13 +1362,178 @@ const DeploymentsAccordions = ({}) => {
1350
1362
  item: true,
1351
1363
  xs: true
1352
1364
  }, /* @__PURE__ */ React__default.createElement(DeploymentAccordion, {
1353
- matchingHpa: getMatchingHpa((_a = deployment.metadata) == null ? void 0 : _a.name, "deployment", groupedResponses.horizontalPodAutoscalers),
1365
+ matchingHpa: getMatchingHpa({
1366
+ name: (_a = deployment.metadata) == null ? void 0 : _a.name,
1367
+ namespace: (_b = deployment.metadata) == null ? void 0 : _b.namespace,
1368
+ kind: "deployment"
1369
+ }, groupedResponses.horizontalPodAutoscalers),
1354
1370
  ownedPods: getOwnedPodsThroughReplicaSets(deployment, groupedResponses.replicaSets, groupedResponses.pods),
1355
1371
  deployment
1356
1372
  })));
1357
1373
  }));
1358
1374
  };
1359
1375
 
1376
+ const StatefulSetDrawer = ({
1377
+ statefulset,
1378
+ expanded
1379
+ }) => {
1380
+ var _a, _b, _c;
1381
+ const namespace = (_a = statefulset.metadata) == null ? void 0 : _a.namespace;
1382
+ return /* @__PURE__ */ React__default.createElement(KubernetesDrawer, {
1383
+ object: statefulset,
1384
+ expanded,
1385
+ kind: "StatefulSet",
1386
+ renderObject: (statefulsetObj) => {
1387
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1388
+ const conditions = ((_b2 = (_a2 = statefulsetObj.status) == null ? void 0 : _a2.conditions) != null ? _b2 : []).map(renderCondition).reduce((accum, next) => {
1389
+ accum[next[0]] = next[1];
1390
+ return accum;
1391
+ }, {});
1392
+ return {
1393
+ updateStrategy: (_d = (_c2 = statefulset.spec) == null ? void 0 : _c2.updateStrategy) != null ? _d : "???",
1394
+ podManagementPolicy: (_f = (_e = statefulset.spec) == null ? void 0 : _e.podManagementPolicy) != null ? _f : "???",
1395
+ serviceName: (_h = (_g = statefulset.spec) == null ? void 0 : _g.serviceName) != null ? _h : "???",
1396
+ selector: (_j = (_i = statefulset.spec) == null ? void 0 : _i.selector) != null ? _j : "???",
1397
+ revisionHistoryLimit: (_l = (_k = statefulset.spec) == null ? void 0 : _k.revisionHistoryLimit) != null ? _l : "???",
1398
+ ...conditions
1399
+ };
1400
+ }
1401
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1402
+ container: true,
1403
+ direction: "column",
1404
+ justifyContent: "flex-start",
1405
+ alignItems: "flex-start",
1406
+ spacing: 0
1407
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1408
+ item: true
1409
+ }, /* @__PURE__ */ React__default.createElement(Typography, {
1410
+ variant: "h5"
1411
+ }, (_c = (_b = statefulset.metadata) == null ? void 0 : _b.name) != null ? _c : "unknown object")), /* @__PURE__ */ React__default.createElement(Grid, {
1412
+ item: true
1413
+ }, /* @__PURE__ */ React__default.createElement(Typography, {
1414
+ color: "textSecondary",
1415
+ variant: "body1"
1416
+ }, "Stateful Set")), namespace && /* @__PURE__ */ React__default.createElement(Grid, {
1417
+ item: true
1418
+ }, /* @__PURE__ */ React__default.createElement(Chip, {
1419
+ size: "small",
1420
+ label: `namespace: ${namespace}`
1421
+ }))));
1422
+ };
1423
+
1424
+ const StatefulSetSummary = ({
1425
+ statefulset,
1426
+ numberOfCurrentPods,
1427
+ numberOfPodsWithErrors,
1428
+ hpa
1429
+ }) => {
1430
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1431
+ return /* @__PURE__ */ React__default.createElement(Grid, {
1432
+ container: true,
1433
+ direction: "row",
1434
+ justifyContent: "flex-start",
1435
+ alignItems: "center"
1436
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1437
+ xs: 3,
1438
+ item: true
1439
+ }, /* @__PURE__ */ React__default.createElement(StatefulSetDrawer, {
1440
+ statefulset
1441
+ })), /* @__PURE__ */ React__default.createElement(Grid, {
1442
+ item: true,
1443
+ xs: 1
1444
+ }, /* @__PURE__ */ React__default.createElement(Divider, {
1445
+ style: { height: "5em" },
1446
+ orientation: "vertical"
1447
+ })), hpa && /* @__PURE__ */ React__default.createElement(Grid, {
1448
+ item: true,
1449
+ xs: 3
1450
+ }, /* @__PURE__ */ React__default.createElement(HorizontalPodAutoscalerDrawer, {
1451
+ hpa
1452
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1453
+ item: true,
1454
+ container: true,
1455
+ direction: "column",
1456
+ justifyContent: "flex-start",
1457
+ alignItems: "flex-start",
1458
+ spacing: 0
1459
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1460
+ item: true
1461
+ }, /* @__PURE__ */ React__default.createElement(Typography, {
1462
+ variant: "subtitle2"
1463
+ }, "min replicas ", (_b = (_a = hpa.spec) == null ? void 0 : _a.minReplicas) != null ? _b : "?", " / max replicas", " ", (_d = (_c = hpa.spec) == null ? void 0 : _c.maxReplicas) != null ? _d : "?")), /* @__PURE__ */ React__default.createElement(Grid, {
1464
+ item: true
1465
+ }, /* @__PURE__ */ React__default.createElement(Typography, {
1466
+ variant: "subtitle2"
1467
+ }, "current CPU usage:", " ", (_f = (_e = hpa.status) == null ? void 0 : _e.currentCPUUtilizationPercentage) != null ? _f : "?", "%")), /* @__PURE__ */ React__default.createElement(Grid, {
1468
+ item: true
1469
+ }, /* @__PURE__ */ React__default.createElement(Typography, {
1470
+ variant: "subtitle2"
1471
+ }, "target CPU usage:", " ", (_h = (_g = hpa.spec) == null ? void 0 : _g.targetCPUUtilizationPercentage) != null ? _h : "?", "%"))))), /* @__PURE__ */ React__default.createElement(Grid, {
1472
+ item: true,
1473
+ container: true,
1474
+ xs: 3,
1475
+ direction: "column",
1476
+ justifyContent: "flex-start",
1477
+ alignItems: "flex-start"
1478
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1479
+ item: true
1480
+ }, /* @__PURE__ */ React__default.createElement(StatusOK, null, numberOfCurrentPods, " pods")), /* @__PURE__ */ React__default.createElement(Grid, {
1481
+ item: true
1482
+ }, numberOfPodsWithErrors > 0 ? /* @__PURE__ */ React__default.createElement(StatusError, null, numberOfPodsWithErrors, " pod", numberOfPodsWithErrors > 1 ? "s" : "", " with errors") : /* @__PURE__ */ React__default.createElement(StatusOK, null, "No pods with errors"))));
1483
+ };
1484
+ const StatefulSetAccordion = ({
1485
+ statefulset,
1486
+ ownedPods,
1487
+ matchingHpa
1488
+ }) => {
1489
+ const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
1490
+ const podsWithErrors = ownedPods.filter((p) => {
1491
+ var _a, _b;
1492
+ return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
1493
+ });
1494
+ return /* @__PURE__ */ React__default.createElement(Accordion, {
1495
+ TransitionProps: { unmountOnExit: true }
1496
+ }, /* @__PURE__ */ React__default.createElement(AccordionSummary, {
1497
+ expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null)
1498
+ }, /* @__PURE__ */ React__default.createElement(StatefulSetSummary, {
1499
+ statefulset,
1500
+ numberOfCurrentPods: ownedPods.length,
1501
+ numberOfPodsWithErrors: podsWithErrors.length,
1502
+ hpa: matchingHpa
1503
+ })), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(PodsTable, {
1504
+ pods: ownedPods,
1505
+ extraColumns: [READY_COLUMNS, RESOURCE_COLUMNS]
1506
+ })));
1507
+ };
1508
+ const StatefulSetsAccordions = ({}) => {
1509
+ const groupedResponses = useContext(GroupedResponsesContext);
1510
+ return /* @__PURE__ */ React__default.createElement(Grid, {
1511
+ container: true,
1512
+ direction: "column",
1513
+ justifyContent: "flex-start",
1514
+ alignItems: "flex-start"
1515
+ }, groupedResponses.statefulsets.map((statefulset, i) => {
1516
+ var _a, _b;
1517
+ return /* @__PURE__ */ React__default.createElement(Grid, {
1518
+ container: true,
1519
+ item: true,
1520
+ key: i,
1521
+ xs: true
1522
+ }, /* @__PURE__ */ React__default.createElement(Grid, {
1523
+ item: true,
1524
+ xs: true
1525
+ }, /* @__PURE__ */ React__default.createElement(StatefulSetAccordion, {
1526
+ matchingHpa: getMatchingHpa({
1527
+ name: (_a = statefulset.metadata) == null ? void 0 : _a.name,
1528
+ namespace: (_b = statefulset.metadata) == null ? void 0 : _b.namespace,
1529
+ kind: "statefulset"
1530
+ }, groupedResponses.horizontalPodAutoscalers),
1531
+ ownedPods: getOwnedResources(statefulset, groupedResponses.pods),
1532
+ statefulset
1533
+ })));
1534
+ }));
1535
+ };
1536
+
1360
1537
  const IngressDrawer = ({
1361
1538
  ingress,
1362
1539
  expanded
@@ -1953,7 +2130,7 @@ const RolloutAccordions = ({
1953
2130
  justifyContent: "flex-start",
1954
2131
  alignItems: "flex-start"
1955
2132
  }, rollouts.map((rollout, i) => {
1956
- var _a;
2133
+ var _a, _b;
1957
2134
  return /* @__PURE__ */ React__default.createElement(Grid, {
1958
2135
  container: true,
1959
2136
  item: true,
@@ -1964,7 +2141,11 @@ const RolloutAccordions = ({
1964
2141
  xs: true
1965
2142
  }, /* @__PURE__ */ React__default.createElement(RolloutAccordion, {
1966
2143
  defaultExpanded,
1967
- matchingHpa: getMatchingHpa((_a = rollout.metadata) == null ? void 0 : _a.name, "rollout", groupedResponses.horizontalPodAutoscalers),
2144
+ matchingHpa: getMatchingHpa({
2145
+ name: (_a = rollout.metadata) == null ? void 0 : _a.name,
2146
+ namespace: (_b = rollout.metadata) == null ? void 0 : _b.namespace,
2147
+ kind: "rollout"
2148
+ }, groupedResponses.horizontalPodAutoscalers),
1968
2149
  ownedPods: getOwnedPodsThroughReplicaSets(rollout, groupedResponses.replicaSets, groupedResponses.pods),
1969
2150
  rollout
1970
2151
  })));
@@ -2172,6 +2353,8 @@ const Cluster = ({ clusterObjects, podsWithErrors }) => {
2172
2353
  item: true
2173
2354
  }, /* @__PURE__ */ React__default.createElement(DeploymentsAccordions, null)), /* @__PURE__ */ React__default.createElement(Grid, {
2174
2355
  item: true
2356
+ }, /* @__PURE__ */ React__default.createElement(StatefulSetsAccordions, null)), /* @__PURE__ */ React__default.createElement(Grid, {
2357
+ item: true
2175
2358
  }, /* @__PURE__ */ React__default.createElement(IngressesAccordions, null)), /* @__PURE__ */ React__default.createElement(Grid, {
2176
2359
  item: true
2177
2360
  }, /* @__PURE__ */ React__default.createElement(ServicesAccordions, null)), /* @__PURE__ */ React__default.createElement(Grid, {