@backstage/plugin-kubernetes 0.8.1-next.0 → 0.9.0-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 +43 -0
- package/dist/index.d.ts +77 -11
- package/dist/index.esm.js +589 -203
- package/dist/index.esm.js.map +1 -1
- package/package.json +7 -6
package/dist/index.esm.js
CHANGED
|
@@ -2,20 +2,24 @@ import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
|
2
2
|
import { NotFoundError } from '@backstage/errors';
|
|
3
3
|
import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, gitlabAuthApiRef, googleAuthApiRef, microsoftAuthApiRef, oktaAuthApiRef, oneloginAuthApiRef, createRoutableExtension, useApi } from '@backstage/core-plugin-api';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import React__default, {
|
|
5
|
+
import React__default, { useState, useCallback, useContext, Fragment } from 'react';
|
|
6
6
|
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
7
7
|
import { Routes, Route } from 'react-router-dom';
|
|
8
|
-
import { Typography,
|
|
9
|
-
import { WarningPanel, Table,
|
|
8
|
+
import { Typography, Paper, makeStyles, createStyles, Dialog, DialogTitle, IconButton, DialogContent, Button, Card, CardHeader, CardContent, Grid, CardActions, FormControlLabel, Switch, Drawer, withStyles as withStyles$1, List, ListItem, Chip, Accordion, AccordionSummary, AccordionDetails, Stepper, Step, StepLabel } from '@material-ui/core';
|
|
9
|
+
import { WarningPanel, Table, DismissableBanner, LogViewer, StructuredMetadataTable, CodeSnippet, LinkButton, StatusError, StatusOK, StatusWarning, ItemCardGrid, SubvalueCell, StatusAborted, StatusPending, Page, Content, Progress, MissingAnnotationEmptyState } from '@backstage/core-components';
|
|
10
10
|
import lodash from 'lodash';
|
|
11
11
|
import { DateTime } from 'luxon';
|
|
12
12
|
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
|
13
|
-
import
|
|
13
|
+
import { Skeleton } from '@material-ui/lab';
|
|
14
|
+
import { kubernetesProxyApiRef as kubernetesProxyApiRef$1 } from '@backstage/plugin-kubernetes';
|
|
15
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
16
|
+
import SubjectIcon from '@material-ui/icons/Subject';
|
|
17
|
+
import CloseIcon from '@material-ui/icons/Close';
|
|
14
18
|
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
|
|
15
19
|
import { withStyles } from '@material-ui/core/styles';
|
|
16
|
-
import jsYaml from 'js-yaml';
|
|
17
20
|
import useInterval from 'react-use/lib/useInterval';
|
|
18
21
|
import useAsyncRetry from 'react-use/lib/useAsyncRetry';
|
|
22
|
+
import jsyaml from 'js-yaml';
|
|
19
23
|
import cronstrue from 'cronstrue';
|
|
20
24
|
import PauseIcon from '@material-ui/icons/Pause';
|
|
21
25
|
import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';
|
|
@@ -121,6 +125,9 @@ class KubernetesBackendClient {
|
|
|
121
125
|
const kubernetesApiRef = createApiRef({
|
|
122
126
|
id: "plugin.kubernetes.service"
|
|
123
127
|
});
|
|
128
|
+
const kubernetesProxyApiRef = createApiRef({
|
|
129
|
+
id: "plugin.kubernetes.proxy-service"
|
|
130
|
+
});
|
|
124
131
|
|
|
125
132
|
const kubernetesAuthProvidersApiRef = createApiRef({
|
|
126
133
|
id: "plugin.kubernetes-auth-providers.service"
|
|
@@ -251,6 +258,41 @@ class KubernetesAuthProviders {
|
|
|
251
258
|
}
|
|
252
259
|
}
|
|
253
260
|
|
|
261
|
+
class KubernetesProxyClient {
|
|
262
|
+
constructor(options) {
|
|
263
|
+
this.kubernetesApi = options.kubernetesApi;
|
|
264
|
+
}
|
|
265
|
+
async handleText(response) {
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
const payload = await response.text();
|
|
268
|
+
let message;
|
|
269
|
+
switch (response.status) {
|
|
270
|
+
default:
|
|
271
|
+
message = `Proxy request failed with ${response.status} ${response.statusText}, ${payload}`;
|
|
272
|
+
}
|
|
273
|
+
throw new Error(message);
|
|
274
|
+
}
|
|
275
|
+
return await response.text();
|
|
276
|
+
}
|
|
277
|
+
async getPodLogs({
|
|
278
|
+
podName,
|
|
279
|
+
namespace,
|
|
280
|
+
clusterName,
|
|
281
|
+
containerName
|
|
282
|
+
}) {
|
|
283
|
+
const params = new URLSearchParams({
|
|
284
|
+
container: containerName
|
|
285
|
+
});
|
|
286
|
+
return await this.kubernetesApi.proxy({
|
|
287
|
+
clusterName,
|
|
288
|
+
path: `/api/v1/namespaces/${namespace}/pods/${podName}/log?${params.toString()}`,
|
|
289
|
+
init: {
|
|
290
|
+
method: "GET"
|
|
291
|
+
}
|
|
292
|
+
}).then((response) => this.handleText(response)).then((text) => ({ text }));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
254
296
|
const rootCatalogKubernetesRouteRef = createRouteRef({
|
|
255
297
|
id: "kubernetes"
|
|
256
298
|
});
|
|
@@ -270,6 +312,15 @@ const kubernetesPlugin = createPlugin({
|
|
|
270
312
|
kubernetesAuthProvidersApi
|
|
271
313
|
})
|
|
272
314
|
}),
|
|
315
|
+
createApiFactory({
|
|
316
|
+
api: kubernetesProxyApiRef,
|
|
317
|
+
deps: {
|
|
318
|
+
kubernetesApi: kubernetesApiRef
|
|
319
|
+
},
|
|
320
|
+
factory: ({ kubernetesApi }) => new KubernetesProxyClient({
|
|
321
|
+
kubernetesApi
|
|
322
|
+
})
|
|
323
|
+
}),
|
|
273
324
|
createApiFactory({
|
|
274
325
|
api: kubernetesAuthProvidersApiRef,
|
|
275
326
|
deps: {
|
|
@@ -316,7 +367,7 @@ const clustersWithErrorsToErrorMessage = (clustersWithErrors) => {
|
|
|
316
367
|
}), /* @__PURE__ */ React__default.createElement("br", null));
|
|
317
368
|
});
|
|
318
369
|
};
|
|
319
|
-
const ErrorPanel
|
|
370
|
+
const ErrorPanel = ({
|
|
320
371
|
entityName,
|
|
321
372
|
errorMessage,
|
|
322
373
|
clustersWithErrors
|
|
@@ -626,127 +677,162 @@ const detectErrors = (objects) => {
|
|
|
626
677
|
return errors;
|
|
627
678
|
};
|
|
628
679
|
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
const containerStatuses2 = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
|
|
640
|
-
const containersReadyItem = containerStatuses2.filter((cs) => cs.ready).length;
|
|
641
|
-
return `${containersReadyItem}/${containerStatuses2.length}`;
|
|
680
|
+
const usePodLogs = ({ podScope }) => {
|
|
681
|
+
const kubernetesProxyApi = useApi(kubernetesProxyApiRef$1);
|
|
682
|
+
return useAsync(async () => {
|
|
683
|
+
return await kubernetesProxyApi.getPodLogs({
|
|
684
|
+
podName: podScope.podName,
|
|
685
|
+
namespace: podScope.podNamespace,
|
|
686
|
+
containerName: podScope.containerName,
|
|
687
|
+
clusterName: podScope.clusterName
|
|
688
|
+
});
|
|
689
|
+
}, [JSON.stringify(podScope)]);
|
|
642
690
|
};
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
const
|
|
646
|
-
|
|
691
|
+
|
|
692
|
+
const PodLogs = ({ podScope }) => {
|
|
693
|
+
const { value, error, loading } = usePodLogs({
|
|
694
|
+
podScope
|
|
695
|
+
});
|
|
696
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, error && /* @__PURE__ */ React__default.createElement(
|
|
697
|
+
DismissableBanner,
|
|
698
|
+
{
|
|
699
|
+
...{
|
|
700
|
+
message: error.message,
|
|
701
|
+
variant: "error",
|
|
702
|
+
fixed: false
|
|
703
|
+
},
|
|
704
|
+
id: "pod-logs"
|
|
705
|
+
}
|
|
706
|
+
), /* @__PURE__ */ React__default.createElement(
|
|
707
|
+
Paper,
|
|
708
|
+
{
|
|
709
|
+
elevation: 1,
|
|
710
|
+
style: { height: "100%", width: "100%", minHeight: "30rem" }
|
|
711
|
+
},
|
|
712
|
+
loading && /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rect", width: "100%", height: "100%" }),
|
|
713
|
+
!loading && value !== void 0 && /* @__PURE__ */ React__default.createElement(LogViewer, { text: value.text })
|
|
714
|
+
));
|
|
647
715
|
};
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
716
|
+
|
|
717
|
+
const useStyles = makeStyles(
|
|
718
|
+
(theme) => createStyles({
|
|
719
|
+
closeButton: {
|
|
720
|
+
position: "absolute",
|
|
721
|
+
right: theme.spacing(1),
|
|
722
|
+
top: theme.spacing(1),
|
|
723
|
+
color: theme.palette.grey[500]
|
|
654
724
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
725
|
+
})
|
|
726
|
+
);
|
|
727
|
+
const PodLogsDialog = ({ podScope }) => {
|
|
728
|
+
const classes = useStyles();
|
|
729
|
+
const [open, setOpen] = useState(false);
|
|
730
|
+
const openDialog = () => {
|
|
731
|
+
setOpen(true);
|
|
732
|
+
};
|
|
733
|
+
const closeDialog = () => {
|
|
734
|
+
setOpen(false);
|
|
735
|
+
};
|
|
736
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Dialog, { maxWidth: "xl", fullWidth: true, open, onClose: closeDialog }, /* @__PURE__ */ React__default.createElement(DialogTitle, { id: "dialog-title" }, podScope.podName, " - ", podScope.containerName, " logs on cluster", " ", podScope.clusterName, /* @__PURE__ */ React__default.createElement(
|
|
737
|
+
IconButton,
|
|
738
|
+
{
|
|
739
|
+
"aria-label": "close",
|
|
740
|
+
className: classes.closeButton,
|
|
741
|
+
onClick: closeDialog
|
|
742
|
+
},
|
|
743
|
+
/* @__PURE__ */ React__default.createElement(CloseIcon, null)
|
|
744
|
+
)), /* @__PURE__ */ React__default.createElement(DialogContent, null, /* @__PURE__ */ React__default.createElement(PodLogs, { podScope }))), /* @__PURE__ */ React__default.createElement(
|
|
745
|
+
Button,
|
|
746
|
+
{
|
|
747
|
+
variant: "outlined",
|
|
748
|
+
"aria-label": "get logs",
|
|
749
|
+
component: "label",
|
|
750
|
+
onClick: openDialog,
|
|
751
|
+
startIcon: /* @__PURE__ */ React__default.createElement(SubjectIcon, null)
|
|
752
|
+
},
|
|
753
|
+
"Logs"
|
|
754
|
+
));
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
const getContainerHealthChecks = (containerSpec, containerStatus) => {
|
|
758
|
+
var _a, _b, _c, _d;
|
|
759
|
+
if (((_b = (_a = containerStatus.state) == null ? void 0 : _a.terminated) == null ? void 0 : _b.reason) === "Completed") {
|
|
760
|
+
return {
|
|
761
|
+
"not waiting to start": ((_c = containerStatus.state) == null ? void 0 : _c.waiting) === void 0,
|
|
762
|
+
"no restarts": containerStatus.restartCount === 0
|
|
666
763
|
};
|
|
667
|
-
if (waiting) {
|
|
668
|
-
accum.push(renderCell(waiting.reason));
|
|
669
|
-
}
|
|
670
|
-
if (terminated) {
|
|
671
|
-
accum.push(renderCell(terminated.reason));
|
|
672
|
-
}
|
|
673
|
-
return accum;
|
|
674
|
-
}, []);
|
|
675
|
-
if (errors.length === 0) {
|
|
676
|
-
return /* @__PURE__ */ React__default.createElement(StatusOK, null, "OK");
|
|
677
764
|
}
|
|
678
|
-
return
|
|
765
|
+
return {
|
|
766
|
+
"not waiting to start": ((_d = containerStatus.state) == null ? void 0 : _d.waiting) === void 0,
|
|
767
|
+
started: !!containerStatus.started,
|
|
768
|
+
ready: containerStatus.ready,
|
|
769
|
+
"no restarts": containerStatus.restartCount === 0,
|
|
770
|
+
"readiness probe set": containerSpec && (containerSpec == null ? void 0 : containerSpec.readinessProbe) !== void 0
|
|
771
|
+
};
|
|
679
772
|
};
|
|
680
|
-
const
|
|
681
|
-
var _a;
|
|
682
|
-
|
|
683
|
-
if (status === "True") {
|
|
684
|
-
return [condition.type, /* @__PURE__ */ React__default.createElement(StatusOK, null, "True")];
|
|
685
|
-
} else if (status === "False") {
|
|
686
|
-
return [
|
|
687
|
-
condition.type,
|
|
688
|
-
/* @__PURE__ */ React__default.createElement(
|
|
689
|
-
SubvalueCell,
|
|
690
|
-
{
|
|
691
|
-
value: /* @__PURE__ */ React__default.createElement(StatusError, null, "False"),
|
|
692
|
-
subvalue: (_a = condition.message) != null ? _a : ""
|
|
693
|
-
}
|
|
694
|
-
)
|
|
695
|
-
];
|
|
696
|
-
}
|
|
697
|
-
return [condition.type, /* @__PURE__ */ React__default.createElement(StatusAborted, null)];
|
|
773
|
+
const getCurrentState = (containerStatus) => {
|
|
774
|
+
var _a, _b, _c, _d, _e;
|
|
775
|
+
return ((_b = (_a = containerStatus.state) == null ? void 0 : _a.waiting) == null ? void 0 : _b.reason) || ((_d = (_c = containerStatus.state) == null ? void 0 : _c.terminated) == null ? void 0 : _d.reason) || (((_e = containerStatus.state) == null ? void 0 : _e.running) !== void 0 ? "Running" : "Unknown");
|
|
698
776
|
};
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
if (typeof current === "number" && typeof resource === "number") {
|
|
703
|
-
return `${Math.round(current / resource * 100)}%`;
|
|
704
|
-
}
|
|
705
|
-
const numerator = BigInt(current);
|
|
706
|
-
const denominator = BigInt(resource);
|
|
707
|
-
return `${numerator * BigInt(100) / denominator}%`;
|
|
777
|
+
const getStartedAtTime = (containerStatus) => {
|
|
778
|
+
var _a, _b, _c, _d;
|
|
779
|
+
return ((_b = (_a = containerStatus.state) == null ? void 0 : _a.running) == null ? void 0 : _b.startedAt) || ((_d = (_c = containerStatus.state) == null ? void 0 : _c.terminated) == null ? void 0 : _d.startedAt);
|
|
708
780
|
};
|
|
709
|
-
const
|
|
710
|
-
return
|
|
781
|
+
const ContainerDatetime = ({ prefix, dateTime }) => {
|
|
782
|
+
return /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, prefix, ":", " ", DateTime.fromISO(dateTime).toRelative({
|
|
783
|
+
locale: "en"
|
|
784
|
+
}));
|
|
711
785
|
};
|
|
712
|
-
const
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
786
|
+
const ContainerCard = ({
|
|
787
|
+
podScope,
|
|
788
|
+
containerSpec,
|
|
789
|
+
containerStatus
|
|
790
|
+
}) => {
|
|
791
|
+
var _a, _b;
|
|
792
|
+
if (containerSpec === void 0) {
|
|
793
|
+
return /* @__PURE__ */ React__default.createElement(Typography, null, "error reading pod from cluster");
|
|
717
794
|
}
|
|
718
|
-
|
|
719
|
-
|
|
795
|
+
const containerStartedTime = getStartedAtTime(containerStatus);
|
|
796
|
+
const containerFinishedTime = (_b = (_a = containerStatus.state) == null ? void 0 : _a.terminated) == null ? void 0 : _b.finishedAt;
|
|
797
|
+
return /* @__PURE__ */ React__default.createElement(Card, null, /* @__PURE__ */ React__default.createElement(
|
|
798
|
+
CardHeader,
|
|
720
799
|
{
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
cpuUtil.requestTotal
|
|
724
|
-
)} of ${formatMilicores(cpuUtil.requestTotal)}`,
|
|
725
|
-
subvalue: `limits: ${currentToDeclaredResourceToPerc(
|
|
726
|
-
currentUsage,
|
|
727
|
-
cpuUtil.limitTotal
|
|
728
|
-
)} of ${formatMilicores(cpuUtil.limitTotal)}`
|
|
800
|
+
title: containerStatus.name,
|
|
801
|
+
subheader: containerStatus.image
|
|
729
802
|
}
|
|
730
|
-
)
|
|
731
|
-
|
|
732
|
-
const bytesToMiB = (value) => {
|
|
733
|
-
return `${parseFloat(value.toString()) / 1024 / 1024}MiB`;
|
|
734
|
-
};
|
|
735
|
-
const podStatusToMemoryUtil = (podStatus) => {
|
|
736
|
-
const memUtil = podStatus.memory;
|
|
737
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
738
|
-
SubvalueCell,
|
|
803
|
+
), /* @__PURE__ */ React__default.createElement(CardContent, null, /* @__PURE__ */ React__default.createElement(Grid, { container: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, containerStartedTime && /* @__PURE__ */ React__default.createElement(
|
|
804
|
+
ContainerDatetime,
|
|
739
805
|
{
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
memUtil.requestTotal
|
|
743
|
-
)} of ${bytesToMiB(memUtil.requestTotal)}`,
|
|
744
|
-
subvalue: `limits: ${currentToDeclaredResourceToPerc(
|
|
745
|
-
memUtil.currentUsage,
|
|
746
|
-
memUtil.limitTotal
|
|
747
|
-
)} of ${bytesToMiB(memUtil.limitTotal)}`
|
|
806
|
+
prefix: "Started",
|
|
807
|
+
dateTime: containerStartedTime
|
|
748
808
|
}
|
|
749
|
-
)
|
|
809
|
+
), containerFinishedTime && /* @__PURE__ */ React__default.createElement(
|
|
810
|
+
ContainerDatetime,
|
|
811
|
+
{
|
|
812
|
+
prefix: "Completed",
|
|
813
|
+
dateTime: containerFinishedTime
|
|
814
|
+
}
|
|
815
|
+
), containerStartedTime && containerFinishedTime && /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "Execution time:", " ", DateTime.fromISO(containerFinishedTime).diff(DateTime.fromISO(containerStartedTime), [
|
|
816
|
+
"hours",
|
|
817
|
+
"minutes",
|
|
818
|
+
"seconds"
|
|
819
|
+
]).toHuman())), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "Status: ", getCurrentState(containerStatus))), containerStatus.restartCount > 0 && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "Restarts: ", containerStatus.restartCount)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "Container health")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
|
|
820
|
+
StructuredMetadataTable,
|
|
821
|
+
{
|
|
822
|
+
metadata: getContainerHealthChecks(
|
|
823
|
+
containerSpec,
|
|
824
|
+
containerStatus
|
|
825
|
+
)
|
|
826
|
+
}
|
|
827
|
+
)))), /* @__PURE__ */ React__default.createElement(CardActions, { disableSpacing: true }, /* @__PURE__ */ React__default.createElement(
|
|
828
|
+
PodLogsDialog,
|
|
829
|
+
{
|
|
830
|
+
podScope: {
|
|
831
|
+
containerName: containerStatus.name,
|
|
832
|
+
...podScope
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
)));
|
|
750
836
|
};
|
|
751
837
|
|
|
752
838
|
const generateAuth = async (entity, kubernetesApi, kubernetesAuthProvidersApi) => {
|
|
@@ -1067,7 +1153,43 @@ function formatClusterLink(options) {
|
|
|
1067
1153
|
return url.toString();
|
|
1068
1154
|
}
|
|
1069
1155
|
|
|
1070
|
-
const
|
|
1156
|
+
const ManifestYaml = ({ object }) => {
|
|
1157
|
+
const [managedFields, setManagedFields] = useState(false);
|
|
1158
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
|
|
1159
|
+
FormControlLabel,
|
|
1160
|
+
{
|
|
1161
|
+
control: /* @__PURE__ */ React__default.createElement(
|
|
1162
|
+
Switch,
|
|
1163
|
+
{
|
|
1164
|
+
checked: managedFields,
|
|
1165
|
+
onChange: (event) => {
|
|
1166
|
+
setManagedFields(event.target.checked);
|
|
1167
|
+
},
|
|
1168
|
+
name: "Managed Fields"
|
|
1169
|
+
}
|
|
1170
|
+
),
|
|
1171
|
+
label: "Managed Fields"
|
|
1172
|
+
}
|
|
1173
|
+
), /* @__PURE__ */ React__default.createElement(
|
|
1174
|
+
CodeSnippet,
|
|
1175
|
+
{
|
|
1176
|
+
language: "yaml",
|
|
1177
|
+
text: jsyaml.dump(object, {
|
|
1178
|
+
// NOTE: this will remove any field called `managedFields`
|
|
1179
|
+
// not just the metadata one
|
|
1180
|
+
// TODO: @mclarke make this only remove the `metadata.managedFields`
|
|
1181
|
+
replacer: (key, value) => {
|
|
1182
|
+
if (!managedFields) {
|
|
1183
|
+
return key === "managedFields" ? void 0 : value;
|
|
1184
|
+
}
|
|
1185
|
+
return value;
|
|
1186
|
+
}
|
|
1187
|
+
})
|
|
1188
|
+
}
|
|
1189
|
+
));
|
|
1190
|
+
};
|
|
1191
|
+
|
|
1192
|
+
const useDrawerStyles$1 = makeStyles(
|
|
1071
1193
|
(theme) => createStyles({
|
|
1072
1194
|
paper: {
|
|
1073
1195
|
width: "50%",
|
|
@@ -1076,7 +1198,7 @@ const useDrawerStyles = makeStyles(
|
|
|
1076
1198
|
}
|
|
1077
1199
|
})
|
|
1078
1200
|
);
|
|
1079
|
-
const useDrawerContentStyles = makeStyles(
|
|
1201
|
+
const useDrawerContentStyles$2 = makeStyles(
|
|
1080
1202
|
(_) => createStyles({
|
|
1081
1203
|
header: {
|
|
1082
1204
|
display: "flex",
|
|
@@ -1108,7 +1230,7 @@ const PodDrawerButton = withStyles({
|
|
|
1108
1230
|
textTransform: "none"
|
|
1109
1231
|
}
|
|
1110
1232
|
})(Button);
|
|
1111
|
-
const
|
|
1233
|
+
const LinkErrorPanel = ({ cluster, errorMessage }) => /* @__PURE__ */ React__default.createElement(
|
|
1112
1234
|
WarningPanel,
|
|
1113
1235
|
{
|
|
1114
1236
|
title: "There was a problem formatting the link to the Kubernetes dashboard",
|
|
@@ -1133,7 +1255,7 @@ function tryFormatClusterLink(options) {
|
|
|
1133
1255
|
};
|
|
1134
1256
|
}
|
|
1135
1257
|
}
|
|
1136
|
-
const
|
|
1258
|
+
const KubernetesStructuredMetadataTableDrawerContent = ({
|
|
1137
1259
|
toggleDrawer,
|
|
1138
1260
|
object,
|
|
1139
1261
|
renderObject,
|
|
@@ -1141,7 +1263,7 @@ const KubernetesDrawerContent = ({
|
|
|
1141
1263
|
}) => {
|
|
1142
1264
|
var _a, _b;
|
|
1143
1265
|
const [isYaml, setIsYaml] = useState(false);
|
|
1144
|
-
const classes = useDrawerContentStyles();
|
|
1266
|
+
const classes = useDrawerContentStyles$2();
|
|
1145
1267
|
const cluster = useContext(ClusterContext);
|
|
1146
1268
|
const { clusterLink, errorMessage } = tryFormatClusterLink({
|
|
1147
1269
|
dashboardUrl: cluster.dashboardUrl,
|
|
@@ -1150,17 +1272,7 @@ const KubernetesDrawerContent = ({
|
|
|
1150
1272
|
object,
|
|
1151
1273
|
kind
|
|
1152
1274
|
});
|
|
1153
|
-
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: classes.header }, /* @__PURE__ */ React__default.createElement(
|
|
1154
|
-
Grid,
|
|
1155
|
-
{
|
|
1156
|
-
container: true,
|
|
1157
|
-
direction: "column",
|
|
1158
|
-
justifyContent: "flex-start",
|
|
1159
|
-
alignItems: "flex-start"
|
|
1160
|
-
},
|
|
1161
|
-
/* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, (_b = (_a = object.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown name")),
|
|
1162
|
-
/* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "body1" }, kind))
|
|
1163
|
-
), /* @__PURE__ */ React__default.createElement(
|
|
1275
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: classes.header }, /* @__PURE__ */ React__default.createElement(Grid, { container: true, justifyContent: "flex-start", alignItems: "flex-start" }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 11 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, (_b = (_a = object.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown name")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 1 }, /* @__PURE__ */ React__default.createElement(
|
|
1164
1276
|
IconButton,
|
|
1165
1277
|
{
|
|
1166
1278
|
key: "dismiss",
|
|
@@ -1168,18 +1280,8 @@ const KubernetesDrawerContent = ({
|
|
|
1168
1280
|
onClick: (e) => toggleDrawer(e, false),
|
|
1169
1281
|
color: "inherit"
|
|
1170
1282
|
},
|
|
1171
|
-
/* @__PURE__ */ React__default.createElement(
|
|
1172
|
-
)),
|
|
1173
|
-
LinkButton,
|
|
1174
|
-
{
|
|
1175
|
-
variant: "outlined",
|
|
1176
|
-
color: "primary",
|
|
1177
|
-
size: "small",
|
|
1178
|
-
to: clusterLink,
|
|
1179
|
-
endIcon: /* @__PURE__ */ React__default.createElement(OpenInNewIcon, null)
|
|
1180
|
-
},
|
|
1181
|
-
"Open Kubernetes Dashboard"
|
|
1182
|
-
)), /* @__PURE__ */ React__default.createElement(
|
|
1283
|
+
/* @__PURE__ */ React__default.createElement(CloseIcon, { className: classes.icon })
|
|
1284
|
+
)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 11 }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "body1" }, kind)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 11 }, /* @__PURE__ */ React__default.createElement(
|
|
1183
1285
|
FormControlLabel,
|
|
1184
1286
|
{
|
|
1185
1287
|
control: /* @__PURE__ */ React__default.createElement(
|
|
@@ -1194,14 +1296,24 @@ const KubernetesDrawerContent = ({
|
|
|
1194
1296
|
),
|
|
1195
1297
|
label: "YAML"
|
|
1196
1298
|
}
|
|
1197
|
-
)), /* @__PURE__ */ React__default.createElement("div", { className: classes.
|
|
1299
|
+
)))), errorMessage && /* @__PURE__ */ React__default.createElement("div", { className: classes.errorMessage }, /* @__PURE__ */ React__default.createElement(LinkErrorPanel, { cluster, errorMessage })), /* @__PURE__ */ React__default.createElement("div", { className: classes.options }, /* @__PURE__ */ React__default.createElement("div", null, clusterLink && /* @__PURE__ */ React__default.createElement(
|
|
1300
|
+
LinkButton,
|
|
1301
|
+
{
|
|
1302
|
+
variant: "outlined",
|
|
1303
|
+
color: "primary",
|
|
1304
|
+
size: "small",
|
|
1305
|
+
to: clusterLink,
|
|
1306
|
+
endIcon: /* @__PURE__ */ React__default.createElement(OpenInNewIcon, null)
|
|
1307
|
+
},
|
|
1308
|
+
"Open Kubernetes Dashboard"
|
|
1309
|
+
))), /* @__PURE__ */ React__default.createElement("div", { className: classes.content }, isYaml && /* @__PURE__ */ React__default.createElement(ManifestYaml, { object }), !isYaml && /* @__PURE__ */ React__default.createElement(
|
|
1198
1310
|
StructuredMetadataTable,
|
|
1199
1311
|
{
|
|
1200
1312
|
metadata: renderObject(replaceNullsWithUndefined(object))
|
|
1201
1313
|
}
|
|
1202
1314
|
)));
|
|
1203
1315
|
};
|
|
1204
|
-
const
|
|
1316
|
+
const KubernetesStructuredMetadataTableDrawer = ({
|
|
1205
1317
|
object,
|
|
1206
1318
|
renderObject,
|
|
1207
1319
|
kind,
|
|
@@ -1211,7 +1323,7 @@ const KubernetesDrawer = ({
|
|
|
1211
1323
|
}) => {
|
|
1212
1324
|
var _a, _b;
|
|
1213
1325
|
const [isOpen, setIsOpen] = useState(expanded);
|
|
1214
|
-
const classes = useDrawerStyles();
|
|
1326
|
+
const classes = useDrawerStyles$1();
|
|
1215
1327
|
const toggleDrawer = (e, newValue) => {
|
|
1216
1328
|
e.stopPropagation();
|
|
1217
1329
|
setIsOpen(newValue);
|
|
@@ -1235,7 +1347,7 @@ const KubernetesDrawer = ({
|
|
|
1235
1347
|
onClick: (event) => event.stopPropagation()
|
|
1236
1348
|
},
|
|
1237
1349
|
/* @__PURE__ */ React__default.createElement(
|
|
1238
|
-
|
|
1350
|
+
KubernetesStructuredMetadataTableDrawerContent,
|
|
1239
1351
|
{
|
|
1240
1352
|
kind,
|
|
1241
1353
|
toggleDrawer,
|
|
@@ -1246,61 +1358,306 @@ const KubernetesDrawer = ({
|
|
|
1246
1358
|
));
|
|
1247
1359
|
};
|
|
1248
1360
|
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1361
|
+
const useDrawerContentStyles$1 = makeStyles(
|
|
1362
|
+
(_theme) => createStyles({
|
|
1363
|
+
header: {
|
|
1364
|
+
display: "flex",
|
|
1365
|
+
flexDirection: "row",
|
|
1366
|
+
justifyContent: "space-between"
|
|
1367
|
+
},
|
|
1368
|
+
content: {
|
|
1369
|
+
height: "80%"
|
|
1370
|
+
},
|
|
1371
|
+
icon: {
|
|
1372
|
+
fontSize: 20
|
|
1373
|
+
}
|
|
1374
|
+
})
|
|
1375
|
+
);
|
|
1376
|
+
const KubernetesDrawerContent = ({
|
|
1377
|
+
children,
|
|
1378
|
+
header,
|
|
1379
|
+
kubernetesObject,
|
|
1380
|
+
close
|
|
1381
|
+
}) => {
|
|
1382
|
+
var _a;
|
|
1383
|
+
const classes = useDrawerContentStyles$1();
|
|
1384
|
+
const [isYaml, setIsYaml] = useState(false);
|
|
1385
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: classes.header }, /* @__PURE__ */ React__default.createElement(Grid, { container: true, justifyContent: "flex-start", alignItems: "flex-start" }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 11 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, (_a = kubernetesObject.metadata) == null ? void 0 : _a.name)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 1 }, /* @__PURE__ */ React__default.createElement(
|
|
1386
|
+
IconButton,
|
|
1387
|
+
{
|
|
1388
|
+
key: "dismiss",
|
|
1389
|
+
title: "Close the drawer",
|
|
1390
|
+
onClick: () => close(),
|
|
1391
|
+
color: "inherit"
|
|
1392
|
+
},
|
|
1393
|
+
/* @__PURE__ */ React__default.createElement(CloseIcon, { className: classes.icon })
|
|
1394
|
+
)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, header), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
|
|
1395
|
+
FormControlLabel,
|
|
1396
|
+
{
|
|
1397
|
+
control: /* @__PURE__ */ React__default.createElement(
|
|
1398
|
+
Switch,
|
|
1399
|
+
{
|
|
1400
|
+
checked: isYaml,
|
|
1401
|
+
onChange: (event) => {
|
|
1402
|
+
setIsYaml(event.target.checked);
|
|
1403
|
+
},
|
|
1404
|
+
name: "YAML"
|
|
1405
|
+
}
|
|
1406
|
+
),
|
|
1407
|
+
label: "YAML"
|
|
1408
|
+
}
|
|
1409
|
+
)))), /* @__PURE__ */ React__default.createElement("div", { className: classes.content }, isYaml && /* @__PURE__ */ React__default.createElement(ManifestYaml, { object: kubernetesObject }), !isYaml && children));
|
|
1410
|
+
};
|
|
1411
|
+
const useDrawerStyles = makeStyles(
|
|
1412
|
+
(theme) => createStyles({
|
|
1413
|
+
paper: {
|
|
1414
|
+
width: "50%",
|
|
1415
|
+
justifyContent: "space-between",
|
|
1416
|
+
padding: theme.spacing(2.5)
|
|
1417
|
+
}
|
|
1418
|
+
})
|
|
1419
|
+
);
|
|
1420
|
+
const DrawerButton = withStyles$1({
|
|
1421
|
+
root: {
|
|
1422
|
+
padding: "6px 5px"
|
|
1423
|
+
},
|
|
1424
|
+
label: {
|
|
1425
|
+
textTransform: "none"
|
|
1426
|
+
}
|
|
1427
|
+
})(Button);
|
|
1428
|
+
const KubernetesDrawer = ({
|
|
1429
|
+
open,
|
|
1430
|
+
label,
|
|
1431
|
+
drawerContentsHeader,
|
|
1432
|
+
kubernetesObject,
|
|
1433
|
+
children
|
|
1434
|
+
}) => {
|
|
1435
|
+
const classes = useDrawerStyles();
|
|
1436
|
+
const [isOpen, setIsOpen] = useState(open != null ? open : false);
|
|
1437
|
+
const toggleDrawer = (e, newValue) => {
|
|
1438
|
+
e.stopPropagation();
|
|
1439
|
+
setIsOpen(newValue);
|
|
1440
|
+
};
|
|
1441
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(DrawerButton, { onClick: () => setIsOpen(true) }, label), /* @__PURE__ */ React__default.createElement(
|
|
1442
|
+
Drawer,
|
|
1443
|
+
{
|
|
1444
|
+
classes: {
|
|
1445
|
+
paper: classes.paper
|
|
1446
|
+
},
|
|
1447
|
+
anchor: "right",
|
|
1448
|
+
open: isOpen,
|
|
1449
|
+
onClose: (e) => toggleDrawer(e, false),
|
|
1450
|
+
onClick: (event) => event.stopPropagation()
|
|
1451
|
+
},
|
|
1452
|
+
isOpen && /* @__PURE__ */ React__default.createElement(
|
|
1453
|
+
KubernetesDrawerContent,
|
|
1454
|
+
{
|
|
1455
|
+
header: drawerContentsHeader,
|
|
1456
|
+
kubernetesObject,
|
|
1457
|
+
children,
|
|
1458
|
+
close: () => setIsOpen(false)
|
|
1459
|
+
}
|
|
1460
|
+
)
|
|
1461
|
+
));
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1464
|
+
const PodCondition = ({ condition }) => {
|
|
1465
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, condition.status === "False" && /* @__PURE__ */ React__default.createElement(StatusError, null, condition.type, " - (", condition.reason, " ", condition.lastTransitionTime && DateTime.fromISO(condition.lastTransitionTime).toRelative({
|
|
1466
|
+
locale: "en"
|
|
1467
|
+
}), ") - ", condition.message, " "), condition.status === "True" && /* @__PURE__ */ React__default.createElement(StatusOK, null, condition.type, " - (", condition.lastTransitionTime && DateTime.fromISO(condition.lastTransitionTime).toRelative({
|
|
1468
|
+
locale: "en"
|
|
1469
|
+
}), ")"), condition.status === "Unknown" && /* @__PURE__ */ React__default.createElement(StatusWarning, null, condition.type, " - (", condition.lastTransitionTime && DateTime.fromISO(condition.lastTransitionTime).toRelative({
|
|
1470
|
+
locale: "en"
|
|
1471
|
+
}), ") ", condition.message));
|
|
1472
|
+
};
|
|
1473
|
+
const PendingPodContent = ({ pod }) => {
|
|
1474
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1475
|
+
const startupConditions = [
|
|
1476
|
+
(_b = (_a = pod.status) == null ? void 0 : _a.conditions) == null ? void 0 : _b.find((c) => c.type === "PodScheduled"),
|
|
1477
|
+
(_d = (_c = pod.status) == null ? void 0 : _c.conditions) == null ? void 0 : _d.find((c) => c.type === "Initialized"),
|
|
1478
|
+
(_f = (_e = pod.status) == null ? void 0 : _e.conditions) == null ? void 0 : _f.find((c) => c.type === "ContainersReady"),
|
|
1479
|
+
(_h = (_g = pod.status) == null ? void 0 : _g.conditions) == null ? void 0 : _h.find((c) => c.type === "Ready")
|
|
1480
|
+
].filter((c) => !!c);
|
|
1481
|
+
return /* @__PURE__ */ React__default.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, "Pod is Pending. Conditions:"), /* @__PURE__ */ React__default.createElement(List, null, startupConditions.map((c) => /* @__PURE__ */ React__default.createElement(ListItem, { key: c.type }, /* @__PURE__ */ React__default.createElement(PodCondition, { condition: c }))))));
|
|
1482
|
+
};
|
|
1483
|
+
|
|
1484
|
+
const useDrawerContentStyles = makeStyles(
|
|
1485
|
+
(_theme) => createStyles({
|
|
1486
|
+
header: {
|
|
1487
|
+
display: "flex",
|
|
1488
|
+
flexDirection: "row",
|
|
1489
|
+
justifyContent: "space-between"
|
|
1490
|
+
},
|
|
1491
|
+
content: {
|
|
1492
|
+
height: "80%"
|
|
1493
|
+
},
|
|
1494
|
+
icon: {
|
|
1495
|
+
fontSize: 20
|
|
1496
|
+
},
|
|
1497
|
+
podoklist: {
|
|
1498
|
+
width: "100%",
|
|
1499
|
+
maxWidth: 360,
|
|
1500
|
+
maxHeight: 360
|
|
1501
|
+
}
|
|
1502
|
+
})
|
|
1503
|
+
);
|
|
1504
|
+
function getContainerSpecByName(pod, containerName) {
|
|
1505
|
+
var _a;
|
|
1506
|
+
return (_a = pod.spec) == null ? void 0 : _a.containers.find((c) => c.name === containerName);
|
|
1507
|
+
}
|
|
1508
|
+
const PodDrawer = ({ podAndErrors, open }) => {
|
|
1509
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1510
|
+
const classes = useDrawerContentStyles();
|
|
1251
1511
|
return /* @__PURE__ */ React__default.createElement(
|
|
1252
1512
|
KubernetesDrawer,
|
|
1253
1513
|
{
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1514
|
+
open,
|
|
1515
|
+
drawerContentsHeader: /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, "Pod", " ", ((_a = podAndErrors.pod.status) == null ? void 0 : _a.podIP) && `(${(_b = podAndErrors.pod.status) == null ? void 0 : _b.podIP})`),
|
|
1516
|
+
kubernetesObject: podAndErrors.pod,
|
|
1517
|
+
label: /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, (_d = (_c = podAndErrors.pod.metadata) == null ? void 0 : _c.name) != null ? _d : "unknown")
|
|
1518
|
+
},
|
|
1519
|
+
/* @__PURE__ */ React__default.createElement("div", { className: classes.content }, ((_e = podAndErrors.pod.status) == null ? void 0 : _e.phase) === "Pending" && /* @__PURE__ */ React__default.createElement(PendingPodContent, { pod: podAndErrors.pod }), ((_g = (_f = podAndErrors.pod.status) == null ? void 0 : _f.containerStatuses) == null ? void 0 : _g.length) && /* @__PURE__ */ React__default.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, "Containers")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(ItemCardGrid, null, (_i = (_h = podAndErrors.pod.status) == null ? void 0 : _h.containerStatuses) == null ? void 0 : _i.map(
|
|
1520
|
+
(containerStatus, i) => {
|
|
1521
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
1522
|
+
const containerSpec = getContainerSpecByName(
|
|
1523
|
+
podAndErrors.pod,
|
|
1524
|
+
containerStatus.name
|
|
1525
|
+
);
|
|
1526
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
1527
|
+
ContainerCard,
|
|
1528
|
+
{
|
|
1529
|
+
key: `container-card-${(_a2 = podAndErrors.pod.metadata) == null ? void 0 : _a2.name}-${i}`,
|
|
1530
|
+
podScope: {
|
|
1531
|
+
podName: (_c2 = (_b2 = podAndErrors.pod.metadata) == null ? void 0 : _b2.name) != null ? _c2 : "unknown",
|
|
1532
|
+
podNamespace: (_e2 = (_d2 = podAndErrors.pod.metadata) == null ? void 0 : _d2.namespace) != null ? _e2 : "unknown",
|
|
1533
|
+
clusterName: podAndErrors.clusterName
|
|
1534
|
+
},
|
|
1535
|
+
containerSpec,
|
|
1536
|
+
containerStatus
|
|
1537
|
+
}
|
|
1538
|
+
);
|
|
1278
1539
|
}
|
|
1540
|
+
)))))
|
|
1541
|
+
);
|
|
1542
|
+
};
|
|
1543
|
+
|
|
1544
|
+
const containersReady = (pod) => {
|
|
1545
|
+
var _a, _b;
|
|
1546
|
+
const containerStatuses2 = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
|
|
1547
|
+
const containersReadyItem = containerStatuses2.filter((cs) => cs.ready).length;
|
|
1548
|
+
return `${containersReadyItem}/${containerStatuses2.length}`;
|
|
1549
|
+
};
|
|
1550
|
+
const totalRestarts = (pod) => {
|
|
1551
|
+
var _a, _b;
|
|
1552
|
+
const containerStatuses2 = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
|
|
1553
|
+
return containerStatuses2 == null ? void 0 : containerStatuses2.reduce((a, b) => a + b.restartCount, 0);
|
|
1554
|
+
};
|
|
1555
|
+
const containerStatuses = (pod) => {
|
|
1556
|
+
var _a, _b;
|
|
1557
|
+
const containerStatusesItem = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
|
|
1558
|
+
const errors = containerStatusesItem.reduce((accum, next) => {
|
|
1559
|
+
if (next.state === void 0) {
|
|
1560
|
+
return accum;
|
|
1561
|
+
}
|
|
1562
|
+
const waiting = next.state.waiting;
|
|
1563
|
+
const terminated = next.state.terminated;
|
|
1564
|
+
const renderCell = (reason) => {
|
|
1565
|
+
var _a2;
|
|
1566
|
+
return /* @__PURE__ */ React__default.createElement(Fragment, { key: `${(_a2 = pod.metadata) == null ? void 0 : _a2.name}-${next.name}` }, /* @__PURE__ */ React__default.createElement(
|
|
1567
|
+
SubvalueCell,
|
|
1568
|
+
{
|
|
1569
|
+
value: reason === "Completed" ? /* @__PURE__ */ React__default.createElement(StatusOK, null, "Container: ", next.name) : /* @__PURE__ */ React__default.createElement(StatusError, null, "Container: ", next.name),
|
|
1570
|
+
subvalue: reason
|
|
1571
|
+
}
|
|
1572
|
+
), /* @__PURE__ */ React__default.createElement("br", null));
|
|
1573
|
+
};
|
|
1574
|
+
if (waiting) {
|
|
1575
|
+
accum.push(renderCell(waiting.reason));
|
|
1576
|
+
}
|
|
1577
|
+
if (terminated) {
|
|
1578
|
+
accum.push(renderCell(terminated.reason));
|
|
1579
|
+
}
|
|
1580
|
+
return accum;
|
|
1581
|
+
}, []);
|
|
1582
|
+
if (errors.length === 0) {
|
|
1583
|
+
return /* @__PURE__ */ React__default.createElement(StatusOK, null, "OK");
|
|
1584
|
+
}
|
|
1585
|
+
return errors;
|
|
1586
|
+
};
|
|
1587
|
+
const renderCondition = (condition) => {
|
|
1588
|
+
var _a;
|
|
1589
|
+
const status = condition.status;
|
|
1590
|
+
if (status === "True") {
|
|
1591
|
+
return [condition.type, /* @__PURE__ */ React__default.createElement(StatusOK, null, "True")];
|
|
1592
|
+
} else if (status === "False") {
|
|
1593
|
+
return [
|
|
1594
|
+
condition.type,
|
|
1595
|
+
/* @__PURE__ */ React__default.createElement(
|
|
1596
|
+
SubvalueCell,
|
|
1597
|
+
{
|
|
1598
|
+
value: /* @__PURE__ */ React__default.createElement(StatusError, null, "False"),
|
|
1599
|
+
subvalue: (_a = condition.message) != null ? _a : ""
|
|
1600
|
+
}
|
|
1601
|
+
)
|
|
1602
|
+
];
|
|
1603
|
+
}
|
|
1604
|
+
return [condition.type, /* @__PURE__ */ React__default.createElement(StatusAborted, null)];
|
|
1605
|
+
};
|
|
1606
|
+
const currentToDeclaredResourceToPerc = (current, resource) => {
|
|
1607
|
+
if (Number(resource) === 0)
|
|
1608
|
+
return `0%`;
|
|
1609
|
+
if (typeof current === "number" && typeof resource === "number") {
|
|
1610
|
+
return `${Math.round(current / resource * 100)}%`;
|
|
1611
|
+
}
|
|
1612
|
+
const numerator = BigInt(current);
|
|
1613
|
+
const denominator = BigInt(resource);
|
|
1614
|
+
return `${numerator * BigInt(100) / denominator}%`;
|
|
1615
|
+
};
|
|
1616
|
+
const formatMilicores = (value) => {
|
|
1617
|
+
return `${parseFloat(value.toString()) * 1e3}m`;
|
|
1618
|
+
};
|
|
1619
|
+
const podStatusToCpuUtil = (podStatus) => {
|
|
1620
|
+
const cpuUtil = podStatus.cpu;
|
|
1621
|
+
let currentUsage = cpuUtil.currentUsage;
|
|
1622
|
+
if (typeof cpuUtil.currentUsage === "number") {
|
|
1623
|
+
currentUsage = cpuUtil.currentUsage / 10;
|
|
1624
|
+
}
|
|
1625
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
1626
|
+
SubvalueCell,
|
|
1627
|
+
{
|
|
1628
|
+
value: `requests: ${currentToDeclaredResourceToPerc(
|
|
1629
|
+
currentUsage,
|
|
1630
|
+
cpuUtil.requestTotal
|
|
1631
|
+
)} of ${formatMilicores(cpuUtil.requestTotal)}`,
|
|
1632
|
+
subvalue: `limits: ${currentToDeclaredResourceToPerc(
|
|
1633
|
+
currentUsage,
|
|
1634
|
+
cpuUtil.limitTotal
|
|
1635
|
+
)} of ${formatMilicores(cpuUtil.limitTotal)}`
|
|
1636
|
+
}
|
|
1637
|
+
);
|
|
1638
|
+
};
|
|
1639
|
+
const bytesToMiB = (value) => {
|
|
1640
|
+
return `${parseFloat(value.toString()) / 1024 / 1024}MiB`;
|
|
1641
|
+
};
|
|
1642
|
+
const podStatusToMemoryUtil = (podStatus) => {
|
|
1643
|
+
const memUtil = podStatus.memory;
|
|
1644
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
1645
|
+
SubvalueCell,
|
|
1646
|
+
{
|
|
1647
|
+
value: `requests: ${currentToDeclaredResourceToPerc(
|
|
1648
|
+
memUtil.currentUsage,
|
|
1649
|
+
memUtil.requestTotal
|
|
1650
|
+
)} of ${bytesToMiB(memUtil.requestTotal)}`,
|
|
1651
|
+
subvalue: `limits: ${currentToDeclaredResourceToPerc(
|
|
1652
|
+
memUtil.currentUsage,
|
|
1653
|
+
memUtil.limitTotal
|
|
1654
|
+
)} of ${bytesToMiB(memUtil.limitTotal)}`
|
|
1279
1655
|
}
|
|
1280
1656
|
);
|
|
1281
1657
|
};
|
|
1282
1658
|
|
|
1283
1659
|
const READY_COLUMNS = "READY";
|
|
1284
1660
|
const RESOURCE_COLUMNS = "RESOURCE";
|
|
1285
|
-
const DEFAULT_COLUMNS = [
|
|
1286
|
-
{
|
|
1287
|
-
title: "name",
|
|
1288
|
-
highlight: true,
|
|
1289
|
-
render: (pod) => /* @__PURE__ */ React__default.createElement(PodDrawer, { pod })
|
|
1290
|
-
},
|
|
1291
|
-
{
|
|
1292
|
-
title: "phase",
|
|
1293
|
-
render: (pod) => {
|
|
1294
|
-
var _a, _b;
|
|
1295
|
-
return (_b = (_a = pod.status) == null ? void 0 : _a.phase) != null ? _b : "unknown";
|
|
1296
|
-
},
|
|
1297
|
-
width: "auto"
|
|
1298
|
-
},
|
|
1299
|
-
{
|
|
1300
|
-
title: "status",
|
|
1301
|
-
render: containerStatuses
|
|
1302
|
-
}
|
|
1303
|
-
];
|
|
1304
1661
|
const READY = [
|
|
1305
1662
|
{
|
|
1306
1663
|
title: "containers ready",
|
|
@@ -1318,7 +1675,36 @@ const READY = [
|
|
|
1318
1675
|
];
|
|
1319
1676
|
const PodsTable = ({ pods, extraColumns = [] }) => {
|
|
1320
1677
|
const podNamesWithMetrics = useContext(PodNamesWithMetricsContext);
|
|
1321
|
-
const
|
|
1678
|
+
const cluster = useContext(ClusterContext);
|
|
1679
|
+
const defaultColumns = [
|
|
1680
|
+
{
|
|
1681
|
+
title: "name",
|
|
1682
|
+
highlight: true,
|
|
1683
|
+
render: (pod) => /* @__PURE__ */ React__default.createElement(
|
|
1684
|
+
PodDrawer,
|
|
1685
|
+
{
|
|
1686
|
+
podAndErrors: {
|
|
1687
|
+
pod,
|
|
1688
|
+
clusterName: cluster.name,
|
|
1689
|
+
errors: []
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
)
|
|
1693
|
+
},
|
|
1694
|
+
{
|
|
1695
|
+
title: "phase",
|
|
1696
|
+
render: (pod) => {
|
|
1697
|
+
var _a, _b;
|
|
1698
|
+
return (_b = (_a = pod.status) == null ? void 0 : _a.phase) != null ? _b : "unknown";
|
|
1699
|
+
},
|
|
1700
|
+
width: "auto"
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
title: "status",
|
|
1704
|
+
render: containerStatuses
|
|
1705
|
+
}
|
|
1706
|
+
];
|
|
1707
|
+
const columns = [...defaultColumns];
|
|
1322
1708
|
if (extraColumns.includes(READY_COLUMNS)) {
|
|
1323
1709
|
columns.push(...READY);
|
|
1324
1710
|
}
|
|
@@ -1376,7 +1762,7 @@ const DeploymentDrawer = ({
|
|
|
1376
1762
|
var _a, _b, _c;
|
|
1377
1763
|
const namespace = (_a = deployment.metadata) == null ? void 0 : _a.namespace;
|
|
1378
1764
|
return /* @__PURE__ */ React__default.createElement(
|
|
1379
|
-
|
|
1765
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1380
1766
|
{
|
|
1381
1767
|
object: deployment,
|
|
1382
1768
|
expanded,
|
|
@@ -1414,7 +1800,7 @@ const DeploymentDrawer = ({
|
|
|
1414
1800
|
const HorizontalPodAutoscalerDrawer = (props) => {
|
|
1415
1801
|
const { hpa, expanded, children } = props;
|
|
1416
1802
|
return /* @__PURE__ */ React__default.createElement(
|
|
1417
|
-
|
|
1803
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1418
1804
|
{
|
|
1419
1805
|
kind: "HorizontalPodAutoscaler",
|
|
1420
1806
|
object: hpa,
|
|
@@ -1580,7 +1966,7 @@ const StatefulSetDrawer = ({
|
|
|
1580
1966
|
var _a, _b, _c;
|
|
1581
1967
|
const namespace = (_a = statefulset.metadata) == null ? void 0 : _a.namespace;
|
|
1582
1968
|
return /* @__PURE__ */ React__default.createElement(
|
|
1583
|
-
|
|
1969
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1584
1970
|
{
|
|
1585
1971
|
object: statefulset,
|
|
1586
1972
|
expanded,
|
|
@@ -1729,7 +2115,7 @@ const IngressDrawer = ({
|
|
|
1729
2115
|
}) => {
|
|
1730
2116
|
var _a, _b;
|
|
1731
2117
|
return /* @__PURE__ */ React__default.createElement(
|
|
1732
|
-
|
|
2118
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1733
2119
|
{
|
|
1734
2120
|
object: ingress,
|
|
1735
2121
|
expanded,
|
|
@@ -1798,7 +2184,7 @@ const ServiceDrawer = ({
|
|
|
1798
2184
|
}) => {
|
|
1799
2185
|
var _a, _b;
|
|
1800
2186
|
return /* @__PURE__ */ React__default.createElement(
|
|
1801
|
-
|
|
2187
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1802
2188
|
{
|
|
1803
2189
|
object: service,
|
|
1804
2190
|
expanded,
|
|
@@ -1883,7 +2269,7 @@ const JobDrawer = ({
|
|
|
1883
2269
|
}) => {
|
|
1884
2270
|
var _a, _b;
|
|
1885
2271
|
return /* @__PURE__ */ React__default.createElement(
|
|
1886
|
-
|
|
2272
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1887
2273
|
{
|
|
1888
2274
|
object: job,
|
|
1889
2275
|
expanded,
|
|
@@ -1972,7 +2358,7 @@ const CronJobDrawer = ({
|
|
|
1972
2358
|
var _a, _b, _c;
|
|
1973
2359
|
const namespace = (_a = cronJob.metadata) == null ? void 0 : _a.namespace;
|
|
1974
2360
|
return /* @__PURE__ */ React__default.createElement(
|
|
1975
|
-
|
|
2361
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
1976
2362
|
{
|
|
1977
2363
|
object: cronJob,
|
|
1978
2364
|
expanded,
|
|
@@ -2080,7 +2466,7 @@ const RolloutDrawer = ({
|
|
|
2080
2466
|
}) => {
|
|
2081
2467
|
var _a, _b;
|
|
2082
2468
|
return /* @__PURE__ */ React__default.createElement(
|
|
2083
|
-
|
|
2469
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
2084
2470
|
{
|
|
2085
2471
|
object: rollout,
|
|
2086
2472
|
expanded,
|
|
@@ -2304,7 +2690,7 @@ const DefaultCustomResourceDrawer = ({
|
|
|
2304
2690
|
var _a, _b;
|
|
2305
2691
|
const capitalizedName = capitalize(customResourceName);
|
|
2306
2692
|
return /* @__PURE__ */ React__default.createElement(
|
|
2307
|
-
|
|
2693
|
+
KubernetesStructuredMetadataTableDrawer,
|
|
2308
2694
|
{
|
|
2309
2695
|
object: customResource,
|
|
2310
2696
|
expanded,
|
|
@@ -2494,13 +2880,13 @@ const KubernetesContent = ({
|
|
|
2494
2880
|
const clustersWithErrors = (_a = kubernetesObjects == null ? void 0 : kubernetesObjects.items.filter((r) => r.errors.length > 0)) != null ? _a : [];
|
|
2495
2881
|
const detectedErrors = kubernetesObjects !== void 0 ? detectErrors(kubernetesObjects) : /* @__PURE__ */ new Map();
|
|
2496
2882
|
return /* @__PURE__ */ React__default.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React__default.createElement(Content, null, kubernetesObjects === void 0 && error === void 0 && /* @__PURE__ */ React__default.createElement(Progress, null), clustersWithErrors.length > 0 && /* @__PURE__ */ React__default.createElement(Grid, { container: true, spacing: 3, direction: "column" }, /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(
|
|
2497
|
-
ErrorPanel
|
|
2883
|
+
ErrorPanel,
|
|
2498
2884
|
{
|
|
2499
2885
|
entityName: entity.metadata.name,
|
|
2500
2886
|
clustersWithErrors
|
|
2501
2887
|
}
|
|
2502
2888
|
))), error !== void 0 && /* @__PURE__ */ React__default.createElement(Grid, { container: true, spacing: 3, direction: "column" }, /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(
|
|
2503
|
-
ErrorPanel
|
|
2889
|
+
ErrorPanel,
|
|
2504
2890
|
{
|
|
2505
2891
|
entityName: entity.metadata.name,
|
|
2506
2892
|
errorMessage: error
|
|
@@ -2583,5 +2969,5 @@ var Router$1 = /*#__PURE__*/Object.freeze({
|
|
|
2583
2969
|
Router: Router
|
|
2584
2970
|
});
|
|
2585
2971
|
|
|
2586
|
-
export { Cluster, ClusterContext, CronJobsAccordions, CustomResources, EntityKubernetesContent, ErrorPanel
|
|
2972
|
+
export { Cluster, ClusterContext, CronJobsAccordions, CustomResources, EntityKubernetesContent, ErrorPanel, ErrorReporting, GoogleKubernetesAuthProvider, GroupedResponsesContext, HorizontalPodAutoscalerDrawer, IngressesAccordions, JobsAccordions, KubernetesAuthProviders, KubernetesBackendClient, KubernetesContent, KubernetesDrawer, KubernetesDrawerContent, KubernetesProxyClient, KubernetesStructuredMetadataTableDrawer, LinkErrorPanel, PodDrawer, PodNamesWithErrorsContext, PodNamesWithMetricsContext, PodsTable, Router, ServerSideKubernetesAuthProvider, ServicesAccordions, clusterLinksFormatters, detectErrors, formatClusterLink, isKubernetesAvailable, kubernetesApiRef, kubernetesAuthProvidersApiRef, kubernetesPlugin, kubernetesProxyApiRef, kubernetesPlugin as plugin, useCustomResources, useKubernetesObjects };
|
|
2587
2973
|
//# sourceMappingURL=index.esm.js.map
|