@backstage/plugin-kubernetes-react 0.3.4 → 0.3.5-next.0

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.
Files changed (154) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/api/KubernetesBackendClient.esm.js +137 -0
  3. package/dist/api/KubernetesBackendClient.esm.js.map +1 -0
  4. package/dist/api/KubernetesClusterLinkFormatter.esm.js +38 -0
  5. package/dist/api/KubernetesClusterLinkFormatter.esm.js.map +1 -0
  6. package/dist/api/KubernetesProxyClient.esm.js +76 -0
  7. package/dist/api/KubernetesProxyClient.esm.js.map +1 -0
  8. package/dist/api/formatters/AksClusterLinksFormatter.esm.js +35 -0
  9. package/dist/api/formatters/AksClusterLinksFormatter.esm.js.map +1 -0
  10. package/dist/api/formatters/EksClusterLinksFormatter.esm.js +10 -0
  11. package/dist/api/formatters/EksClusterLinksFormatter.esm.js.map +1 -0
  12. package/dist/api/formatters/GkeClusterLinksFormatter.esm.js +62 -0
  13. package/dist/api/formatters/GkeClusterLinksFormatter.esm.js.map +1 -0
  14. package/dist/api/formatters/OpenshiftClusterLinksFormatter.esm.js +41 -0
  15. package/dist/api/formatters/OpenshiftClusterLinksFormatter.esm.js.map +1 -0
  16. package/dist/api/formatters/RancherClusterLinksFormatter.esm.js +33 -0
  17. package/dist/api/formatters/RancherClusterLinksFormatter.esm.js.map +1 -0
  18. package/dist/api/formatters/StandardClusterLinksFormatter.esm.js +37 -0
  19. package/dist/api/formatters/StandardClusterLinksFormatter.esm.js.map +1 -0
  20. package/dist/api/formatters/index.esm.js +21 -0
  21. package/dist/api/formatters/index.esm.js.map +1 -0
  22. package/dist/api/types.esm.js +14 -0
  23. package/dist/api/types.esm.js.map +1 -0
  24. package/dist/components/Cluster/Cluster.esm.js +88 -0
  25. package/dist/components/Cluster/Cluster.esm.js.map +1 -0
  26. package/dist/components/CronJobsAccordions/CronJobsAccordions.esm.js +80 -0
  27. package/dist/components/CronJobsAccordions/CronJobsAccordions.esm.js.map +1 -0
  28. package/dist/components/CronJobsAccordions/CronJobsDrawer.esm.js +51 -0
  29. package/dist/components/CronJobsAccordions/CronJobsDrawer.esm.js.map +1 -0
  30. package/dist/components/CustomResources/ArgoRollouts/Rollout.esm.js +222 -0
  31. package/dist/components/CustomResources/ArgoRollouts/Rollout.esm.js.map +1 -0
  32. package/dist/components/CustomResources/ArgoRollouts/RolloutDrawer.esm.js +40 -0
  33. package/dist/components/CustomResources/ArgoRollouts/RolloutDrawer.esm.js.map +1 -0
  34. package/dist/components/CustomResources/ArgoRollouts/StepsProgress.esm.js +32 -0
  35. package/dist/components/CustomResources/ArgoRollouts/StepsProgress.esm.js.map +1 -0
  36. package/dist/components/CustomResources/CustomResources.esm.js +44 -0
  37. package/dist/components/CustomResources/CustomResources.esm.js.map +1 -0
  38. package/dist/components/CustomResources/DefaultCustomResource.esm.js +79 -0
  39. package/dist/components/CustomResources/DefaultCustomResource.esm.js.map +1 -0
  40. package/dist/components/CustomResources/DefaultCustomResourceDrawer.esm.js +43 -0
  41. package/dist/components/CustomResources/DefaultCustomResourceDrawer.esm.js.map +1 -0
  42. package/dist/components/DaemonSetsAccordions/DaemonSetsAccordions.esm.js +126 -0
  43. package/dist/components/DaemonSetsAccordions/DaemonSetsAccordions.esm.js.map +1 -0
  44. package/dist/components/DaemonSetsAccordions/DaemonSetsDrawer.esm.js +55 -0
  45. package/dist/components/DaemonSetsAccordions/DaemonSetsDrawer.esm.js.map +1 -0
  46. package/dist/components/DeploymentsAccordions/DeploymentDrawer.esm.js +56 -0
  47. package/dist/components/DeploymentsAccordions/DeploymentDrawer.esm.js.map +1 -0
  48. package/dist/components/DeploymentsAccordions/DeploymentsAccordions.esm.js +160 -0
  49. package/dist/components/DeploymentsAccordions/DeploymentsAccordions.esm.js.map +1 -0
  50. package/dist/components/ErrorPanel/ErrorPanel.esm.js +27 -0
  51. package/dist/components/ErrorPanel/ErrorPanel.esm.js.map +1 -0
  52. package/dist/components/ErrorReporting/ErrorReporting.esm.js +63 -0
  53. package/dist/components/ErrorReporting/ErrorReporting.esm.js.map +1 -0
  54. package/dist/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.esm.js +34 -0
  55. package/dist/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.esm.js.map +1 -0
  56. package/dist/components/IngressesAccordions/IngressDrawer.esm.js +42 -0
  57. package/dist/components/IngressesAccordions/IngressDrawer.esm.js.map +1 -0
  58. package/dist/components/IngressesAccordions/IngressesAccordions.esm.js +62 -0
  59. package/dist/components/IngressesAccordions/IngressesAccordions.esm.js.map +1 -0
  60. package/dist/components/JobsAccordions/JobsAccordions.esm.js +101 -0
  61. package/dist/components/JobsAccordions/JobsAccordions.esm.js.map +1 -0
  62. package/dist/components/JobsAccordions/JobsDrawer.esm.js +48 -0
  63. package/dist/components/JobsAccordions/JobsDrawer.esm.js.map +1 -0
  64. package/dist/components/KubernetesDialog/KubernetesDialog.esm.js +72 -0
  65. package/dist/components/KubernetesDialog/KubernetesDialog.esm.js.map +1 -0
  66. package/dist/components/KubernetesDrawer/KubernetesDrawer.esm.js +117 -0
  67. package/dist/components/KubernetesDrawer/KubernetesDrawer.esm.js.map +1 -0
  68. package/dist/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.esm.js +199 -0
  69. package/dist/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.esm.js.map +1 -0
  70. package/dist/components/KubernetesDrawer/ManifestYaml.esm.js +44 -0
  71. package/dist/components/KubernetesDrawer/ManifestYaml.esm.js.map +1 -0
  72. package/dist/components/PodExecTerminal/PodExecTerminal.esm.js +88 -0
  73. package/dist/components/PodExecTerminal/PodExecTerminal.esm.js.map +1 -0
  74. package/dist/components/PodExecTerminal/PodExecTerminalAttachAddon.esm.js +40 -0
  75. package/dist/components/PodExecTerminal/PodExecTerminalAttachAddon.esm.js.map +1 -0
  76. package/dist/components/PodExecTerminal/PodExecTerminalDialog.esm.js +35 -0
  77. package/dist/components/PodExecTerminal/PodExecTerminalDialog.esm.js.map +1 -0
  78. package/dist/components/Pods/ErrorList/ErrorList.esm.js +52 -0
  79. package/dist/components/Pods/ErrorList/ErrorList.esm.js.map +1 -0
  80. package/dist/components/Pods/Events/Events.esm.js +74 -0
  81. package/dist/components/Pods/Events/Events.esm.js.map +1 -0
  82. package/dist/components/Pods/Events/useEvents.esm.js +21 -0
  83. package/dist/components/Pods/Events/useEvents.esm.js.map +1 -0
  84. package/dist/components/Pods/FixDialog/FixDialog.esm.js +107 -0
  85. package/dist/components/Pods/FixDialog/FixDialog.esm.js.map +1 -0
  86. package/dist/components/Pods/PodDrawer/ContainerCard.esm.js +166 -0
  87. package/dist/components/Pods/PodDrawer/ContainerCard.esm.js.map +1 -0
  88. package/dist/components/Pods/PodDrawer/PendingPodContent.esm.js +30 -0
  89. package/dist/components/Pods/PodDrawer/PendingPodContent.esm.js.map +1 -0
  90. package/dist/components/Pods/PodDrawer/PodDrawer.esm.js +114 -0
  91. package/dist/components/Pods/PodDrawer/PodDrawer.esm.js.map +1 -0
  92. package/dist/components/Pods/PodLogs/PodLogs.esm.js +44 -0
  93. package/dist/components/Pods/PodLogs/PodLogs.esm.js.map +1 -0
  94. package/dist/components/Pods/PodLogs/PodLogsDialog.esm.js +21 -0
  95. package/dist/components/Pods/PodLogs/PodLogsDialog.esm.js.map +1 -0
  96. package/dist/components/Pods/PodLogs/usePodLogs.esm.js +19 -0
  97. package/dist/components/Pods/PodLogs/usePodLogs.esm.js.map +1 -0
  98. package/dist/components/Pods/PodsTable.esm.js +153 -0
  99. package/dist/components/Pods/PodsTable.esm.js.map +1 -0
  100. package/dist/components/ResourceUtilization/ResourceUtilization.esm.js +50 -0
  101. package/dist/components/ResourceUtilization/ResourceUtilization.esm.js.map +1 -0
  102. package/dist/components/ServicesAccordions/ServiceDrawer.esm.js +42 -0
  103. package/dist/components/ServicesAccordions/ServiceDrawer.esm.js.map +1 -0
  104. package/dist/components/ServicesAccordions/ServicesAccordions.esm.js +79 -0
  105. package/dist/components/ServicesAccordions/ServicesAccordions.esm.js.map +1 -0
  106. package/dist/components/StatefulSetsAccordions/StatefulSetDrawer.esm.js +58 -0
  107. package/dist/components/StatefulSetsAccordions/StatefulSetDrawer.esm.js.map +1 -0
  108. package/dist/components/StatefulSetsAccordions/StatefulSetsAccordions.esm.js +156 -0
  109. package/dist/components/StatefulSetsAccordions/StatefulSetsAccordions.esm.js.map +1 -0
  110. package/dist/hooks/Cluster.esm.js +8 -0
  111. package/dist/hooks/Cluster.esm.js.map +1 -0
  112. package/dist/hooks/GroupedResponses.esm.js +19 -0
  113. package/dist/hooks/GroupedResponses.esm.js.map +1 -0
  114. package/dist/hooks/PodNamesWithErrors.esm.js +8 -0
  115. package/dist/hooks/PodNamesWithErrors.esm.js.map +1 -0
  116. package/dist/hooks/PodNamesWithMetrics.esm.js +6 -0
  117. package/dist/hooks/PodNamesWithMetrics.esm.js.map +1 -0
  118. package/dist/hooks/auth.esm.js +24 -0
  119. package/dist/hooks/auth.esm.js.map +1 -0
  120. package/dist/hooks/useCustomResources.esm.js +42 -0
  121. package/dist/hooks/useCustomResources.esm.js.map +1 -0
  122. package/dist/hooks/useIsPodExecTerminalEnabled.esm.js +9 -0
  123. package/dist/hooks/useIsPodExecTerminalEnabled.esm.js.map +1 -0
  124. package/dist/hooks/useIsPodExecTerminalSupported.esm.js +21 -0
  125. package/dist/hooks/useIsPodExecTerminalSupported.esm.js.map +1 -0
  126. package/dist/hooks/useKubernetesObjects.esm.js +36 -0
  127. package/dist/hooks/useKubernetesObjects.esm.js.map +1 -0
  128. package/dist/hooks/useMatchingErrors.esm.js +20 -0
  129. package/dist/hooks/useMatchingErrors.esm.js.map +1 -0
  130. package/dist/hooks/usePodMetrics.esm.js +20 -0
  131. package/dist/hooks/usePodMetrics.esm.js.map +1 -0
  132. package/dist/index.esm.js +53 -3465
  133. package/dist/index.esm.js.map +1 -1
  134. package/dist/kubernetes-auth-provider/AksKubernetesAuthProvider.esm.js +21 -0
  135. package/dist/kubernetes-auth-provider/AksKubernetesAuthProvider.esm.js.map +1 -0
  136. package/dist/kubernetes-auth-provider/GoogleKubernetesAuthProvider.esm.js +31 -0
  137. package/dist/kubernetes-auth-provider/GoogleKubernetesAuthProvider.esm.js.map +1 -0
  138. package/dist/kubernetes-auth-provider/KubernetesAuthProviders.esm.js +89 -0
  139. package/dist/kubernetes-auth-provider/KubernetesAuthProviders.esm.js.map +1 -0
  140. package/dist/kubernetes-auth-provider/OidcKubernetesAuthProvider.esm.js +33 -0
  141. package/dist/kubernetes-auth-provider/OidcKubernetesAuthProvider.esm.js.map +1 -0
  142. package/dist/kubernetes-auth-provider/ServerSideAuthProvider.esm.js +11 -0
  143. package/dist/kubernetes-auth-provider/ServerSideAuthProvider.esm.js.map +1 -0
  144. package/dist/kubernetes-auth-provider/types.esm.js +8 -0
  145. package/dist/kubernetes-auth-provider/types.esm.js.map +1 -0
  146. package/dist/utils/crons.esm.js +22 -0
  147. package/dist/utils/crons.esm.js.map +1 -0
  148. package/dist/utils/owner.esm.js +30 -0
  149. package/dist/utils/owner.esm.js.map +1 -0
  150. package/dist/utils/pod.esm.js +120 -0
  151. package/dist/utils/pod.esm.js.map +1 -0
  152. package/dist/utils/resources.esm.js +19 -0
  153. package/dist/utils/resources.esm.js.map +1 -0
  154. package/package.json +6 -6
package/dist/index.esm.js CHANGED
@@ -1,3466 +1,54 @@
1
- import { useApi, configApiRef, createApiRef, discoveryApiRef } from '@backstage/core-plugin-api';
2
- import useAsync from 'react-use/esm/useAsync';
3
- import * as React from 'react';
4
- import React__default, { useCallback, useContext, useState, useEffect, useMemo, Fragment } from 'react';
5
- import useInterval from 'react-use/esm/useInterval';
6
- import useAsyncRetry from 'react-use/esm/useAsyncRetry';
7
- import { stringifyEntityRef } from '@backstage/catalog-model';
8
- import { NotFoundError } from '@backstage/errors';
9
- import Accordion from '@material-ui/core/Accordion';
10
- import AccordionDetails from '@material-ui/core/AccordionDetails';
11
- import AccordionSummary from '@material-ui/core/AccordionSummary';
12
- import Grid from '@material-ui/core/Grid';
13
- import Typography from '@material-ui/core/Typography';
14
- import { groupResponses } from '@backstage/plugin-kubernetes-common';
15
- import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
16
- import { LinearGauge, DismissableBanner, EmptyState, LogViewer, StructuredMetadataTable, CodeSnippet, WarningPanel, LinkButton, StatusError, StatusOK, StatusWarning, ItemCardGrid, SubvalueCell, StatusAborted, Table, StatusPending } from '@backstage/core-components';
17
- import { makeStyles, createStyles, withStyles } from '@material-ui/core/styles';
18
- import Card from '@material-ui/core/Card';
19
- import CardActions from '@material-ui/core/CardActions';
20
- import CardContent from '@material-ui/core/CardContent';
21
- import CardHeader from '@material-ui/core/CardHeader';
22
- import { DateTime } from 'luxon';
23
- import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
24
- import Button from '@material-ui/core/Button';
25
- import Dialog from '@material-ui/core/Dialog';
26
- import DialogContent from '@material-ui/core/DialogContent';
27
- import DialogTitle from '@material-ui/core/DialogTitle';
28
- import IconButton from '@material-ui/core/IconButton';
29
- import CloseIcon from '@material-ui/icons/Close';
30
- import 'xterm/css/xterm.css';
31
- import { Terminal } from 'xterm';
32
- import { FitAddon } from 'xterm-addon-fit';
33
- import { AttachAddon } from 'xterm-addon-attach';
34
- import Paper from '@material-ui/core/Paper';
35
- import Skeleton from '@material-ui/lab/Skeleton';
36
- import SubjectIcon from '@material-ui/icons/Subject';
37
- import Drawer from '@material-ui/core/Drawer';
38
- import Switch from '@material-ui/core/Switch';
39
- import FormControlLabel from '@material-ui/core/FormControlLabel';
40
- import OpenInNewIcon from '@material-ui/icons/OpenInNew';
41
- import jsyaml from 'js-yaml';
42
- import List from '@material-ui/core/List';
43
- import ListItem from '@material-ui/core/ListItem';
44
- import ListItemText from '@material-ui/core/ListItemText';
45
- import Divider from '@material-ui/core/Divider';
46
- import DialogActions from '@material-ui/core/DialogActions';
47
- import HelpIcon from '@material-ui/icons/Help';
48
- import Avatar from '@material-ui/core/Avatar';
49
- import Container from '@material-ui/core/Container';
50
- import ListItemAvatar from '@material-ui/core/ListItemAvatar';
51
- import Tooltip from '@material-ui/core/Tooltip';
52
- import InfoIcon from '@material-ui/icons/Info';
53
- import WarningIcon from '@material-ui/icons/Warning';
54
- import Chip from '@material-ui/core/Chip';
55
- import cronstrue from 'cronstrue';
56
- import lodash from 'lodash';
57
- import PauseIcon from '@material-ui/icons/Pause';
58
- import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';
59
- import Step from '@material-ui/core/Step';
60
- import StepLabel from '@material-ui/core/StepLabel';
61
- import Stepper from '@material-ui/core/Stepper';
62
-
63
- const useIsPodExecTerminalEnabled = () => {
64
- const configApi = useApi(configApiRef);
65
- return configApi.getOptionalBoolean("kubernetes.podExecTerminal.enabled");
66
- };
67
-
68
- const kubernetesApiRef = createApiRef({
69
- id: "plugin.kubernetes.service"
70
- });
71
- const kubernetesProxyApiRef = createApiRef({
72
- id: "plugin.kubernetes.proxy-service"
73
- });
74
- const kubernetesClusterLinkFormatterApiRef = createApiRef({
75
- id: "plugin.kubernetes.cluster-link-formatter-service"
76
- });
77
-
78
- const useIsPodExecTerminalSupported = () => {
79
- const kubernetesApi = useApi(kubernetesApiRef);
80
- return useAsync(async () => {
81
- const clusters = await kubernetesApi.getClusters();
82
- if (clusters.length !== 1) {
83
- return false;
84
- }
85
- const { authProvider } = clusters[0];
86
- const isClientAuthProvider = ["aks", "google", "oidc"].some(
87
- (authProviderName) => authProvider.includes(authProviderName)
88
- );
89
- return !isClientAuthProvider;
90
- });
91
- };
92
-
93
- const generateAuth = async (entity, kubernetesApi, kubernetesAuthProvidersApi) => {
94
- var _a;
95
- const clusters = await kubernetesApi.getClusters();
96
- const authProviders = [
97
- ...new Set(
98
- clusters.map(
99
- (c) => `${c.authProvider}${c.oidcTokenProvider ? `.${c.oidcTokenProvider}` : ""}`
100
- )
101
- )
102
- ];
103
- let requestBody = {
104
- entity
105
- };
106
- for (const authProviderStr of authProviders) {
107
- requestBody = await kubernetesAuthProvidersApi.decorateRequestBodyForAuth(
108
- authProviderStr,
109
- requestBody
110
- );
111
- }
112
- return (_a = requestBody.auth) != null ? _a : {};
113
- };
114
-
115
- const kubernetesAuthProvidersApiRef = createApiRef({
116
- id: "plugin.kubernetes-auth-providers.service"
117
- });
118
-
119
- var __defProp$5 = Object.defineProperty;
120
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
121
- var __publicField$5 = (obj, key, value) => {
122
- __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
123
- return value;
124
- };
125
- class GoogleKubernetesAuthProvider {
126
- constructor(authProvider) {
127
- __publicField$5(this, "authProvider");
128
- this.authProvider = authProvider;
129
- }
130
- async decorateRequestBodyForAuth(requestBody) {
131
- const googleAuthToken = (await this.getCredentials()).token;
132
- if ("auth" in requestBody) {
133
- requestBody.auth.google = googleAuthToken;
134
- } else {
135
- requestBody.auth = { google: googleAuthToken };
136
- }
137
- return requestBody;
138
- }
139
- async getCredentials() {
140
- return {
141
- token: await this.authProvider.getAccessToken(
142
- "https://www.googleapis.com/auth/cloud-platform.read-only"
143
- )
144
- };
145
- }
146
- }
147
-
148
- class ServerSideKubernetesAuthProvider {
149
- async decorateRequestBodyForAuth(requestBody) {
150
- return requestBody;
151
- }
152
- async getCredentials() {
153
- return {};
154
- }
155
- }
156
-
157
- var __defProp$4 = Object.defineProperty;
158
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
159
- var __publicField$4 = (obj, key, value) => {
160
- __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
161
- return value;
162
- };
163
- class OidcKubernetesAuthProvider {
164
- constructor(providerName, authProvider) {
165
- __publicField$4(this, "providerName");
166
- __publicField$4(this, "authProvider");
167
- this.providerName = providerName;
168
- this.authProvider = authProvider;
169
- }
170
- async decorateRequestBodyForAuth(requestBody) {
171
- const authToken = (await this.getCredentials()).token;
172
- const auth = { ...requestBody.auth };
173
- if (auth.oidc) {
174
- auth.oidc[this.providerName] = authToken;
175
- } else {
176
- auth.oidc = { [this.providerName]: authToken };
177
- }
178
- requestBody.auth = auth;
179
- return requestBody;
180
- }
181
- async getCredentials() {
182
- return {
183
- token: await this.authProvider.getIdToken()
184
- };
185
- }
186
- }
187
-
188
- class AksKubernetesAuthProvider {
189
- constructor(microsoftAuthApi) {
190
- this.microsoftAuthApi = microsoftAuthApi;
191
- }
192
- async decorateRequestBodyForAuth(requestBody) {
193
- return {
194
- ...requestBody,
195
- auth: { ...requestBody.auth, aks: (await this.getCredentials()).token }
196
- };
197
- }
198
- async getCredentials() {
199
- return {
200
- token: await this.microsoftAuthApi.getAccessToken(
201
- "6dae42f8-4368-4678-94ff-3960e28e3630/user.read"
202
- )
203
- };
204
- }
205
- }
206
-
207
- var __defProp$3 = Object.defineProperty;
208
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
209
- var __publicField$3 = (obj, key, value) => {
210
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
211
- return value;
212
- };
213
- class KubernetesAuthProviders {
214
- constructor(options) {
215
- __publicField$3(this, "kubernetesAuthProviderMap");
216
- this.kubernetesAuthProviderMap = /* @__PURE__ */ new Map();
217
- this.kubernetesAuthProviderMap.set(
218
- "google",
219
- new GoogleKubernetesAuthProvider(options.googleAuthApi)
220
- );
221
- this.kubernetesAuthProviderMap.set(
222
- "serviceAccount",
223
- new ServerSideKubernetesAuthProvider()
224
- );
225
- this.kubernetesAuthProviderMap.set(
226
- "googleServiceAccount",
227
- new ServerSideKubernetesAuthProvider()
228
- );
229
- this.kubernetesAuthProviderMap.set(
230
- "aws",
231
- new ServerSideKubernetesAuthProvider()
232
- );
233
- this.kubernetesAuthProviderMap.set(
234
- "azure",
235
- new ServerSideKubernetesAuthProvider()
236
- );
237
- this.kubernetesAuthProviderMap.set(
238
- "localKubectlProxy",
239
- new ServerSideKubernetesAuthProvider()
240
- );
241
- this.kubernetesAuthProviderMap.set(
242
- "aks",
243
- new AksKubernetesAuthProvider(options.microsoftAuthApi)
244
- );
245
- if (options.oidcProviders) {
246
- Object.keys(options.oidcProviders).forEach((provider) => {
247
- this.kubernetesAuthProviderMap.set(
248
- `oidc.${provider}`,
249
- new OidcKubernetesAuthProvider(
250
- provider,
251
- options.oidcProviders[provider]
252
- )
253
- );
254
- });
255
- }
256
- }
257
- async decorateRequestBodyForAuth(authProvider, requestBody) {
258
- const kubernetesAuthProvider = this.kubernetesAuthProviderMap.get(authProvider);
259
- if (kubernetesAuthProvider) {
260
- return await kubernetesAuthProvider.decorateRequestBodyForAuth(
261
- requestBody
262
- );
263
- }
264
- if (authProvider.startsWith("oidc.")) {
265
- throw new Error(
266
- `KubernetesAuthProviders has no oidcProvider configured for ${authProvider}`
267
- );
268
- }
269
- throw new Error(
270
- `authProvider "${authProvider}" has no KubernetesAuthProvider defined for it`
271
- );
272
- }
273
- async getCredentials(authProvider) {
274
- const kubernetesAuthProvider = this.kubernetesAuthProviderMap.get(authProvider);
275
- if (kubernetesAuthProvider) {
276
- return await kubernetesAuthProvider.getCredentials();
277
- }
278
- if (authProvider.startsWith("oidc.")) {
279
- throw new Error(
280
- `KubernetesAuthProviders has no oidcProvider configured for ${authProvider}`
281
- );
282
- }
283
- throw new Error(
284
- `authProvider "${authProvider}" has no KubernetesAuthProvider defined for it`
285
- );
286
- }
287
- }
288
-
289
- const useKubernetesObjects = (entity, intervalMs = 1e4) => {
290
- const kubernetesApi = useApi(kubernetesApiRef);
291
- const kubernetesAuthProvidersApi = useApi(kubernetesAuthProvidersApiRef);
292
- const getObjects = useCallback(async () => {
293
- const auth = await generateAuth(
294
- entity,
295
- kubernetesApi,
296
- kubernetesAuthProvidersApi
297
- );
298
- return await kubernetesApi.getObjectsByEntity({
299
- auth,
300
- entity
301
- });
302
- }, [kubernetesApi, entity, kubernetesAuthProvidersApi]);
303
- const { value, loading, error, retry } = useAsyncRetry(
304
- () => getObjects(),
305
- [getObjects]
306
- );
307
- useInterval(() => retry(), intervalMs);
308
- return {
309
- kubernetesObjects: value,
310
- loading,
311
- error: error == null ? void 0 : error.message
312
- };
313
- };
314
-
315
- const useCustomResources = (entity, customResourceMatchers, intervalMs = 1e4) => {
316
- const kubernetesApi = useApi(kubernetesApiRef);
317
- const kubernetesAuthProvidersApi = useApi(kubernetesAuthProvidersApiRef);
318
- const matchersString = JSON.stringify(customResourceMatchers);
319
- const getCustomObjects = useCallback(
320
- async () => {
321
- const auth = await generateAuth(
322
- entity,
323
- kubernetesApi,
324
- kubernetesAuthProvidersApi
325
- );
326
- return await kubernetesApi.getCustomObjectsByEntity({
327
- auth,
328
- customResources: customResourceMatchers,
329
- entity
330
- });
331
- },
332
- // eslint-disable-next-line react-hooks/exhaustive-deps
333
- [kubernetesApi, entity, kubernetesAuthProvidersApi, matchersString]
334
- );
335
- const { value, loading, error, retry } = useAsyncRetry(
336
- () => getCustomObjects(),
337
- [getCustomObjects]
338
- );
339
- useInterval(() => retry(), intervalMs);
340
- return {
341
- kubernetesObjects: value,
342
- loading,
343
- error: error == null ? void 0 : error.message
344
- };
345
- };
346
-
347
- const PodNamesWithErrorsContext = React__default.createContext(
348
- /* @__PURE__ */ new Set()
349
- );
350
-
351
- const PodNamesWithMetricsContext = React__default.createContext(/* @__PURE__ */ new Map());
352
-
353
- const GroupedResponsesContext = React__default.createContext({
354
- pods: [],
355
- replicaSets: [],
356
- deployments: [],
357
- daemonSets: [],
358
- services: [],
359
- configMaps: [],
360
- horizontalPodAutoscalers: [],
361
- ingresses: [],
362
- jobs: [],
363
- cronJobs: [],
364
- customResources: [],
365
- statefulsets: []
366
- });
367
-
368
- const ClusterContext = React__default.createContext({
369
- name: ""
370
- });
371
-
372
- const PodMetricsContext = React__default.createContext(/* @__PURE__ */ new Map());
373
- const usePodMetrics = (clusterName, matcher) => {
374
- var _a, _b, _c, _d;
375
- const targetRef = {
376
- name: (_b = (_a = matcher.metadata) == null ? void 0 : _a.name) != null ? _b : "",
377
- namespace: (_d = (_c = matcher.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
378
- };
379
- const metricsMap = useContext(PodMetricsContext);
380
- const metrics = metricsMap.get(clusterName);
381
- return metrics == null ? void 0 : metrics.find((m) => {
382
- var _a2, _b2, _c2, _d2;
383
- const pod = m.pod;
384
- return targetRef.name === ((_b2 = (_a2 = pod.metadata) == null ? void 0 : _a2.name) != null ? _b2 : "") && targetRef.namespace === ((_d2 = (_c2 = pod.metadata) == null ? void 0 : _c2.namespace) != null ? _d2 : "");
385
- });
386
- };
387
-
388
- const DetectedErrorsContext = React__default.createContext([]);
389
- const useMatchingErrors = (matcher) => {
390
- var _a, _b, _c, _d;
391
- const targetRef = {
392
- name: (_b = (_a = matcher.metadata) == null ? void 0 : _a.name) != null ? _b : "",
393
- namespace: (_d = (_c = matcher.metadata) == null ? void 0 : _c.namespace) != null ? _d : "",
394
- kind: matcher.kind,
395
- apiGroup: matcher.apiVersion
396
- };
397
- const errors = useContext(DetectedErrorsContext);
398
- return errors.filter((e) => {
399
- const r = e.sourceRef;
400
- return targetRef.apiGroup === r.apiGroup && targetRef.kind === r.kind && targetRef.name === r.name && targetRef.namespace === r.namespace;
401
- });
402
- };
403
-
404
- var __defProp$2 = Object.defineProperty;
405
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
406
- var __publicField$2 = (obj, key, value) => {
407
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
408
- return value;
409
- };
410
- class KubernetesBackendClient {
411
- constructor(options) {
412
- __publicField$2(this, "discoveryApi");
413
- __publicField$2(this, "identityApi");
414
- __publicField$2(this, "kubernetesAuthProvidersApi");
415
- this.discoveryApi = options.discoveryApi;
416
- this.identityApi = options.identityApi;
417
- this.kubernetesAuthProvidersApi = options.kubernetesAuthProvidersApi;
418
- }
419
- async handleResponse(response) {
420
- if (!response.ok) {
421
- const payload = await response.text();
422
- let message;
423
- switch (response.status) {
424
- case 404:
425
- message = "Could not find the Kubernetes Backend (HTTP 404). Make sure the plugin has been fully installed.";
426
- break;
427
- default:
428
- message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
429
- }
430
- throw new Error(message);
431
- }
432
- return await response.json();
433
- }
434
- async postRequired(path, requestBody) {
435
- const url = `${await this.discoveryApi.getBaseUrl("kubernetes")}${path}`;
436
- const { token: idToken } = await this.identityApi.getCredentials();
437
- const response = await fetch(url, {
438
- method: "POST",
439
- headers: {
440
- "Content-Type": "application/json",
441
- ...idToken && { Authorization: `Bearer ${idToken}` }
442
- },
443
- body: JSON.stringify(requestBody)
444
- });
445
- return this.handleResponse(response);
446
- }
447
- async getCluster(clusterName) {
448
- const cluster = await this.getClusters().then(
449
- (clusters) => clusters.find((c) => c.name === clusterName)
450
- );
451
- if (!cluster) {
452
- throw new NotFoundError(`Cluster ${clusterName} not found`);
453
- }
454
- return cluster;
455
- }
456
- async getCredentials(authProvider, oidcTokenProvider) {
457
- return await this.kubernetesAuthProvidersApi.getCredentials(
458
- authProvider === "oidc" ? `${authProvider}.${oidcTokenProvider}` : authProvider
459
- );
460
- }
461
- async getObjectsByEntity(requestBody) {
462
- return await this.postRequired(
463
- `/services/${requestBody.entity.metadata.name}`,
464
- requestBody
465
- );
466
- }
467
- async getWorkloadsByEntity(request) {
468
- return await this.postRequired("/resources/workloads/query", {
469
- auth: request.auth,
470
- entityRef: stringifyEntityRef(request.entity)
471
- });
472
- }
473
- async getCustomObjectsByEntity(request) {
474
- return await this.postRequired(`/resources/custom/query`, {
475
- entityRef: stringifyEntityRef(request.entity),
476
- auth: request.auth,
477
- customResources: request.customResources
478
- });
479
- }
480
- async getClusters() {
481
- const { token: idToken } = await this.identityApi.getCredentials();
482
- const url = `${await this.discoveryApi.getBaseUrl("kubernetes")}/clusters`;
483
- const response = await fetch(url, {
484
- method: "GET",
485
- headers: {
486
- ...idToken && { Authorization: `Bearer ${idToken}` }
487
- }
488
- });
489
- return (await this.handleResponse(response)).items;
490
- }
491
- async proxy(options) {
492
- const { authProvider, oidcTokenProvider } = await this.getCluster(
493
- options.clusterName
494
- );
495
- const kubernetesCredentials = await this.getCredentials(
496
- authProvider,
497
- oidcTokenProvider
498
- );
499
- const url = `${await this.discoveryApi.getBaseUrl("kubernetes")}/proxy${options.path}`;
500
- const identityResponse = await this.identityApi.getCredentials();
501
- const headers = KubernetesBackendClient.getKubernetesHeaders(
502
- options,
503
- kubernetesCredentials == null ? void 0 : kubernetesCredentials.token,
504
- identityResponse,
505
- authProvider,
506
- oidcTokenProvider
507
- );
508
- return await fetch(url, { ...options.init, headers });
509
- }
510
- static getKubernetesHeaders(options, k8sToken, identityResponse, authProvider, oidcTokenProvider) {
511
- var _a;
512
- const kubernetesAuthHeader = KubernetesBackendClient.getKubernetesAuthHeaderByAuthProvider(
513
- authProvider,
514
- oidcTokenProvider
515
- );
516
- return {
517
- ...(_a = options.init) == null ? void 0 : _a.headers,
518
- [`Backstage-Kubernetes-Cluster`]: options.clusterName,
519
- ...k8sToken && {
520
- [kubernetesAuthHeader]: k8sToken
521
- },
522
- ...identityResponse.token && {
523
- Authorization: `Bearer ${identityResponse.token}`
524
- }
525
- };
526
- }
527
- static getKubernetesAuthHeaderByAuthProvider(authProvider, oidcTokenProvider) {
528
- let header = "Backstage-Kubernetes-Authorization";
529
- header = header.concat("-", authProvider);
530
- if (oidcTokenProvider)
531
- header = header.concat("-", oidcTokenProvider);
532
- return header;
533
- }
534
- }
535
-
536
- var __defProp$1 = Object.defineProperty;
537
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
538
- var __publicField$1 = (obj, key, value) => {
539
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
540
- return value;
541
- };
542
- class KubernetesClusterLinkFormatter {
543
- constructor(options) {
544
- __publicField$1(this, "formatters");
545
- __publicField$1(this, "defaultFormatterName");
546
- this.formatters = options.formatters;
547
- this.defaultFormatterName = options.defaultFormatterName;
548
- }
549
- async formatClusterLink(options) {
550
- var _a;
551
- if (!options.dashboardUrl && !options.dashboardParameters) {
552
- return void 0;
553
- }
554
- if (options.dashboardUrl && !options.object) {
555
- return options.dashboardUrl;
556
- }
557
- const app = (_a = options.dashboardApp) != null ? _a : this.defaultFormatterName;
558
- const formatter = this.formatters[app];
559
- if (!formatter) {
560
- throw new Error(`Could not find Kubernetes dashboard app named '${app}'`);
561
- }
562
- const url = await formatter.formatClusterLink({
563
- dashboardUrl: options.dashboardUrl ? new URL(options.dashboardUrl) : void 0,
564
- dashboardParameters: options.dashboardParameters,
565
- object: options.object,
566
- kind: options.kind
567
- });
568
- return url.toString();
569
- }
570
- }
571
-
572
- var __defProp = Object.defineProperty;
573
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
574
- var __publicField = (obj, key, value) => {
575
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
576
- return value;
577
- };
578
- class KubernetesProxyClient {
579
- constructor(options) {
580
- __publicField(this, "kubernetesApi");
581
- this.kubernetesApi = options.kubernetesApi;
582
- }
583
- async handleText(response) {
584
- if (!response.ok) {
585
- const payload = await response.text();
586
- let message;
587
- switch (response.status) {
588
- default:
589
- message = `Proxy request failed with ${response.status} ${response.statusText}, ${payload}`;
590
- }
591
- throw new Error(message);
592
- }
593
- return await response.text();
594
- }
595
- async handleJson(response) {
596
- if (!response.ok) {
597
- const payload = await response.text();
598
- let message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
599
- switch (response.status) {
600
- case 404:
601
- message = `Proxy request failed with ${response.status} ${response.statusText}, ${payload}`;
602
- break;
603
- default:
604
- message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
605
- }
606
- throw new Error(message);
607
- }
608
- return await response.json();
609
- }
610
- async getEventsByInvolvedObjectName({
611
- clusterName,
612
- involvedObjectName,
613
- namespace
614
- }) {
615
- return await this.kubernetesApi.proxy({
616
- clusterName,
617
- path: `/api/v1/namespaces/${namespace}/events?fieldSelector=involvedObject.name=${involvedObjectName}`,
618
- init: {
619
- method: "GET"
620
- }
621
- }).then((response) => this.handleJson(response)).then((eventList) => eventList.items);
622
- }
623
- async getPodLogs({
624
- podName,
625
- namespace,
626
- clusterName,
627
- containerName,
628
- previous
629
- }) {
630
- const params = new URLSearchParams({
631
- container: containerName
632
- });
633
- if (previous) {
634
- params.append("previous", "");
635
- }
636
- return await this.kubernetesApi.proxy({
637
- clusterName,
638
- path: `/api/v1/namespaces/${namespace}/pods/${podName}/log?${params.toString()}`,
639
- init: {
640
- method: "GET"
641
- }
642
- }).then((response) => this.handleText(response)).then((text) => ({ text }));
643
- }
644
- }
645
-
646
- const basePath = "https://portal.azure.com/#blade/Microsoft_Azure_ContainerService/AksK8ResourceMenuBlade/overview-Deployment/aksClusterId";
647
- const requiredParams = ["subscriptionId", "resourceGroup", "clusterName"];
648
- class AksClusterLinksFormatter {
649
- async formatClusterLink(options) {
650
- if (!options.dashboardParameters) {
651
- throw new Error("AKS dashboard requires a dashboardParameters option");
652
- }
653
- const args = options.dashboardParameters;
654
- for (const param of requiredParams) {
655
- if (typeof args[param] !== "string") {
656
- throw new Error(
657
- `AKS dashboard requires a "${param}" of type string in the dashboardParameters option`
658
- );
659
- }
660
- }
661
- const path = `/subscriptions/${args.subscriptionId}/resourceGroups/${args.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${args.clusterName}`;
662
- const { name, namespace, uid } = options.object.metadata;
663
- const { selector } = options.object.spec;
664
- const params = {
665
- kind: options.kind,
666
- metadata: { name, namespace, uid },
667
- spec: {
668
- selector
669
- }
670
- };
671
- return new URL(
672
- `${basePath}/${encodeURIComponent(path)}/resource/${encodeURIComponent(
673
- JSON.stringify(params)
674
- )}`
675
- );
676
- }
677
- }
678
-
679
- class EksClusterLinksFormatter {
680
- async formatClusterLink(_options) {
681
- throw new Error(
682
- "EKS formatter is not yet implemented. Please, contribute!"
683
- );
684
- }
685
- }
686
-
687
- const kindMappings$3 = {
688
- deployment: "deployment",
689
- pod: "pod",
690
- ingress: "ingress",
691
- service: "service",
692
- horizontalpodautoscaler: "deployment"
693
- };
694
- class GkeClusterLinksFormatter {
695
- constructor(googleAuthApi) {
696
- this.googleAuthApi = googleAuthApi;
697
- }
698
- async formatClusterLink(options) {
699
- var _a, _b, _c, _d;
700
- if (!options.dashboardParameters) {
701
- throw new Error("GKE dashboard requires a dashboardParameters option");
702
- }
703
- const args = options.dashboardParameters;
704
- if (typeof args.projectId !== "string") {
705
- throw new Error(
706
- 'GKE dashboard requires a "projectId" of type string in the dashboardParameters option'
707
- );
708
- }
709
- if (typeof args.region !== "string") {
710
- throw new Error(
711
- 'GKE dashboard requires a "region" of type string in the dashboardParameters option'
712
- );
713
- }
714
- if (typeof args.clusterName !== "string") {
715
- throw new Error(
716
- 'GKE dashboard requires a "clusterName" of type string in the dashboardParameters option'
717
- );
718
- }
719
- const basePath = new URL("https://console.cloud.google.com/");
720
- const region = encodeURIComponent(args.region);
721
- const clusterName = encodeURIComponent(args.clusterName);
722
- const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
723
- const namespace = encodeURIComponent(
724
- (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
725
- );
726
- const validKind = kindMappings$3[options.kind.toLocaleLowerCase("en-US")];
727
- let path;
728
- if (namespace && name && validKind) {
729
- const kindsWithDetails = ["ingress", "pod"];
730
- const landingPage = kindsWithDetails.includes(validKind) ? "details" : "overview";
731
- path = `kubernetes/${validKind}/${region}/${clusterName}/${namespace}/${name}/${landingPage}`;
732
- } else {
733
- path = `kubernetes/clusters/details/${region}/${clusterName}/details`;
734
- }
735
- const result = new URL(path, basePath);
736
- result.searchParams.set("project", args.projectId);
737
- if (this.googleAuthApi) {
738
- const profile = await this.googleAuthApi.getProfile({ optional: true });
739
- if (profile == null ? void 0 : profile.email) {
740
- result.searchParams.set("authuser", profile.email);
741
- }
742
- }
743
- return result;
744
- }
745
- }
746
-
747
- const kindMappings$2 = {
748
- deployment: "deployment",
749
- pod: "pod",
750
- ingress: "ingress",
751
- service: "service",
752
- horizontalpodautoscaler: "deployment",
753
- statefulset: "statefulset"
754
- };
755
- class StandardClusterLinksFormatter {
756
- async formatClusterLink(options) {
757
- var _a, _b, _c, _d;
758
- if (!options.dashboardUrl) {
759
- throw new Error("standard dashboard requires a dashboardUrl option");
760
- }
761
- const result = new URL(options.dashboardUrl.href);
762
- const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
763
- const namespace = encodeURIComponent(
764
- (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
765
- );
766
- const validKind = kindMappings$2[options.kind.toLocaleLowerCase("en-US")];
767
- if (!result.pathname.endsWith("/")) {
768
- result.pathname += "/";
769
- }
770
- if (validKind && name && namespace) {
771
- result.hash = `/${validKind}/${namespace}/${name}`;
772
- } else if (namespace) {
773
- result.hash = "/workloads";
774
- }
775
- if (namespace) {
776
- result.hash += `?namespace=${namespace}`;
777
- }
778
- return result;
779
- }
780
- }
781
-
782
- const kindMappings$1 = {
783
- deployment: "deployments",
784
- ingress: "ingresses",
785
- service: "services",
786
- horizontalpodautoscaler: "horizontalpodautoscalers",
787
- persistentvolume: "persistentvolumes"
788
- };
789
- class OpenshiftClusterLinksFormatter {
790
- async formatClusterLink(options) {
791
- var _a, _b, _c, _d;
792
- if (!options.dashboardUrl) {
793
- throw new Error("OpenShift dashboard requires a dashboardUrl option");
794
- }
795
- const basePath = new URL(options.dashboardUrl.href);
796
- const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
797
- const namespace = encodeURIComponent(
798
- (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
799
- );
800
- const validKind = kindMappings$1[options.kind.toLocaleLowerCase("en-US")];
801
- if (!basePath.pathname.endsWith("/")) {
802
- basePath.pathname += "/";
803
- }
804
- let path = "";
805
- if (namespace) {
806
- if (name && validKind) {
807
- path = `k8s/ns/${namespace}/${validKind}/${name}`;
808
- } else {
809
- path = `k8s/cluster/projects/${namespace}`;
810
- }
811
- } else if (validKind) {
812
- path = `k8s/cluster/${validKind}`;
813
- if (name) {
814
- path += `/${name}`;
815
- }
816
- }
817
- return new URL(path, basePath);
818
- }
819
- }
820
-
821
- const kindMappings = {
822
- deployment: "apps.deployment",
823
- ingress: "networking.k8s.io.ingress",
824
- service: "service",
825
- horizontalpodautoscaler: "autoscaling.horizontalpodautoscaler"
826
- };
827
- class RancherClusterLinksFormatter {
828
- async formatClusterLink(options) {
829
- var _a, _b, _c, _d;
830
- if (!options.dashboardUrl) {
831
- throw new Error("Rancher dashboard requires a dashboardUrl option");
832
- }
833
- const basePath = new URL(options.dashboardUrl.href);
834
- const name = encodeURIComponent((_b = (_a = options.object.metadata) == null ? void 0 : _a.name) != null ? _b : "");
835
- const namespace = encodeURIComponent(
836
- (_d = (_c = options.object.metadata) == null ? void 0 : _c.namespace) != null ? _d : ""
837
- );
838
- const validKind = kindMappings[options.kind.toLocaleLowerCase("en-US")];
839
- if (!basePath.pathname.endsWith("/")) {
840
- basePath.pathname += "/";
841
- }
842
- let path = "";
843
- if (validKind && name && namespace) {
844
- path = `explorer/${validKind}/${namespace}/${name}`;
845
- } else if (namespace) {
846
- path = "explorer/workload";
847
- }
848
- return new URL(path, basePath);
849
- }
850
- }
851
-
852
- const DEFAULT_FORMATTER_NAME = "standard";
853
- function getDefaultFormatters(deps) {
854
- return {
855
- standard: new StandardClusterLinksFormatter(),
856
- aks: new AksClusterLinksFormatter(),
857
- eks: new EksClusterLinksFormatter(),
858
- gke: new GkeClusterLinksFormatter(deps.googleAuthApi),
859
- openshift: new OpenshiftClusterLinksFormatter(),
860
- rancher: new RancherClusterLinksFormatter()
861
- };
862
- }
863
-
864
- const currentToDeclaredResourceToPerc$1 = (current, resource) => {
865
- if (Number(resource) === 0)
866
- return 0;
867
- if (typeof current === "number" && typeof resource === "number") {
868
- return Math.round(current / resource * 100);
869
- }
870
- const numerator = BigInt(current);
871
- const denominator = BigInt(resource);
872
- return Number(numerator * BigInt(100) / denominator);
873
- };
874
- const bytesToMiB = (value) => {
875
- return `${(parseFloat(value.toString()) / 1024 / 1024).toFixed(0)}MiB`;
876
- };
877
- const formatMillicores = (value) => {
878
- return `${(parseFloat(value.toString()) * 1e3).toFixed(0)}m`;
879
- };
880
-
881
- const useStyles$3 = makeStyles(
882
- (theme) => createStyles({
883
- dialogPaper: { minHeight: "calc(100% - 64px)" },
884
- dialogContent: { flexBasis: 0 },
885
- closeButton: {
886
- position: "absolute",
887
- right: theme.spacing(1),
888
- top: theme.spacing(1),
889
- color: theme.palette.grey[500]
890
- }
891
- })
892
- );
893
- const KubernetesDialog = ({
894
- buttonAriaLabel,
895
- buttonIcon,
896
- buttonText,
897
- children,
898
- disabled,
899
- title
900
- }) => {
901
- const classes = useStyles$3();
902
- const [open, setOpen] = useState(false);
903
- const openDialog = () => {
904
- setOpen(true);
905
- };
906
- const closeDialog = () => {
907
- setOpen(false);
908
- };
909
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
910
- Dialog,
911
- {
912
- maxWidth: "xl",
913
- fullWidth: true,
914
- open,
915
- onClose: closeDialog,
916
- PaperProps: { className: classes.dialogPaper }
917
- },
918
- /* @__PURE__ */ React__default.createElement(DialogTitle, { id: "dialog-title" }, title, /* @__PURE__ */ React__default.createElement(
919
- IconButton,
920
- {
921
- "aria-label": "close",
922
- className: classes.closeButton,
923
- onClick: closeDialog
924
- },
925
- /* @__PURE__ */ React__default.createElement(CloseIcon, null)
926
- )),
927
- /* @__PURE__ */ React__default.createElement(DialogContent, { className: classes.dialogContent }, children)
928
- ), /* @__PURE__ */ React__default.createElement(
929
- Button,
930
- {
931
- variant: "outlined",
932
- "aria-label": buttonAriaLabel,
933
- component: "label",
934
- disabled,
935
- onClick: openDialog,
936
- startIcon: buttonIcon
937
- },
938
- buttonText
939
- ));
940
- };
941
-
942
- var __accessCheck = (obj, member, msg) => {
943
- if (!member.has(obj))
944
- throw TypeError("Cannot " + msg);
945
- };
946
- var __privateGet = (obj, member, getter) => {
947
- __accessCheck(obj, member, "read from private field");
948
- return getter ? getter.call(obj) : member.get(obj);
949
- };
950
- var __privateAdd = (obj, member, value) => {
951
- if (member.has(obj))
952
- throw TypeError("Cannot add the same private member more than once");
953
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
954
- };
955
- var _textEncoder;
956
- class PodExecTerminalAttachAddon extends AttachAddon {
957
- constructor(socket, options) {
958
- super(socket, options);
959
- __privateAdd(this, _textEncoder, new TextEncoder());
960
- const thisAddon = this;
961
- thisAddon._sendBinary = (data) => {
962
- if (!thisAddon._checkOpenSocket()) {
963
- return;
964
- }
965
- const buffer = Uint8Array.from([0, ...__privateGet(this, _textEncoder).encode(data)]);
966
- thisAddon._socket.send(buffer);
967
- };
968
- thisAddon._sendData = (data) => {
969
- if (!thisAddon._checkOpenSocket()) {
970
- return;
971
- }
972
- thisAddon._sendBinary(data);
973
- };
974
- }
975
- }
976
- _textEncoder = new WeakMap();
977
-
978
- const hasSocketProtocol = (url) => /wss?:\/\//.test(url.toString());
979
- const useStyles$2 = makeStyles(
980
- (theme) => createStyles({
981
- podExecTerminal: {
982
- width: "100%",
983
- height: "100%",
984
- "& .xterm-screen": { padding: theme.spacing(1) }
985
- }
986
- })
987
- );
988
- const PodExecTerminal = (props) => {
989
- const classes = useStyles$2();
990
- const { containerName, podNamespace, podName } = props;
991
- const [baseUrl, setBaseUrl] = useState(window.location.host);
992
- const terminalRef = React__default.useRef(null);
993
- const discoveryApi = useApi(discoveryApiRef);
994
- const namespace = podNamespace != null ? podNamespace : "default";
995
- useEffect(() => {
996
- discoveryApi.getBaseUrl("kubernetes").then((url) => url != null ? url : window.location.host).then((url) => url.replace(/^http(s?):\/\//, "ws$1://")).then((url) => setBaseUrl(url));
997
- }, [discoveryApi]);
998
- const urlParams = useMemo(() => {
999
- const params = new URLSearchParams({
1000
- container: containerName,
1001
- stdin: "true",
1002
- stdout: "true",
1003
- stderr: "true",
1004
- tty: "true",
1005
- command: "/bin/sh"
1006
- });
1007
- return params;
1008
- }, [containerName]);
1009
- const socketUrl = useMemo(() => {
1010
- if (!hasSocketProtocol(baseUrl)) {
1011
- return "";
1012
- }
1013
- return new URL(
1014
- `${baseUrl}/proxy/api/v1/namespaces/${namespace}/pods/${podName}/exec?${urlParams}`
1015
- );
1016
- }, [baseUrl, namespace, podName, urlParams]);
1017
- useEffect(() => {
1018
- if (!hasSocketProtocol(socketUrl)) {
1019
- return () => {
1020
- };
1021
- }
1022
- const terminal = new Terminal();
1023
- const fitAddon = new FitAddon();
1024
- terminal.loadAddon(fitAddon);
1025
- if (terminalRef.current) {
1026
- terminal.open(terminalRef.current);
1027
- fitAddon.fit();
1028
- }
1029
- terminal.writeln("Starting terminal, please wait...");
1030
- const socket = new WebSocket(socketUrl, ["channel.k8s.io"]);
1031
- socket.onopen = () => {
1032
- terminal.clear();
1033
- const attachAddon = new PodExecTerminalAttachAddon(socket, {
1034
- bidirectional: true
1035
- });
1036
- terminal.loadAddon(attachAddon);
1037
- };
1038
- socket.onclose = () => {
1039
- terminal.writeln("Socket connection closed");
1040
- };
1041
- return () => {
1042
- terminal == null ? void 0 : terminal.clear();
1043
- socket == null ? void 0 : socket.close();
1044
- };
1045
- }, [baseUrl, socketUrl]);
1046
- return /* @__PURE__ */ React__default.createElement(
1047
- "div",
1048
- {
1049
- "data-testid": "terminal",
1050
- ref: terminalRef,
1051
- className: classes.podExecTerminal
1052
- }
1053
- );
1054
- };
1055
-
1056
- const PodExecTerminalDialog = (props) => {
1057
- const { cluster, containerName, podName } = props;
1058
- const isPodExecTerminalSupported = useIsPodExecTerminalSupported();
1059
- return !isPodExecTerminalSupported.loading && isPodExecTerminalSupported.value && /* @__PURE__ */ React__default.createElement(
1060
- KubernetesDialog,
1061
- {
1062
- buttonAriaLabel: "open terminal",
1063
- buttonIcon: /* @__PURE__ */ React__default.createElement(OpenInBrowserIcon, null),
1064
- buttonText: "Terminal",
1065
- disabled: isPodExecTerminalSupported.loading || !isPodExecTerminalSupported.value,
1066
- title: `${podName} - ${containerName} terminal shell on cluster ${cluster.title || cluster.name}`
1067
- },
1068
- /* @__PURE__ */ React__default.createElement(PodExecTerminal, { ...props })
1069
- );
1070
- };
1071
-
1072
- const getProgressColor = ({
1073
- palette,
1074
- value,
1075
- inverse,
1076
- max
1077
- }) => {
1078
- if (isNaN(value)) {
1079
- return palette.status.pending;
1080
- }
1081
- const actualMax = max ? max : 100;
1082
- const actualValue = inverse ? actualMax - value : value;
1083
- if (actualValue >= actualMax) {
1084
- return palette.status.error;
1085
- } else if (actualValue > 90 || actualValue < 40) {
1086
- return palette.status.warning;
1087
- }
1088
- return palette.status.ok;
1089
- };
1090
- const ResourceUtilization = ({
1091
- compressed = false,
1092
- title,
1093
- usage,
1094
- total,
1095
- totalFormatted
1096
- }) => {
1097
- const utilization = currentToDeclaredResourceToPerc$1(usage, total);
1098
- return /* @__PURE__ */ React__default.createElement(Grid, { container: true, spacing: 0 }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
1099
- Typography,
1100
- {
1101
- variant: compressed ? "caption" : "subtitle2"
1102
- },
1103
- `${title}: ${totalFormatted}`
1104
- )), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
1105
- LinearGauge,
1106
- {
1107
- getColor: getProgressColor,
1108
- width: compressed ? "thin" : "thick",
1109
- value: utilization / 100
1110
- }
1111
- ), !compressed && /* @__PURE__ */ React__default.createElement(Typography, { variant: "caption" }, "usage: ", `${utilization}%`)));
1112
- };
1113
-
1114
- const usePodLogs = ({ containerScope, previous }) => {
1115
- const kubernetesProxyApi = useApi(kubernetesProxyApiRef);
1116
- return useAsync(async () => {
1117
- return await kubernetesProxyApi.getPodLogs({
1118
- podName: containerScope.podName,
1119
- namespace: containerScope.podNamespace,
1120
- containerName: containerScope.containerName,
1121
- clusterName: containerScope.cluster.name,
1122
- previous
1123
- });
1124
- }, [JSON.stringify(containerScope)]);
1125
- };
1126
-
1127
- const PodLogs = ({
1128
- containerScope,
1129
- previous
1130
- }) => {
1131
- const { value, error, loading } = usePodLogs({
1132
- containerScope,
1133
- previous
1134
- });
1135
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, error && /* @__PURE__ */ React__default.createElement(
1136
- DismissableBanner,
1137
- {
1138
- ...{
1139
- message: error.message,
1140
- variant: "error",
1141
- fixed: false
1142
- },
1143
- id: "pod-logs"
1144
- }
1145
- ), /* @__PURE__ */ React__default.createElement(
1146
- Paper,
1147
- {
1148
- elevation: 1,
1149
- style: { height: "100%", width: "100%", minHeight: "55rem" }
1150
- },
1151
- loading && /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rect", width: "100%", height: "100%" }),
1152
- !loading && value !== void 0 && (value.text === "" ? /* @__PURE__ */ React__default.createElement(
1153
- EmptyState,
1154
- {
1155
- missing: "data",
1156
- title: "No logs emitted",
1157
- description: "No logs were emitted by the container"
1158
- }
1159
- ) : /* @__PURE__ */ React__default.createElement(LogViewer, { text: value.text }))
1160
- ));
1161
- };
1162
-
1163
- const PodLogsDialog = ({ containerScope }) => {
1164
- return /* @__PURE__ */ React__default.createElement(
1165
- KubernetesDialog,
1166
- {
1167
- buttonAriaLabel: "get logs",
1168
- buttonIcon: /* @__PURE__ */ React__default.createElement(SubjectIcon, null),
1169
- buttonText: "Logs",
1170
- disabled: false,
1171
- title: `${containerScope.podName} - ${containerScope.containerName} logs on cluster ${containerScope.cluster.title || containerScope.cluster.name}`
1172
- },
1173
- /* @__PURE__ */ React__default.createElement(PodLogs, { containerScope })
1174
- );
1175
- };
1176
-
1177
- const getContainerHealthChecks = (containerSpec, containerStatus) => {
1178
- var _a, _b, _c, _d;
1179
- if (((_b = (_a = containerStatus.state) == null ? void 0 : _a.terminated) == null ? void 0 : _b.reason) === "Completed") {
1180
- return {
1181
- "not waiting to start": ((_c = containerStatus.state) == null ? void 0 : _c.waiting) === void 0,
1182
- "no restarts": containerStatus.restartCount === 0
1183
- };
1184
- }
1185
- return {
1186
- "not waiting to start": ((_d = containerStatus.state) == null ? void 0 : _d.waiting) === void 0,
1187
- started: !!containerStatus.started,
1188
- ready: containerStatus.ready,
1189
- "no restarts": containerStatus.restartCount === 0,
1190
- "readiness probe set": containerSpec && (containerSpec == null ? void 0 : containerSpec.readinessProbe) !== void 0
1191
- };
1192
- };
1193
- const getCurrentState = (containerStatus) => {
1194
- var _a, _b, _c, _d, _e;
1195
- 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");
1196
- };
1197
- const getStartedAtTime = (containerStatus) => {
1198
- var _a, _b, _c, _d;
1199
- 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);
1200
- };
1201
- const ContainerDatetime = ({ prefix, dateTime }) => {
1202
- return /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, prefix, ":", " ", DateTime.fromISO(dateTime).toRelative({
1203
- locale: "en"
1204
- }));
1205
- };
1206
- const ContainerCard = ({
1207
- podScope,
1208
- containerSpec,
1209
- containerStatus,
1210
- containerMetrics
1211
- }) => {
1212
- var _a, _b;
1213
- const isPodExecTerminalEnabled = useIsPodExecTerminalEnabled();
1214
- if (containerSpec === void 0) {
1215
- return /* @__PURE__ */ React__default.createElement(Typography, null, "error reading pod from cluster");
1216
- }
1217
- const containerStartedTime = getStartedAtTime(containerStatus);
1218
- const containerFinishedTime = (_b = (_a = containerStatus.state) == null ? void 0 : _a.terminated) == null ? void 0 : _b.finishedAt;
1219
- return /* @__PURE__ */ React__default.createElement(Card, null, /* @__PURE__ */ React__default.createElement(
1220
- CardHeader,
1221
- {
1222
- title: containerStatus.name,
1223
- subheader: containerStatus.image
1224
- }
1225
- ), /* @__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(
1226
- ContainerDatetime,
1227
- {
1228
- prefix: "Started",
1229
- dateTime: containerStartedTime
1230
- }
1231
- ), containerFinishedTime && /* @__PURE__ */ React__default.createElement(
1232
- ContainerDatetime,
1233
- {
1234
- prefix: "Completed",
1235
- dateTime: containerFinishedTime
1236
- }
1237
- ), containerStartedTime && containerFinishedTime && /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "Execution time:", " ", DateTime.fromISO(containerFinishedTime).diff(DateTime.fromISO(containerStartedTime), [
1238
- "hours",
1239
- "minutes",
1240
- "seconds"
1241
- ]).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(
1242
- StructuredMetadataTable,
1243
- {
1244
- metadata: getContainerHealthChecks(
1245
- containerSpec,
1246
- containerStatus
1247
- )
1248
- }
1249
- )), containerMetrics && /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, xs: 12, spacing: 0 }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, "Resource utilization")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12, style: { minHeight: "5rem" } }, /* @__PURE__ */ React__default.createElement(
1250
- ResourceUtilization,
1251
- {
1252
- compressed: true,
1253
- title: "CPU requests",
1254
- usage: containerMetrics.cpuUsage.currentUsage,
1255
- total: containerMetrics.cpuUsage.requestTotal,
1256
- totalFormatted: formatMillicores(
1257
- containerMetrics.cpuUsage.requestTotal
1258
- )
1259
- }
1260
- ), /* @__PURE__ */ React__default.createElement(
1261
- ResourceUtilization,
1262
- {
1263
- compressed: true,
1264
- title: "CPU limits",
1265
- usage: containerMetrics.cpuUsage.currentUsage,
1266
- total: containerMetrics.cpuUsage.limitTotal,
1267
- totalFormatted: formatMillicores(
1268
- containerMetrics.cpuUsage.limitTotal
1269
- )
1270
- }
1271
- ), /* @__PURE__ */ React__default.createElement(
1272
- ResourceUtilization,
1273
- {
1274
- compressed: true,
1275
- title: "Memory requests",
1276
- usage: containerMetrics.memoryUsage.currentUsage,
1277
- total: containerMetrics.memoryUsage.requestTotal,
1278
- totalFormatted: bytesToMiB(
1279
- containerMetrics.memoryUsage.requestTotal
1280
- )
1281
- }
1282
- ), /* @__PURE__ */ React__default.createElement(
1283
- ResourceUtilization,
1284
- {
1285
- compressed: true,
1286
- title: "Memory limits",
1287
- usage: containerMetrics.memoryUsage.currentUsage,
1288
- total: containerMetrics.memoryUsage.limitTotal,
1289
- totalFormatted: bytesToMiB(
1290
- containerMetrics.memoryUsage.limitTotal
1291
- )
1292
- }
1293
- ))))), /* @__PURE__ */ React__default.createElement(CardActions, null, /* @__PURE__ */ React__default.createElement(
1294
- PodLogsDialog,
1295
- {
1296
- containerScope: {
1297
- containerName: containerStatus.name,
1298
- ...podScope
1299
- }
1300
- }
1301
- ), isPodExecTerminalEnabled && /* @__PURE__ */ React__default.createElement(
1302
- PodExecTerminalDialog,
1303
- {
1304
- cluster: podScope.cluster,
1305
- containerName: containerStatus.name,
1306
- podName: podScope.podName,
1307
- podNamespace: podScope.podNamespace
1308
- }
1309
- )));
1310
- };
1311
-
1312
- const ManifestYaml = ({ object }) => {
1313
- const [managedFields, setManagedFields] = useState(false);
1314
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
1315
- FormControlLabel,
1316
- {
1317
- control: /* @__PURE__ */ React__default.createElement(
1318
- Switch,
1319
- {
1320
- checked: managedFields,
1321
- onChange: (event) => {
1322
- setManagedFields(event.target.checked);
1323
- },
1324
- name: "Managed Fields"
1325
- }
1326
- ),
1327
- label: "Managed Fields"
1328
- }
1329
- ), /* @__PURE__ */ React__default.createElement(
1330
- CodeSnippet,
1331
- {
1332
- language: "yaml",
1333
- text: jsyaml.dump(object, {
1334
- // NOTE: this will remove any field called `managedFields`
1335
- // not just the metadata one
1336
- // TODO: @mclarke make this only remove the `metadata.managedFields`
1337
- replacer: (key, value) => {
1338
- if (!managedFields) {
1339
- return key === "managedFields" ? void 0 : value;
1340
- }
1341
- return value;
1342
- }
1343
- })
1344
- }
1345
- ));
1346
- };
1347
-
1348
- const useDrawerStyles$1 = makeStyles(
1349
- (theme) => createStyles({
1350
- paper: {
1351
- width: "50%",
1352
- justifyContent: "space-between",
1353
- padding: theme.spacing(2.5)
1354
- }
1355
- })
1356
- );
1357
- const useDrawerContentStyles$2 = makeStyles(
1358
- (_) => createStyles({
1359
- header: {
1360
- display: "flex",
1361
- flexDirection: "row",
1362
- justifyContent: "space-between"
1363
- },
1364
- errorMessage: {
1365
- marginTop: "1em",
1366
- marginBottom: "1em"
1367
- },
1368
- options: {
1369
- display: "flex",
1370
- flexDirection: "row",
1371
- justifyContent: "space-between"
1372
- },
1373
- icon: {
1374
- fontSize: 20
1375
- },
1376
- content: {
1377
- height: "80%"
1378
- }
1379
- })
1380
- );
1381
- const PodDrawerButton = withStyles({
1382
- root: {
1383
- padding: "6px 5px"
1384
- },
1385
- label: {
1386
- textTransform: "none"
1387
- }
1388
- })(Button);
1389
- const LinkErrorPanel = ({
1390
- cluster,
1391
- errorMessage
1392
- }) => /* @__PURE__ */ React__default.createElement(
1393
- WarningPanel,
1394
- {
1395
- title: "There was a problem formatting the link to the Kubernetes dashboard",
1396
- message: `Could not format the link to the dashboard of your cluster named '${cluster.name}'. Its dashboardApp property has been set to '${cluster.dashboardApp || "standard"}.'`
1397
- },
1398
- errorMessage && /* @__PURE__ */ React__default.createElement(Typography, { variant: "body2" }, "Errors: ", errorMessage)
1399
- );
1400
- function replaceNullsWithUndefined(someObj) {
1401
- const replacer = (_, value) => String(value) === "null" || String(value) === "undefined" ? void 0 : value;
1402
- return JSON.parse(JSON.stringify(someObj, replacer));
1403
- }
1404
- const KubernetesStructuredMetadataTableDrawerContent = ({
1405
- toggleDrawer,
1406
- object,
1407
- renderObject,
1408
- kind
1409
- }) => {
1410
- var _a, _b;
1411
- const [isYaml, setIsYaml] = useState(false);
1412
- const formatter = useApi(kubernetesClusterLinkFormatterApiRef);
1413
- const classes = useDrawerContentStyles$2();
1414
- const cluster = useContext(ClusterContext);
1415
- const { value: clusterLink, error } = useAsync(
1416
- async () => formatter.formatClusterLink({
1417
- dashboardUrl: cluster.dashboardUrl,
1418
- dashboardApp: cluster.dashboardApp,
1419
- dashboardParameters: cluster.dashboardParameters,
1420
- object,
1421
- kind
1422
- }),
1423
- [cluster, object, kind, formatter]
1424
- );
1425
- 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(
1426
- IconButton,
1427
- {
1428
- key: "dismiss",
1429
- title: "Close the drawer",
1430
- onClick: (e) => toggleDrawer(e, false),
1431
- color: "inherit"
1432
- },
1433
- /* @__PURE__ */ React__default.createElement(CloseIcon, { className: classes.icon })
1434
- )), /* @__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(
1435
- FormControlLabel,
1436
- {
1437
- control: /* @__PURE__ */ React__default.createElement(
1438
- Switch,
1439
- {
1440
- checked: isYaml,
1441
- onChange: (event) => {
1442
- setIsYaml(event.target.checked);
1443
- },
1444
- name: "YAML"
1445
- }
1446
- ),
1447
- label: "YAML"
1448
- }
1449
- )))), error && /* @__PURE__ */ React__default.createElement("div", { className: classes.errorMessage }, /* @__PURE__ */ React__default.createElement(
1450
- LinkErrorPanel,
1451
- {
1452
- cluster,
1453
- errorMessage: error.message || error.toString()
1454
- }
1455
- )), /* @__PURE__ */ React__default.createElement("div", { className: classes.options }, /* @__PURE__ */ React__default.createElement("div", null, clusterLink && /* @__PURE__ */ React__default.createElement(
1456
- LinkButton,
1457
- {
1458
- variant: "outlined",
1459
- color: "primary",
1460
- size: "small",
1461
- to: clusterLink,
1462
- endIcon: /* @__PURE__ */ React__default.createElement(OpenInNewIcon, null)
1463
- },
1464
- "Open Kubernetes Dashboard"
1465
- ))), /* @__PURE__ */ React__default.createElement("div", { className: classes.content }, isYaml && /* @__PURE__ */ React__default.createElement(ManifestYaml, { object }), !isYaml && /* @__PURE__ */ React__default.createElement(
1466
- StructuredMetadataTable,
1467
- {
1468
- metadata: renderObject(replaceNullsWithUndefined(object))
1469
- }
1470
- )));
1471
- };
1472
- const KubernetesStructuredMetadataTableDrawer = ({
1473
- object,
1474
- renderObject,
1475
- kind,
1476
- buttonVariant = "subtitle2",
1477
- expanded = false,
1478
- children
1479
- }) => {
1480
- var _a, _b;
1481
- const [isOpen, setIsOpen] = useState(expanded);
1482
- const classes = useDrawerStyles$1();
1483
- const toggleDrawer = (e, newValue) => {
1484
- e.stopPropagation();
1485
- setIsOpen(newValue);
1486
- };
1487
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
1488
- PodDrawerButton,
1489
- {
1490
- onClick: (e) => toggleDrawer(e, true),
1491
- onFocus: (event) => event.stopPropagation()
1492
- },
1493
- children === void 0 ? /* @__PURE__ */ React__default.createElement(Typography, { variant: buttonVariant }, (_b = (_a = object.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown object") : children
1494
- ), /* @__PURE__ */ React__default.createElement(
1495
- Drawer,
1496
- {
1497
- classes: {
1498
- paper: classes.paper
1499
- },
1500
- anchor: "right",
1501
- open: isOpen,
1502
- onClose: (e) => toggleDrawer(e, false),
1503
- onClick: (event) => event.stopPropagation()
1504
- },
1505
- /* @__PURE__ */ React__default.createElement(
1506
- KubernetesStructuredMetadataTableDrawerContent,
1507
- {
1508
- kind,
1509
- toggleDrawer,
1510
- object,
1511
- renderObject
1512
- }
1513
- )
1514
- ));
1515
- };
1516
-
1517
- const useDrawerContentStyles$1 = makeStyles(
1518
- (_theme) => createStyles({
1519
- header: {
1520
- display: "flex",
1521
- flexDirection: "row",
1522
- justifyContent: "space-between"
1523
- },
1524
- content: {
1525
- height: "80%"
1526
- },
1527
- icon: {
1528
- fontSize: 20
1529
- }
1530
- })
1531
- );
1532
- const KubernetesDrawerContent = ({
1533
- children,
1534
- header,
1535
- kubernetesObject,
1536
- close
1537
- }) => {
1538
- var _a;
1539
- const classes = useDrawerContentStyles$1();
1540
- const [isYaml, setIsYaml] = useState(false);
1541
- 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(
1542
- IconButton,
1543
- {
1544
- key: "dismiss",
1545
- title: "Close the drawer",
1546
- onClick: () => close(),
1547
- color: "inherit"
1548
- },
1549
- /* @__PURE__ */ React__default.createElement(CloseIcon, { className: classes.icon })
1550
- )), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, header), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
1551
- FormControlLabel,
1552
- {
1553
- control: /* @__PURE__ */ React__default.createElement(
1554
- Switch,
1555
- {
1556
- checked: isYaml,
1557
- onChange: (event) => {
1558
- setIsYaml(event.target.checked);
1559
- },
1560
- name: "YAML"
1561
- }
1562
- ),
1563
- label: "YAML"
1564
- }
1565
- )))), /* @__PURE__ */ React__default.createElement("div", { className: classes.content }, isYaml && /* @__PURE__ */ React__default.createElement(ManifestYaml, { object: kubernetesObject }), !isYaml && children));
1566
- };
1567
- const useDrawerStyles = makeStyles(
1568
- (theme) => createStyles({
1569
- paper: {
1570
- width: "50%",
1571
- justifyContent: "space-between",
1572
- padding: theme.spacing(2.5)
1573
- }
1574
- })
1575
- );
1576
- const DrawerButton = withStyles({
1577
- root: {
1578
- padding: "6px 5px"
1579
- },
1580
- label: {
1581
- textTransform: "none"
1582
- }
1583
- })(Button);
1584
- const KubernetesDrawer = ({
1585
- open,
1586
- label,
1587
- drawerContentsHeader,
1588
- kubernetesObject,
1589
- children
1590
- }) => {
1591
- const classes = useDrawerStyles();
1592
- const [isOpen, setIsOpen] = useState(open != null ? open : false);
1593
- const toggleDrawer = (e, newValue) => {
1594
- e.stopPropagation();
1595
- setIsOpen(newValue);
1596
- };
1597
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(DrawerButton, { onClick: () => setIsOpen(true) }, label), /* @__PURE__ */ React__default.createElement(
1598
- Drawer,
1599
- {
1600
- classes: {
1601
- paper: classes.paper
1602
- },
1603
- anchor: "right",
1604
- open: isOpen,
1605
- onClose: (e) => toggleDrawer(e, false),
1606
- onClick: (event) => event.stopPropagation()
1607
- },
1608
- isOpen && /* @__PURE__ */ React__default.createElement(
1609
- KubernetesDrawerContent,
1610
- {
1611
- header: drawerContentsHeader,
1612
- kubernetesObject,
1613
- children,
1614
- close: () => setIsOpen(false)
1615
- }
1616
- )
1617
- ));
1618
- };
1619
-
1620
- const PodCondition = ({ condition }) => {
1621
- 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({
1622
- locale: "en"
1623
- }), ") - ", condition.message, " "), condition.status === "True" && /* @__PURE__ */ React__default.createElement(StatusOK, null, condition.type, " - (", condition.lastTransitionTime && DateTime.fromISO(condition.lastTransitionTime).toRelative({
1624
- locale: "en"
1625
- }), ")"), condition.status === "Unknown" && /* @__PURE__ */ React__default.createElement(StatusWarning, null, condition.type, " - (", condition.lastTransitionTime && DateTime.fromISO(condition.lastTransitionTime).toRelative({
1626
- locale: "en"
1627
- }), ") ", condition.message));
1628
- };
1629
- const PendingPodContent = ({ pod }) => {
1630
- var _a, _b, _c, _d, _e, _f, _g, _h;
1631
- const startupConditions = [
1632
- (_b = (_a = pod.status) == null ? void 0 : _a.conditions) == null ? void 0 : _b.find((c) => c.type === "PodScheduled"),
1633
- (_d = (_c = pod.status) == null ? void 0 : _c.conditions) == null ? void 0 : _d.find((c) => c.type === "Initialized"),
1634
- (_f = (_e = pod.status) == null ? void 0 : _e.conditions) == null ? void 0 : _f.find((c) => c.type === "ContainersReady"),
1635
- (_h = (_g = pod.status) == null ? void 0 : _g.conditions) == null ? void 0 : _h.find((c) => c.type === "Ready")
1636
- ].filter((c) => !!c);
1637
- 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 }))))));
1638
- };
1639
-
1640
- const useEvents = ({
1641
- involvedObjectName,
1642
- namespace,
1643
- clusterName
1644
- }) => {
1645
- const kubernetesProxyApi = useApi(kubernetesProxyApiRef);
1646
- return useAsync(async () => {
1647
- return await kubernetesProxyApi.getEventsByInvolvedObjectName({
1648
- involvedObjectName,
1649
- namespace,
1650
- clusterName
1651
- });
1652
- }, [involvedObjectName, namespace, clusterName]);
1653
- };
1654
-
1655
- const getAvatarByType = (type) => {
1656
- return /* @__PURE__ */ React__default.createElement(ListItemAvatar, null, /* @__PURE__ */ React__default.createElement(Avatar, null, type === "Warning" ? /* @__PURE__ */ React__default.createElement(WarningIcon, null) : /* @__PURE__ */ React__default.createElement(InfoIcon, null)));
1657
- };
1658
- const EventsContent = ({
1659
- events,
1660
- warningEventsOnly
1661
- }) => {
1662
- if (events.length === 0) {
1663
- return /* @__PURE__ */ React__default.createElement(Typography, null, "No events found");
1664
- }
1665
- return /* @__PURE__ */ React__default.createElement(Container, null, /* @__PURE__ */ React__default.createElement(Grid, null, /* @__PURE__ */ React__default.createElement(List, null, events.filter((event) => {
1666
- if (warningEventsOnly) {
1667
- return event.type === "Warning";
1668
- }
1669
- return true;
1670
- }).map((event) => {
1671
- var _a;
1672
- const timeAgo = event.metadata.creationTimestamp ? DateTime.fromISO(event.metadata.creationTimestamp).toRelative(
1673
- {
1674
- locale: "en"
1675
- }
1676
- ) : "unknown";
1677
- return /* @__PURE__ */ React__default.createElement(ListItem, { key: event.metadata.name }, /* @__PURE__ */ React__default.createElement(Tooltip, { title: `${(_a = event.type) != null ? _a : ""} event` }, getAvatarByType(event.type)), /* @__PURE__ */ React__default.createElement(
1678
- ListItemText,
1679
- {
1680
- primary: `First event ${timeAgo} (count: ${event.count})`,
1681
- secondary: `${event.reason}: ${event.message}`
1682
- }
1683
- ));
1684
- }))));
1685
- };
1686
- const Events = ({
1687
- involvedObjectName,
1688
- namespace,
1689
- clusterName,
1690
- warningEventsOnly
1691
- }) => {
1692
- const { value, error, loading } = useEvents({
1693
- involvedObjectName,
1694
- namespace,
1695
- clusterName
1696
- });
1697
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, error && /* @__PURE__ */ React__default.createElement(
1698
- DismissableBanner,
1699
- {
1700
- ...{
1701
- message: error.message,
1702
- variant: "error",
1703
- fixed: false
1704
- },
1705
- id: "events"
1706
- }
1707
- ), loading && /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rect", width: "100%", height: "100%" }), !loading && value !== void 0 && /* @__PURE__ */ React__default.createElement(EventsContent, { warningEventsOnly, events: value }));
1708
- };
1709
-
1710
- const useStyles$1 = makeStyles(
1711
- (theme) => createStyles({
1712
- closeButton: {
1713
- position: "absolute",
1714
- right: theme.spacing(1),
1715
- top: theme.spacing(1),
1716
- color: theme.palette.grey[500]
1717
- }
1718
- })
1719
- );
1720
- const FixDialog = ({
1721
- open,
1722
- pod,
1723
- error,
1724
- clusterName
1725
- }) => {
1726
- var _a;
1727
- const [isOpen, setOpen] = useState(!!open);
1728
- const classes = useStyles$1();
1729
- const openDialog = () => {
1730
- setOpen(true);
1731
- };
1732
- const closeDialog = () => {
1733
- setOpen(false);
1734
- };
1735
- const pf = error.proposedFix;
1736
- const dialogContent = () => {
1737
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1738
- return /* @__PURE__ */ React__default.createElement(Grid, { container: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6" }, "Detected error:"), /* @__PURE__ */ React__default.createElement(Typography, null, error.message)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6" }, "Cause explanation:"), /* @__PURE__ */ React__default.createElement(Typography, null, (_b = (_a2 = error.proposedFix) == null ? void 0 : _a2.rootCauseExplanation) != null ? _b : "unknown")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6" }, "Fix:"), /* @__PURE__ */ React__default.createElement(Typography, null, /* @__PURE__ */ React__default.createElement("ul", null, ((_d = (_c = error.proposedFix) == null ? void 0 : _c.actions) != null ? _d : []).map((fix, i) => {
1739
- var _a3, _b2;
1740
- return /* @__PURE__ */ React__default.createElement("li", { key: `${(_b2 = (_a3 = pod.metadata) == null ? void 0 : _a3.name) != null ? _b2 : "unknown"}-pf-${i}` }, fix);
1741
- })))), pf && pf.type === "logs" && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6" }, "Crash logs:")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 9 }, /* @__PURE__ */ React__default.createElement(
1742
- PodLogs,
1743
- {
1744
- previous: true,
1745
- containerScope: {
1746
- podName: (_f = (_e = pod.metadata) == null ? void 0 : _e.name) != null ? _f : "unknown",
1747
- podNamespace: (_h = (_g = pod.metadata) == null ? void 0 : _g.namespace) != null ? _h : "unknown",
1748
- cluster: { name: clusterName },
1749
- containerName: pf.container
1750
- }
1751
- }
1752
- ))), pf && pf.type === "events" && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6" }, "Events:")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 9 }, /* @__PURE__ */ React__default.createElement(
1753
- Events,
1754
- {
1755
- warningEventsOnly: true,
1756
- involvedObjectName: (_j = (_i = pod.metadata) == null ? void 0 : _i.name) != null ? _j : "",
1757
- namespace: (_l = (_k = pod.metadata) == null ? void 0 : _k.namespace) != null ? _l : "",
1758
- clusterName
1759
- }
1760
- ))));
1761
- };
1762
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
1763
- Button,
1764
- {
1765
- variant: "outlined",
1766
- "aria-label": "fix issue",
1767
- component: "label",
1768
- onClick: openDialog,
1769
- startIcon: /* @__PURE__ */ React__default.createElement(HelpIcon, null)
1770
- },
1771
- "Help"
1772
- ), /* @__PURE__ */ React__default.createElement(Dialog, { maxWidth: "xl", fullWidth: true, open: isOpen, onClose: closeDialog }, /* @__PURE__ */ React__default.createElement(DialogTitle, { id: "dialog-title" }, (_a = pod.metadata) == null ? void 0 : _a.name, " - ", error.type, /* @__PURE__ */ React__default.createElement(
1773
- IconButton,
1774
- {
1775
- "aria-label": "close",
1776
- className: classes.closeButton,
1777
- onClick: closeDialog
1778
- },
1779
- /* @__PURE__ */ React__default.createElement(CloseIcon, null)
1780
- )), /* @__PURE__ */ React__default.createElement(DialogContent, null, dialogContent()), /* @__PURE__ */ React__default.createElement(DialogActions, null, pf && pf.type === "docs" && /* @__PURE__ */ React__default.createElement(
1781
- LinkButton,
1782
- {
1783
- to: pf.docsLink,
1784
- variant: "outlined",
1785
- startIcon: /* @__PURE__ */ React__default.createElement(OpenInNewIcon, null),
1786
- target: "_blank",
1787
- rel: "noopener"
1788
- },
1789
- "Open docs"
1790
- ))));
1791
- };
1792
-
1793
- const useStyles = makeStyles(
1794
- (_theme) => createStyles({
1795
- root: {
1796
- overflow: "auto"
1797
- },
1798
- list: {
1799
- width: "100%"
1800
- }
1801
- })
1802
- );
1803
- const ErrorList = ({ podAndErrors }) => {
1804
- const classes = useStyles();
1805
- return /* @__PURE__ */ React__default.createElement(Paper, { className: classes.root }, /* @__PURE__ */ React__default.createElement(List, { className: classes.list }, podAndErrors.filter((pae) => pae.errors.length > 0).flatMap((onlyPodWithErrors) => {
1806
- return onlyPodWithErrors.errors.map((error, i) => {
1807
- var _a, _b, _c;
1808
- return /* @__PURE__ */ React__default.createElement(
1809
- React__default.Fragment,
1810
- {
1811
- key: `${(_b = (_a = onlyPodWithErrors.pod.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown"}-eli-${i}`
1812
- },
1813
- i > 0 && /* @__PURE__ */ React__default.createElement(Divider, { key: `error-divider${i}` }),
1814
- /* @__PURE__ */ React__default.createElement(ListItem, null, /* @__PURE__ */ React__default.createElement(Grid, { container: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 9 }, /* @__PURE__ */ React__default.createElement(
1815
- ListItemText,
1816
- {
1817
- primary: error.message,
1818
- secondary: (_c = onlyPodWithErrors.pod.metadata) == null ? void 0 : _c.name
1819
- }
1820
- )), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 3 }, /* @__PURE__ */ React__default.createElement(
1821
- FixDialog,
1822
- {
1823
- pod: onlyPodWithErrors.pod,
1824
- error,
1825
- clusterName: onlyPodWithErrors.cluster.name
1826
- }
1827
- ))))
1828
- );
1829
- });
1830
- })));
1831
- };
1832
-
1833
- const useDrawerContentStyles = makeStyles(
1834
- (_theme) => createStyles({
1835
- header: {
1836
- display: "flex",
1837
- flexDirection: "row",
1838
- justifyContent: "space-between"
1839
- },
1840
- content: {
1841
- height: "80%"
1842
- },
1843
- icon: {
1844
- fontSize: 20
1845
- },
1846
- podoklist: {
1847
- width: "100%",
1848
- maxWidth: 360,
1849
- maxHeight: 360
1850
- }
1851
- })
1852
- );
1853
- function getContainerSpecByName(pod, containerName) {
1854
- var _a;
1855
- return (_a = pod.spec) == null ? void 0 : _a.containers.find((c) => c.name === containerName);
1856
- }
1857
- const PodDrawer = ({ podAndErrors, open }) => {
1858
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1859
- const classes = useDrawerContentStyles();
1860
- const podMetrics = usePodMetrics(podAndErrors.cluster.name, podAndErrors.pod);
1861
- return /* @__PURE__ */ React__default.createElement(
1862
- KubernetesDrawer,
1863
- {
1864
- open,
1865
- 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})`),
1866
- kubernetesObject: podAndErrors.pod,
1867
- label: /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, (_d = (_c = podAndErrors.pod.metadata) == null ? void 0 : _c.name) != null ? _d : "unknown")
1868
- },
1869
- /* @__PURE__ */ React__default.createElement("div", { className: classes.content }, podMetrics && /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, "Resource utilization")), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 6 }, /* @__PURE__ */ React__default.createElement(
1870
- ResourceUtilization,
1871
- {
1872
- title: "CPU requests",
1873
- usage: podMetrics.cpu.currentUsage,
1874
- total: podMetrics.cpu.requestTotal,
1875
- totalFormatted: formatMillicores(podMetrics.cpu.requestTotal)
1876
- }
1877
- ), /* @__PURE__ */ React__default.createElement(
1878
- ResourceUtilization,
1879
- {
1880
- title: "CPU limits",
1881
- usage: podMetrics.cpu.currentUsage,
1882
- total: podMetrics.cpu.limitTotal,
1883
- totalFormatted: formatMillicores(podMetrics.cpu.limitTotal)
1884
- }
1885
- )), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 6 }, /* @__PURE__ */ React__default.createElement(
1886
- ResourceUtilization,
1887
- {
1888
- title: "Memory requests",
1889
- usage: podMetrics.memory.currentUsage,
1890
- total: podMetrics.memory.requestTotal,
1891
- totalFormatted: bytesToMiB(podMetrics.memory.requestTotal)
1892
- }
1893
- ), /* @__PURE__ */ React__default.createElement(
1894
- ResourceUtilization,
1895
- {
1896
- title: "Memory limits",
1897
- usage: podMetrics.memory.currentUsage,
1898
- total: podMetrics.memory.limitTotal,
1899
- totalFormatted: bytesToMiB(podMetrics.memory.limitTotal)
1900
- }
1901
- ))), ((_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(
1902
- (containerStatus, i) => {
1903
- var _a2, _b2, _c2, _d2, _e2, _f2;
1904
- const containerSpec = getContainerSpecByName(
1905
- podAndErrors.pod,
1906
- containerStatus.name
1907
- );
1908
- const containerMetrics = ((_a2 = podMetrics == null ? void 0 : podMetrics.containers) != null ? _a2 : []).find((c) => c.container === containerStatus.name);
1909
- return /* @__PURE__ */ React__default.createElement(
1910
- ContainerCard,
1911
- {
1912
- key: `container-card-${(_b2 = podAndErrors.pod.metadata) == null ? void 0 : _b2.name}-${i}`,
1913
- containerMetrics,
1914
- podScope: {
1915
- podName: (_d2 = (_c2 = podAndErrors.pod.metadata) == null ? void 0 : _c2.name) != null ? _d2 : "unknown",
1916
- podNamespace: (_f2 = (_e2 = podAndErrors.pod.metadata) == null ? void 0 : _e2.namespace) != null ? _f2 : "unknown",
1917
- cluster: podAndErrors.cluster
1918
- },
1919
- containerSpec,
1920
- containerStatus
1921
- }
1922
- );
1923
- }
1924
- ))), podAndErrors.errors.length > 0 && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h5" }, "Errors")), podAndErrors.errors.length > 0 && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(ErrorList, { podAndErrors: [podAndErrors] }))))
1925
- );
1926
- };
1927
-
1928
- const containersReady = (pod) => {
1929
- var _a, _b;
1930
- const containerStatuses2 = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
1931
- const containersReadyItem = containerStatuses2.filter((cs) => cs.ready).length;
1932
- return `${containersReadyItem}/${containerStatuses2.length}`;
1933
- };
1934
- const totalRestarts = (pod) => {
1935
- var _a, _b;
1936
- const containerStatuses2 = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
1937
- return containerStatuses2 == null ? void 0 : containerStatuses2.reduce((a, b) => a + b.restartCount, 0);
1938
- };
1939
- const containerStatuses = (pod) => {
1940
- var _a, _b;
1941
- const containerStatusesItem = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) != null ? _b : [];
1942
- const errors = containerStatusesItem.reduce((accum, next) => {
1943
- if (next.state === void 0) {
1944
- return accum;
1945
- }
1946
- const waiting = next.state.waiting;
1947
- const terminated = next.state.terminated;
1948
- const renderCell = (reason) => {
1949
- var _a2;
1950
- return /* @__PURE__ */ React__default.createElement(Fragment, { key: `${(_a2 = pod.metadata) == null ? void 0 : _a2.name}-${next.name}` }, /* @__PURE__ */ React__default.createElement(
1951
- SubvalueCell,
1952
- {
1953
- value: reason === "Completed" ? /* @__PURE__ */ React__default.createElement(StatusOK, null, "Container: ", next.name) : /* @__PURE__ */ React__default.createElement(StatusError, null, "Container: ", next.name),
1954
- subvalue: reason
1955
- }
1956
- ), /* @__PURE__ */ React__default.createElement("br", null));
1957
- };
1958
- if (waiting) {
1959
- accum.push(renderCell(waiting.reason));
1960
- }
1961
- if (terminated) {
1962
- accum.push(renderCell(terminated.reason));
1963
- }
1964
- return accum;
1965
- }, []);
1966
- if (errors.length === 0) {
1967
- return /* @__PURE__ */ React__default.createElement(StatusOK, null, "OK");
1968
- }
1969
- return errors;
1970
- };
1971
- const renderCondition = (condition) => {
1972
- var _a;
1973
- const status = condition.status;
1974
- if (status === "True") {
1975
- return [condition.type, /* @__PURE__ */ React__default.createElement(StatusOK, null, "True")];
1976
- } else if (status === "False") {
1977
- return [
1978
- condition.type,
1979
- /* @__PURE__ */ React__default.createElement(
1980
- SubvalueCell,
1981
- {
1982
- value: /* @__PURE__ */ React__default.createElement(StatusError, null, "False"),
1983
- subvalue: (_a = condition.message) != null ? _a : ""
1984
- }
1985
- )
1986
- ];
1987
- }
1988
- return [condition.type, /* @__PURE__ */ React__default.createElement(StatusAborted, null)];
1989
- };
1990
- const currentToDeclaredResourceToPerc = (current, resource) => {
1991
- if (Number(resource) === 0)
1992
- return `0%`;
1993
- if (typeof current === "number" && typeof resource === "number") {
1994
- return `${Math.round(current / resource * 100)}%`;
1995
- }
1996
- const numerator = BigInt(
1997
- typeof current === "number" ? Math.round(current) : current
1998
- );
1999
- const denominator = BigInt(
2000
- typeof resource === "number" ? Math.round(resource) : resource
2001
- );
2002
- return `${numerator * BigInt(100) / denominator}%`;
2003
- };
2004
- const podStatusToCpuUtil = (podStatus) => {
2005
- const cpuUtil = podStatus.cpu;
2006
- let currentUsage = cpuUtil.currentUsage;
2007
- if (typeof cpuUtil.currentUsage === "number") {
2008
- currentUsage = cpuUtil.currentUsage / 10;
2009
- }
2010
- return /* @__PURE__ */ React__default.createElement(
2011
- SubvalueCell,
2012
- {
2013
- value: `requests: ${currentToDeclaredResourceToPerc(
2014
- currentUsage,
2015
- cpuUtil.requestTotal
2016
- )} of ${formatMillicores(cpuUtil.requestTotal)}`,
2017
- subvalue: `limits: ${currentToDeclaredResourceToPerc(
2018
- currentUsage,
2019
- cpuUtil.limitTotal
2020
- )} of ${formatMillicores(cpuUtil.limitTotal)}`
2021
- }
2022
- );
2023
- };
2024
- const podStatusToMemoryUtil = (podStatus) => {
2025
- const memUtil = podStatus.memory;
2026
- return /* @__PURE__ */ React__default.createElement(
2027
- SubvalueCell,
2028
- {
2029
- value: `requests: ${currentToDeclaredResourceToPerc(
2030
- memUtil.currentUsage,
2031
- memUtil.requestTotal
2032
- )} of ${bytesToMiB(memUtil.requestTotal)}`,
2033
- subvalue: `limits: ${currentToDeclaredResourceToPerc(
2034
- memUtil.currentUsage,
2035
- memUtil.limitTotal
2036
- )} of ${bytesToMiB(memUtil.limitTotal)}`
2037
- }
2038
- );
2039
- };
2040
-
2041
- const READY_COLUMNS = "READY";
2042
- const RESOURCE_COLUMNS = "RESOURCE";
2043
- const READY = [
2044
- {
2045
- title: "containers ready",
2046
- align: "center",
2047
- render: containersReady,
2048
- width: "auto"
2049
- },
2050
- {
2051
- title: "total restarts",
2052
- align: "center",
2053
- render: totalRestarts,
2054
- type: "numeric",
2055
- width: "auto"
2056
- }
2057
- ];
2058
- const PodDrawerTrigger = ({ pod }) => {
2059
- const errors = useMatchingErrors({
2060
- kind: "Pod",
2061
- apiVersion: "v1",
2062
- metadata: pod.metadata
2063
- });
2064
- return /* @__PURE__ */ React__default.createElement(
2065
- PodDrawer,
2066
- {
2067
- podAndErrors: {
2068
- pod,
2069
- cluster: useContext(ClusterContext),
2070
- errors
2071
- }
2072
- }
2073
- );
2074
- };
2075
- const Cpu = ({ clusterName, pod }) => {
2076
- const metrics = usePodMetrics(clusterName, pod);
2077
- if (!metrics) {
2078
- return /* @__PURE__ */ React__default.createElement(Typography, null, "unknown");
2079
- }
2080
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, podStatusToCpuUtil(metrics));
2081
- };
2082
- const Memory = ({ clusterName, pod }) => {
2083
- const metrics = usePodMetrics(clusterName, pod);
2084
- if (!metrics) {
2085
- return /* @__PURE__ */ React__default.createElement(Typography, null, "unknown");
2086
- }
2087
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, podStatusToMemoryUtil(metrics));
2088
- };
2089
- const PodsTable = ({ pods, extraColumns = [] }) => {
2090
- const cluster = useContext(ClusterContext);
2091
- const defaultColumns = [
2092
- {
2093
- title: "ID",
2094
- field: "metadata.uid",
2095
- hidden: true
2096
- },
2097
- {
2098
- title: "name",
2099
- highlight: true,
2100
- render: (pod) => {
2101
- return /* @__PURE__ */ React__default.createElement(PodDrawerTrigger, { pod });
2102
- }
2103
- },
2104
- {
2105
- title: "phase",
2106
- render: (pod) => {
2107
- var _a, _b;
2108
- return (_b = (_a = pod.status) == null ? void 0 : _a.phase) != null ? _b : "unknown";
2109
- },
2110
- width: "auto"
2111
- },
2112
- {
2113
- title: "status",
2114
- render: containerStatuses
2115
- }
2116
- ];
2117
- const columns = [...defaultColumns];
2118
- if (extraColumns.includes(READY_COLUMNS)) {
2119
- columns.push(...READY);
2120
- }
2121
- if (extraColumns.includes(RESOURCE_COLUMNS)) {
2122
- const resourceColumns = [
2123
- {
2124
- title: "CPU usage %",
2125
- render: (pod) => {
2126
- return /* @__PURE__ */ React__default.createElement(Cpu, { clusterName: cluster.name, pod });
2127
- },
2128
- width: "auto"
2129
- },
2130
- {
2131
- title: "Memory usage %",
2132
- render: (pod) => {
2133
- return /* @__PURE__ */ React__default.createElement(Memory, { clusterName: cluster.name, pod });
2134
- },
2135
- width: "auto"
2136
- }
2137
- ];
2138
- columns.push(...resourceColumns);
2139
- }
2140
- const tableStyle = {
2141
- minWidth: "0",
2142
- width: "100%"
2143
- };
2144
- return /* @__PURE__ */ React__default.createElement("div", { style: tableStyle }, /* @__PURE__ */ React__default.createElement(
2145
- Table,
2146
- {
2147
- options: { paging: true, search: false, emptyRowsWhenPaging: false },
2148
- data: pods.map((pod) => {
2149
- var _a;
2150
- return {
2151
- ...pod,
2152
- id: (_a = pod == null ? void 0 : pod.metadata) == null ? void 0 : _a.uid
2153
- };
2154
- }),
2155
- columns
2156
- }
2157
- ));
2158
- };
2159
-
2160
- const DeploymentDrawer = ({
2161
- deployment,
2162
- expanded
2163
- }) => {
2164
- var _a, _b, _c;
2165
- const namespace = (_a = deployment.metadata) == null ? void 0 : _a.namespace;
2166
- return /* @__PURE__ */ React__default.createElement(
2167
- KubernetesStructuredMetadataTableDrawer,
2168
- {
2169
- object: deployment,
2170
- expanded,
2171
- kind: "Deployment",
2172
- renderObject: (deploymentObj) => {
2173
- var _a2, _b2, _c2, _d, _e, _f, _g, _h;
2174
- const conditions = ((_b2 = (_a2 = deploymentObj.status) == null ? void 0 : _a2.conditions) != null ? _b2 : []).map(renderCondition).reduce((accum, next) => {
2175
- accum[next[0]] = next[1];
2176
- return accum;
2177
- }, {});
2178
- return {
2179
- strategy: (_d = (_c2 = deploymentObj.spec) == null ? void 0 : _c2.strategy) != null ? _d : "???",
2180
- minReadySeconds: (_f = (_e = deploymentObj.spec) == null ? void 0 : _e.minReadySeconds) != null ? _f : "???",
2181
- progressDeadlineSeconds: (_h = (_g = deploymentObj.spec) == null ? void 0 : _g.progressDeadlineSeconds) != null ? _h : "???",
2182
- ...conditions
2183
- };
2184
- }
2185
- },
2186
- /* @__PURE__ */ React__default.createElement(
2187
- Grid,
2188
- {
2189
- container: true,
2190
- direction: "column",
2191
- justifyContent: "flex-start",
2192
- alignItems: "flex-start",
2193
- spacing: 0
2194
- },
2195
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_c = (_b = deployment.metadata) == null ? void 0 : _b.name) != null ? _c : "unknown object")),
2196
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Deployment")),
2197
- namespace && /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Chip, { size: "small", label: `namespace: ${namespace}` }))
2198
- )
2199
- );
2200
- };
2201
-
2202
- const HorizontalPodAutoscalerDrawer = (props) => {
2203
- const { hpa, expanded, children } = props;
2204
- return /* @__PURE__ */ React__default.createElement(
2205
- KubernetesStructuredMetadataTableDrawer,
2206
- {
2207
- kind: "HorizontalPodAutoscaler",
2208
- object: hpa,
2209
- expanded,
2210
- renderObject: (hpaObject) => {
2211
- var _a, _b, _c, _d, _e, _f;
2212
- return {
2213
- targetCPUUtilizationPercentage: (_a = hpaObject.spec) == null ? void 0 : _a.targetCPUUtilizationPercentage,
2214
- currentCPUUtilizationPercentage: (_b = hpaObject.status) == null ? void 0 : _b.currentCPUUtilizationPercentage,
2215
- minReplicas: (_c = hpaObject.spec) == null ? void 0 : _c.minReplicas,
2216
- maxReplicas: (_d = hpaObject.spec) == null ? void 0 : _d.maxReplicas,
2217
- currentReplicas: (_e = hpaObject.status) == null ? void 0 : _e.currentReplicas,
2218
- desiredReplicas: (_f = hpaObject.status) == null ? void 0 : _f.desiredReplicas
2219
- };
2220
- }
2221
- },
2222
- children
2223
- );
2224
- };
2225
-
2226
- function getOwnedResources(potentialOwner, possiblyOwned) {
2227
- return possiblyOwned.filter(
2228
- (p) => {
2229
- var _a, _b, _c;
2230
- return (_c = (_b = (_a = p.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some(
2231
- (o) => {
2232
- var _a2;
2233
- return o.uid === ((_a2 = potentialOwner.metadata) == null ? void 0 : _a2.uid);
2234
- }
2235
- )) != null ? _c : false;
2236
- }
2237
- );
2238
- }
2239
- const getOwnedPodsThroughReplicaSets = (potentialOwner, replicaSets, pods) => {
2240
- return getOwnedResources(
2241
- potentialOwner,
2242
- replicaSets.filter((rs) => rs.status && rs.status.replicas > 0)
2243
- ).reduce((accum, rs) => {
2244
- return accum.concat(getOwnedResources(rs, pods));
2245
- }, []);
2246
- };
2247
- const getMatchingHpa = (owner, hpas) => {
2248
- return hpas.find((hpa) => {
2249
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2250
- 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");
2251
- });
2252
- };
2253
-
2254
- const DeploymentSummary = ({
2255
- deployment,
2256
- numberOfCurrentPods,
2257
- numberOfPodsWithErrors,
2258
- hpa
2259
- }) => {
2260
- var _a, _b, _c, _d, _e, _f, _g, _h;
2261
- return /* @__PURE__ */ React__default.createElement(
2262
- Grid,
2263
- {
2264
- container: true,
2265
- direction: "row",
2266
- justifyContent: "space-between",
2267
- alignItems: "center",
2268
- spacing: 0
2269
- },
2270
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 4, item: true }, /* @__PURE__ */ React__default.createElement(DeploymentDrawer, { deployment })),
2271
- hpa && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 4 }, /* @__PURE__ */ React__default.createElement(HorizontalPodAutoscalerDrawer, { hpa }, /* @__PURE__ */ React__default.createElement(
2272
- Grid,
2273
- {
2274
- item: true,
2275
- container: true,
2276
- direction: "column",
2277
- justifyContent: "flex-start",
2278
- alignItems: "flex-start",
2279
- spacing: 0
2280
- },
2281
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "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 : "?")),
2282
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "current CPU usage:", " ", (_f = (_e = hpa.status) == null ? void 0 : _e.currentCPUUtilizationPercentage) != null ? _f : "?", "%")),
2283
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "target CPU usage:", " ", (_h = (_g = hpa.spec) == null ? void 0 : _g.targetCPUUtilizationPercentage) != null ? _h : "?", "%"))
2284
- ))),
2285
- /* @__PURE__ */ React__default.createElement(
2286
- Grid,
2287
- {
2288
- item: true,
2289
- container: true,
2290
- xs: 4,
2291
- direction: "column",
2292
- justifyContent: "flex-start",
2293
- alignItems: "flex-end",
2294
- spacing: 0
2295
- },
2296
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(StatusOK, null, numberOfCurrentPods, " pods")),
2297
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, 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"))
2298
- )
2299
- );
2300
- };
2301
- const DeploymentAccordion = ({
2302
- deployment,
2303
- ownedPods,
2304
- matchingHpa
2305
- }) => {
2306
- const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
2307
- const podsWithErrors = ownedPods.filter(
2308
- (p) => {
2309
- var _a, _b;
2310
- return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
2311
- }
2312
- );
2313
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, variant: "outlined" }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(
2314
- DeploymentSummary,
2315
- {
2316
- deployment,
2317
- numberOfCurrentPods: ownedPods.length,
2318
- numberOfPodsWithErrors: podsWithErrors.length,
2319
- hpa: matchingHpa
2320
- }
2321
- )), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(
2322
- PodsTable,
2323
- {
2324
- pods: ownedPods,
2325
- extraColumns: [READY_COLUMNS, RESOURCE_COLUMNS]
2326
- }
2327
- )));
2328
- };
2329
- const DeploymentsAccordions = ({}) => {
2330
- const groupedResponses = useContext(GroupedResponsesContext);
2331
- return /* @__PURE__ */ React__default.createElement(
2332
- Grid,
2333
- {
2334
- container: true,
2335
- direction: "column",
2336
- justifyContent: "flex-start",
2337
- alignItems: "flex-start"
2338
- },
2339
- groupedResponses.deployments.map((deployment, i) => {
2340
- var _a, _b;
2341
- return /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
2342
- DeploymentAccordion,
2343
- {
2344
- matchingHpa: getMatchingHpa(
2345
- {
2346
- name: (_a = deployment.metadata) == null ? void 0 : _a.name,
2347
- namespace: (_b = deployment.metadata) == null ? void 0 : _b.namespace,
2348
- kind: "deployment"
2349
- },
2350
- groupedResponses.horizontalPodAutoscalers
2351
- ),
2352
- ownedPods: getOwnedPodsThroughReplicaSets(
2353
- deployment,
2354
- groupedResponses.replicaSets,
2355
- groupedResponses.pods
2356
- ),
2357
- deployment
2358
- }
2359
- )));
2360
- })
2361
- );
2362
- };
2363
-
2364
- const StatefulSetDrawer = ({
2365
- statefulset,
2366
- expanded
2367
- }) => {
2368
- var _a, _b, _c;
2369
- const namespace = (_a = statefulset.metadata) == null ? void 0 : _a.namespace;
2370
- return /* @__PURE__ */ React__default.createElement(
2371
- KubernetesStructuredMetadataTableDrawer,
2372
- {
2373
- object: statefulset,
2374
- expanded,
2375
- kind: "StatefulSet",
2376
- renderObject: (statefulsetObj) => {
2377
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l;
2378
- const conditions = ((_b2 = (_a2 = statefulsetObj.status) == null ? void 0 : _a2.conditions) != null ? _b2 : []).map(renderCondition).reduce((accum, next) => {
2379
- accum[next[0]] = next[1];
2380
- return accum;
2381
- }, {});
2382
- return {
2383
- updateStrategy: (_d = (_c2 = statefulset.spec) == null ? void 0 : _c2.updateStrategy) != null ? _d : "???",
2384
- podManagementPolicy: (_f = (_e = statefulset.spec) == null ? void 0 : _e.podManagementPolicy) != null ? _f : "???",
2385
- serviceName: (_h = (_g = statefulset.spec) == null ? void 0 : _g.serviceName) != null ? _h : "???",
2386
- selector: (_j = (_i = statefulset.spec) == null ? void 0 : _i.selector) != null ? _j : "???",
2387
- revisionHistoryLimit: (_l = (_k = statefulset.spec) == null ? void 0 : _k.revisionHistoryLimit) != null ? _l : "???",
2388
- ...conditions
2389
- };
2390
- }
2391
- },
2392
- /* @__PURE__ */ React__default.createElement(
2393
- Grid,
2394
- {
2395
- container: true,
2396
- direction: "column",
2397
- justifyContent: "flex-start",
2398
- alignItems: "flex-start",
2399
- spacing: 0
2400
- },
2401
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_c = (_b = statefulset.metadata) == null ? void 0 : _b.name) != null ? _c : "unknown object")),
2402
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Stateful Set")),
2403
- namespace && /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Chip, { size: "small", label: `namespace: ${namespace}` }))
2404
- )
2405
- );
2406
- };
2407
-
2408
- const StatefulSetSummary = ({
2409
- statefulset,
2410
- numberOfCurrentPods,
2411
- numberOfPodsWithErrors,
2412
- hpa
2413
- }) => {
2414
- var _a, _b, _c, _d, _e, _f, _g, _h;
2415
- return /* @__PURE__ */ React__default.createElement(
2416
- Grid,
2417
- {
2418
- container: true,
2419
- direction: "row",
2420
- justifyContent: "space-between",
2421
- alignItems: "center",
2422
- spacing: 0
2423
- },
2424
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 6, item: true }, /* @__PURE__ */ React__default.createElement(StatefulSetDrawer, { statefulset })),
2425
- hpa && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 3 }, /* @__PURE__ */ React__default.createElement(HorizontalPodAutoscalerDrawer, { hpa }, /* @__PURE__ */ React__default.createElement(
2426
- Grid,
2427
- {
2428
- item: true,
2429
- container: true,
2430
- direction: "column",
2431
- justifyContent: "flex-start",
2432
- alignItems: "flex-start",
2433
- spacing: 0
2434
- },
2435
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "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 : "?")),
2436
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "current CPU usage:", " ", (_f = (_e = hpa.status) == null ? void 0 : _e.currentCPUUtilizationPercentage) != null ? _f : "?", "%")),
2437
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "target CPU usage:", " ", (_h = (_g = hpa.spec) == null ? void 0 : _g.targetCPUUtilizationPercentage) != null ? _h : "?", "%"))
2438
- ))),
2439
- /* @__PURE__ */ React__default.createElement(
2440
- Grid,
2441
- {
2442
- item: true,
2443
- container: true,
2444
- xs: 3,
2445
- direction: "column",
2446
- justifyContent: "flex-start",
2447
- alignItems: "flex-start",
2448
- spacing: 0
2449
- },
2450
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(StatusOK, null, numberOfCurrentPods, " pods")),
2451
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, 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"))
2452
- )
2453
- );
2454
- };
2455
- const StatefulSetAccordion = ({
2456
- statefulset,
2457
- ownedPods,
2458
- matchingHpa
2459
- }) => {
2460
- const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
2461
- const podsWithErrors = ownedPods.filter(
2462
- (p) => {
2463
- var _a, _b;
2464
- return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
2465
- }
2466
- );
2467
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, variant: "outlined" }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(
2468
- StatefulSetSummary,
2469
- {
2470
- statefulset,
2471
- numberOfCurrentPods: ownedPods.length,
2472
- numberOfPodsWithErrors: podsWithErrors.length,
2473
- hpa: matchingHpa
2474
- }
2475
- )), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(
2476
- PodsTable,
2477
- {
2478
- pods: ownedPods,
2479
- extraColumns: [READY_COLUMNS, RESOURCE_COLUMNS]
2480
- }
2481
- )));
2482
- };
2483
- const StatefulSetsAccordions = ({}) => {
2484
- const groupedResponses = useContext(GroupedResponsesContext);
2485
- return /* @__PURE__ */ React__default.createElement(
2486
- Grid,
2487
- {
2488
- container: true,
2489
- direction: "column",
2490
- justifyContent: "flex-start",
2491
- alignItems: "flex-start"
2492
- },
2493
- groupedResponses.statefulsets.map((statefulset, i) => {
2494
- var _a, _b;
2495
- return /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
2496
- StatefulSetAccordion,
2497
- {
2498
- matchingHpa: getMatchingHpa(
2499
- {
2500
- name: (_a = statefulset.metadata) == null ? void 0 : _a.name,
2501
- namespace: (_b = statefulset.metadata) == null ? void 0 : _b.namespace,
2502
- kind: "statefulset"
2503
- },
2504
- groupedResponses.horizontalPodAutoscalers
2505
- ),
2506
- ownedPods: getOwnedResources(statefulset, groupedResponses.pods),
2507
- statefulset
2508
- }
2509
- )));
2510
- })
2511
- );
2512
- };
2513
-
2514
- const IngressDrawer = ({
2515
- ingress,
2516
- expanded
2517
- }) => {
2518
- var _a, _b;
2519
- return /* @__PURE__ */ React__default.createElement(
2520
- KubernetesStructuredMetadataTableDrawer,
2521
- {
2522
- object: ingress,
2523
- expanded,
2524
- kind: "Ingress",
2525
- renderObject: (ingressObject) => {
2526
- return ingressObject.spec || {};
2527
- }
2528
- },
2529
- /* @__PURE__ */ React__default.createElement(
2530
- Grid,
2531
- {
2532
- container: true,
2533
- direction: "column",
2534
- justifyContent: "flex-start",
2535
- alignItems: "flex-start",
2536
- spacing: 0
2537
- },
2538
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_b = (_a = ingress.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown object")),
2539
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Ingress"))
2540
- )
2541
- );
2542
- };
2543
-
2544
- const IngressSummary = ({ ingress }) => {
2545
- return /* @__PURE__ */ React__default.createElement(
2546
- Grid,
2547
- {
2548
- container: true,
2549
- direction: "row",
2550
- justifyContent: "flex-start",
2551
- alignItems: "center"
2552
- },
2553
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 12, item: true }, /* @__PURE__ */ React__default.createElement(IngressDrawer, { ingress }))
2554
- );
2555
- };
2556
- const IngressCard = ({ ingress }) => {
2557
- return /* @__PURE__ */ React__default.createElement(
2558
- StructuredMetadataTable,
2559
- {
2560
- metadata: {
2561
- ...ingress.spec
2562
- }
2563
- }
2564
- );
2565
- };
2566
- const IngressAccordion = ({ ingress }) => {
2567
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true } }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(IngressSummary, { ingress })), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(IngressCard, { ingress })));
2568
- };
2569
- const IngressesAccordions = ({}) => {
2570
- const groupedResponses = useContext(GroupedResponsesContext);
2571
- return /* @__PURE__ */ React__default.createElement(
2572
- Grid,
2573
- {
2574
- container: true,
2575
- direction: "row",
2576
- justifyContent: "flex-start",
2577
- alignItems: "flex-start"
2578
- },
2579
- groupedResponses.ingresses.map((ingress, i) => /* @__PURE__ */ React__default.createElement(Grid, { item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(IngressAccordion, { ingress })))
2580
- );
2581
- };
2582
-
2583
- const ServiceDrawer = ({
2584
- service,
2585
- expanded
2586
- }) => {
2587
- var _a, _b;
2588
- return /* @__PURE__ */ React__default.createElement(
2589
- KubernetesStructuredMetadataTableDrawer,
2590
- {
2591
- object: service,
2592
- expanded,
2593
- kind: "Service",
2594
- renderObject: (serviceObject) => {
2595
- return serviceObject.spec || {};
2596
- }
2597
- },
2598
- /* @__PURE__ */ React__default.createElement(
2599
- Grid,
2600
- {
2601
- container: true,
2602
- direction: "column",
2603
- justifyContent: "flex-start",
2604
- alignItems: "flex-start",
2605
- spacing: 0
2606
- },
2607
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_b = (_a = service.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown object")),
2608
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Service"))
2609
- )
2610
- );
2611
- };
2612
-
2613
- const ServiceSummary = ({ service }) => {
2614
- var _a, _b;
2615
- return /* @__PURE__ */ React__default.createElement(
2616
- Grid,
2617
- {
2618
- container: true,
2619
- direction: "row",
2620
- justifyContent: "space-between",
2621
- alignItems: "center",
2622
- spacing: 0
2623
- },
2624
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 8, item: true }, /* @__PURE__ */ React__default.createElement(ServiceDrawer, { service })),
2625
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "Type: ", (_b = (_a = service.spec) == null ? void 0 : _a.type) != null ? _b : "?"))
2626
- );
2627
- };
2628
- const ServiceCard = ({ service }) => {
2629
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2630
- const metadata = {};
2631
- if ((_d = (_c = (_b = (_a = service.status) == null ? void 0 : _a.loadBalancer) == null ? void 0 : _b.ingress) == null ? void 0 : _c.length) != null ? _d : -1 > 0) {
2632
- metadata.loadbalancer = (_e = service.status) == null ? void 0 : _e.loadBalancer;
2633
- }
2634
- if (((_f = service.spec) == null ? void 0 : _f.type) === "ClusterIP") {
2635
- metadata.clusterIP = service.spec.clusterIP;
2636
- }
2637
- if (((_g = service.spec) == null ? void 0 : _g.type) === "ExternalName") {
2638
- metadata.externalName = service.spec.externalName;
2639
- }
2640
- return /* @__PURE__ */ React__default.createElement(
2641
- StructuredMetadataTable,
2642
- {
2643
- metadata: {
2644
- type: (_h = service.spec) == null ? void 0 : _h.type,
2645
- ports: (_i = service.spec) == null ? void 0 : _i.ports,
2646
- ...metadata
2647
- }
2648
- }
2649
- );
2650
- };
2651
- const ServiceAccordion = ({ service }) => {
2652
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, variant: "outlined" }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(ServiceSummary, { service })), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(ServiceCard, { service })));
2653
- };
2654
- const ServicesAccordions = ({}) => {
2655
- const groupedResponses = useContext(GroupedResponsesContext);
2656
- return /* @__PURE__ */ React__default.createElement(
2657
- Grid,
2658
- {
2659
- container: true,
2660
- direction: "row",
2661
- justifyContent: "flex-start",
2662
- alignItems: "flex-start"
2663
- },
2664
- groupedResponses.services.map((service, i) => /* @__PURE__ */ React__default.createElement(Grid, { item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(ServiceAccordion, { service })))
2665
- );
2666
- };
2667
-
2668
- const JobDrawer = ({
2669
- job,
2670
- expanded
2671
- }) => {
2672
- var _a, _b;
2673
- return /* @__PURE__ */ React__default.createElement(
2674
- KubernetesStructuredMetadataTableDrawer,
2675
- {
2676
- object: job,
2677
- expanded,
2678
- kind: "Job",
2679
- renderObject: (jobObj) => {
2680
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
2681
- return {
2682
- parallelism: (_b2 = (_a2 = jobObj.spec) == null ? void 0 : _a2.parallelism) != null ? _b2 : "???",
2683
- completions: (_d = (_c = jobObj.spec) == null ? void 0 : _c.completions) != null ? _d : "???",
2684
- backoffLimit: (_f = (_e = jobObj.spec) == null ? void 0 : _e.backoffLimit) != null ? _f : "???",
2685
- startTime: (_h = (_g = jobObj.status) == null ? void 0 : _g.startTime) != null ? _h : "???"
2686
- };
2687
- }
2688
- },
2689
- /* @__PURE__ */ React__default.createElement(
2690
- Grid,
2691
- {
2692
- container: true,
2693
- direction: "column",
2694
- justifyContent: "flex-start",
2695
- alignItems: "flex-start",
2696
- spacing: 0
2697
- },
2698
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_b = (_a = job.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown object")),
2699
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Job"))
2700
- )
2701
- );
2702
- };
2703
-
2704
- const JobSummary = ({ job }) => {
2705
- var _a, _b, _c, _d, _e, _f;
2706
- return /* @__PURE__ */ React__default.createElement(
2707
- Grid,
2708
- {
2709
- container: true,
2710
- direction: "row",
2711
- justifyContent: "space-between",
2712
- alignItems: "center",
2713
- spacing: 0
2714
- },
2715
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 6, item: true }, /* @__PURE__ */ React__default.createElement(JobDrawer, { job })),
2716
- /* @__PURE__ */ React__default.createElement(
2717
- Grid,
2718
- {
2719
- item: true,
2720
- container: true,
2721
- xs: 6,
2722
- direction: "column",
2723
- justifyContent: "flex-start",
2724
- alignItems: "flex-end",
2725
- spacing: 0
2726
- },
2727
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, ((_a = job.status) == null ? void 0 : _a.succeeded) && /* @__PURE__ */ React__default.createElement(StatusOK, null, "Succeeded"), ((_b = job.status) == null ? void 0 : _b.active) && /* @__PURE__ */ React__default.createElement(StatusPending, null, "Running"), ((_c = job.status) == null ? void 0 : _c.failed) && /* @__PURE__ */ React__default.createElement(StatusError, null, "Failed")),
2728
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, "Start time: ", (_e = (_d = job.status) == null ? void 0 : _d.startTime) == null ? void 0 : _e.toString()),
2729
- ((_f = job.status) == null ? void 0 : _f.completionTime) && /* @__PURE__ */ React__default.createElement(Grid, { item: true }, "Completion time: ", job.status.completionTime.toString())
2730
- )
2731
- );
2732
- };
2733
- const JobAccordion = ({ job, ownedPods }) => {
2734
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, variant: "outlined" }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(JobSummary, { job })), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(PodsTable, { pods: ownedPods })));
2735
- };
2736
- const JobsAccordions = ({ jobs }) => {
2737
- const groupedResponses = useContext(GroupedResponsesContext);
2738
- return /* @__PURE__ */ React__default.createElement(
2739
- Grid,
2740
- {
2741
- container: true,
2742
- direction: "column",
2743
- justifyContent: "flex-start",
2744
- alignItems: "flex-start"
2745
- },
2746
- jobs.map((job, i) => /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
2747
- JobAccordion,
2748
- {
2749
- ownedPods: getOwnedResources(job, groupedResponses.pods),
2750
- job
2751
- }
2752
- ))))
2753
- );
2754
- };
2755
-
2756
- const CronJobDrawer = ({
2757
- cronJob,
2758
- expanded
2759
- }) => {
2760
- var _a, _b, _c;
2761
- const namespace = (_a = cronJob.metadata) == null ? void 0 : _a.namespace;
2762
- return /* @__PURE__ */ React__default.createElement(
2763
- KubernetesStructuredMetadataTableDrawer,
2764
- {
2765
- object: cronJob,
2766
- expanded,
2767
- kind: "CronJob",
2768
- renderObject: (cronJobObj) => {
2769
- var _a2, _b2, _c2, _d, _e, _f, _g, _h;
2770
- return {
2771
- schedule: (_b2 = (_a2 = cronJobObj.spec) == null ? void 0 : _a2.schedule) != null ? _b2 : "???",
2772
- startingDeadlineSeconds: (_d = (_c2 = cronJobObj.spec) == null ? void 0 : _c2.startingDeadlineSeconds) != null ? _d : "???",
2773
- concurrencyPolicy: (_f = (_e = cronJobObj.spec) == null ? void 0 : _e.concurrencyPolicy) != null ? _f : "???",
2774
- lastScheduleTime: (_h = (_g = cronJobObj.status) == null ? void 0 : _g.lastScheduleTime) != null ? _h : "???"
2775
- };
2776
- }
2777
- },
2778
- /* @__PURE__ */ React__default.createElement(
2779
- Grid,
2780
- {
2781
- container: true,
2782
- direction: "column",
2783
- justifyContent: "flex-start",
2784
- alignItems: "flex-start",
2785
- spacing: 0
2786
- },
2787
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_c = (_b = cronJob.metadata) == null ? void 0 : _b.name) != null ? _c : "unknown object")),
2788
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "CronJob")),
2789
- namespace && /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Chip, { size: "small", label: `namespace: ${namespace}` }))
2790
- )
2791
- );
2792
- };
2793
-
2794
- const k8sCronAliases = /* @__PURE__ */ new Map([
2795
- ["@yearly", "0 0 1 1 *"],
2796
- ["@annually", "0 0 1 1 *"],
2797
- ["@monthly", "0 0 1 * *"],
2798
- ["@weekly", "0 0 * * 0"],
2799
- ["@daily", "0 0 * * *"],
2800
- ["@midnight", "0 0 * * *"],
2801
- ["@hourly", "0 * * * *"]
2802
- ]);
2803
- const humanizeCron = (schedule) => {
2804
- const deAliasedSchedule = k8sCronAliases.get(schedule) || schedule;
2805
- try {
2806
- return cronstrue.toString(deAliasedSchedule);
2807
- } catch (e) {
2808
- return deAliasedSchedule;
2809
- }
2810
- };
2811
-
2812
- const CronJobSummary = ({ cronJob }) => {
2813
- var _a, _b;
2814
- return /* @__PURE__ */ React__default.createElement(
2815
- Grid,
2816
- {
2817
- container: true,
2818
- direction: "row",
2819
- justifyContent: "space-between",
2820
- alignItems: "center",
2821
- spacing: 0
2822
- },
2823
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 6, item: true }, /* @__PURE__ */ React__default.createElement(CronJobDrawer, { cronJob })),
2824
- /* @__PURE__ */ React__default.createElement(
2825
- Grid,
2826
- {
2827
- item: true,
2828
- container: true,
2829
- xs: 6,
2830
- direction: "column",
2831
- justifyContent: "flex-start",
2832
- alignItems: "flex-end",
2833
- spacing: 0
2834
- },
2835
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, ((_a = cronJob.spec) == null ? void 0 : _a.suspend) ? /* @__PURE__ */ React__default.createElement(StatusError, null, "Suspended") : /* @__PURE__ */ React__default.createElement(StatusOK, null, "Active")),
2836
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, "Schedule:", " ", ((_b = cronJob.spec) == null ? void 0 : _b.schedule) ? `${cronJob.spec.schedule} (${humanizeCron(
2837
- cronJob.spec.schedule
2838
- )})` : "N/A"))
2839
- )
2840
- );
2841
- };
2842
- const CronJobAccordion = ({ cronJob, ownedJobs }) => {
2843
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, variant: "outlined" }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(CronJobSummary, { cronJob })), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(JobsAccordions, { jobs: ownedJobs.reverse() })));
2844
- };
2845
- const CronJobsAccordions = ({}) => {
2846
- const groupedResponses = useContext(GroupedResponsesContext);
2847
- return /* @__PURE__ */ React__default.createElement(
2848
- Grid,
2849
- {
2850
- container: true,
2851
- direction: "column",
2852
- justifyContent: "flex-start",
2853
- alignItems: "flex-start"
2854
- },
2855
- groupedResponses.cronJobs.map((cronJob, i) => /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
2856
- CronJobAccordion,
2857
- {
2858
- ownedJobs: getOwnedResources(cronJob, groupedResponses.jobs),
2859
- cronJob
2860
- }
2861
- ))))
2862
- );
2863
- };
2864
-
2865
- const RolloutDrawer = ({
2866
- rollout,
2867
- expanded
2868
- }) => {
2869
- var _a, _b;
2870
- return /* @__PURE__ */ React__default.createElement(
2871
- KubernetesStructuredMetadataTableDrawer,
2872
- {
2873
- object: rollout,
2874
- expanded,
2875
- kind: "Rollout",
2876
- renderObject: () => ({})
2877
- },
2878
- /* @__PURE__ */ React__default.createElement(
2879
- Grid,
2880
- {
2881
- container: true,
2882
- direction: "column",
2883
- justifyContent: "flex-start",
2884
- alignItems: "flex-start",
2885
- spacing: 0
2886
- },
2887
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_b = (_a = rollout.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown object")),
2888
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Rollout"))
2889
- )
2890
- );
2891
- };
2892
-
2893
- const isSetWeightStep = (step) => step.hasOwnProperty("setWeight");
2894
- const isPauseStep = (step) => step.hasOwnProperty("pause");
2895
- const isAnalysisStep = (step) => step.hasOwnProperty("analysis");
2896
- const createLabelForStep = (step) => {
2897
- if (isSetWeightStep(step)) {
2898
- return `setWeight ${step.setWeight}%`;
2899
- } else if (isPauseStep(step)) {
2900
- return step.pause.duration === void 0 ? "infinite pause" : `pause for ${step.pause.duration}`;
2901
- } else if (isAnalysisStep(step)) {
2902
- return /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(Typography, { paragraph: true }, "analysis templates:"), step.analysis.templates.map((t, i) => /* @__PURE__ */ React__default.createElement(Typography, { paragraph: true, key: i }, `${t.templateName}${t.clusterScope ? " (cluster scoped)" : ""}`)));
2903
- }
2904
- return "unknown step";
2905
- };
2906
- const StepsProgress = ({
2907
- currentStepIndex,
2908
- aborted,
2909
- steps
2910
- }) => {
2911
- const activeStepIndex = currentStepIndex >= steps.length ? currentStepIndex + 1 : currentStepIndex;
2912
- return /* @__PURE__ */ React__default.createElement(Stepper, { activeStep: aborted ? -1 : activeStepIndex, alternativeLabel: true }, steps.map((step, i) => /* @__PURE__ */ React__default.createElement(Step, { key: i }, /* @__PURE__ */ React__default.createElement(StepLabel, { "data-testid": `step-${i}` }, createLabelForStep(step)))).concat(
2913
- /* @__PURE__ */ React__default.createElement(Step, { key: "-1" }, /* @__PURE__ */ React__default.createElement(StepLabel, { "data-testid": "step--1" }, "Canary promoted"))
2914
- ));
2915
- };
2916
-
2917
- const AbortedTitle = /* @__PURE__ */ React__default.createElement(
2918
- "div",
2919
- {
2920
- style: {
2921
- display: "flex",
2922
- alignItems: "center",
2923
- flexWrap: "wrap"
2924
- }
2925
- },
2926
- /* @__PURE__ */ React__default.createElement(ErrorOutlineIcon, null),
2927
- /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, "Aborted")
2928
- );
2929
- const findAbortedMessage = (rollout) => {
2930
- var _a, _b, _c;
2931
- return (_c = (_b = (_a = rollout.status) == null ? void 0 : _a.conditions) == null ? void 0 : _b.find(
2932
- (c) => c.type === "Progressing" && c.status === "False" && c.reason === "RolloutAborted"
2933
- )) == null ? void 0 : _c.message;
2934
- };
2935
- const RolloutSummary = ({
2936
- rollout,
2937
- numberOfCurrentPods,
2938
- numberOfPodsWithErrors,
2939
- hpa
2940
- }) => {
2941
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2942
- const pauseTime = (_c = (_b = (_a = rollout.status) == null ? void 0 : _a.pauseConditions) == null ? void 0 : _b.find(
2943
- (p) => p.reason === "CanaryPauseStep"
2944
- )) == null ? void 0 : _c.startTime;
2945
- const abortedMessage = findAbortedMessage(rollout);
2946
- return /* @__PURE__ */ React__default.createElement(
2947
- Grid,
2948
- {
2949
- container: true,
2950
- direction: "row",
2951
- justifyContent: "space-between",
2952
- alignItems: "center",
2953
- spacing: 0
2954
- },
2955
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 6, item: true }, /* @__PURE__ */ React__default.createElement(RolloutDrawer, { rollout })),
2956
- hpa && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 3 }, /* @__PURE__ */ React__default.createElement(HorizontalPodAutoscalerDrawer, { hpa }, /* @__PURE__ */ React__default.createElement(
2957
- Grid,
2958
- {
2959
- item: true,
2960
- container: true,
2961
- direction: "column",
2962
- justifyContent: "flex-start",
2963
- alignItems: "flex-start",
2964
- spacing: 0
2965
- },
2966
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "min replicas ", (_e = (_d = hpa.spec) == null ? void 0 : _d.minReplicas) != null ? _e : "?", " / max replicas", " ", (_g = (_f = hpa.spec) == null ? void 0 : _f.maxReplicas) != null ? _g : "?")),
2967
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "current CPU usage:", " ", (_i = (_h = hpa.status) == null ? void 0 : _h.currentCPUUtilizationPercentage) != null ? _i : "?", "%")),
2968
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, "target CPU usage:", " ", (_k = (_j = hpa.spec) == null ? void 0 : _j.targetCPUUtilizationPercentage) != null ? _k : "?", "%"))
2969
- ))),
2970
- /* @__PURE__ */ React__default.createElement(
2971
- Grid,
2972
- {
2973
- item: true,
2974
- container: true,
2975
- xs: 3,
2976
- direction: "column",
2977
- justifyContent: "flex-start",
2978
- alignItems: "flex-end",
2979
- spacing: 0
2980
- },
2981
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(StatusOK, null, numberOfCurrentPods, " pods")),
2982
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, 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"))
2983
- ),
2984
- pauseTime && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 3 }, /* @__PURE__ */ React__default.createElement(
2985
- "div",
2986
- {
2987
- style: {
2988
- display: "flex",
2989
- alignItems: "center",
2990
- flexWrap: "wrap"
2991
- }
2992
- },
2993
- /* @__PURE__ */ React__default.createElement(PauseIcon, null),
2994
- /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, "Paused (", DateTime.fromISO(pauseTime).toRelative({ locale: "en" }), ")")
2995
- )),
2996
- abortedMessage && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 3 }, AbortedTitle)
2997
- );
2998
- };
2999
- const RolloutAccordion = ({
3000
- rollout,
3001
- ownedPods,
3002
- matchingHpa,
3003
- defaultExpanded
3004
- }) => {
3005
- var _a, _b, _c, _d, _e, _f;
3006
- const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
3007
- const podsWithErrors = ownedPods.filter(
3008
- (p) => {
3009
- var _a2, _b2;
3010
- return podNamesWithErrors.has((_b2 = (_a2 = p.metadata) == null ? void 0 : _a2.name) != null ? _b2 : "");
3011
- }
3012
- );
3013
- const currentStepIndex = (_b = (_a = rollout.status) == null ? void 0 : _a.currentStepIndex) != null ? _b : 0;
3014
- const abortedMessage = findAbortedMessage(rollout);
3015
- return /* @__PURE__ */ React__default.createElement(
3016
- Accordion,
3017
- {
3018
- defaultExpanded,
3019
- TransitionProps: { unmountOnExit: true },
3020
- variant: "outlined"
3021
- },
3022
- /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(
3023
- RolloutSummary,
3024
- {
3025
- rollout,
3026
- numberOfCurrentPods: ownedPods.length,
3027
- numberOfPodsWithErrors: podsWithErrors.length,
3028
- hpa: matchingHpa
3029
- }
3030
- )),
3031
- /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement("div", { style: { width: "100%" } }, /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6" }, "Rollout status")), /* @__PURE__ */ React__default.createElement("div", { style: { margin: "1rem" } }, abortedMessage && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, AbortedTitle, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, abortedMessage)), /* @__PURE__ */ React__default.createElement(
3032
- StepsProgress,
3033
- {
3034
- aborted: abortedMessage !== void 0,
3035
- steps: (_f = (_e = (_d = (_c = rollout.spec) == null ? void 0 : _c.strategy) == null ? void 0 : _d.canary) == null ? void 0 : _e.steps) != null ? _f : [],
3036
- currentStepIndex
3037
- }
3038
- )), /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(
3039
- PodsTable,
3040
- {
3041
- pods: ownedPods,
3042
- extraColumns: [READY_COLUMNS, RESOURCE_COLUMNS]
3043
- }
3044
- ))))
3045
- );
3046
- };
3047
- const RolloutAccordions = ({
3048
- rollouts,
3049
- defaultExpanded = false
3050
- }) => {
3051
- const groupedResponses = useContext(GroupedResponsesContext);
3052
- return /* @__PURE__ */ React__default.createElement(
3053
- Grid,
3054
- {
3055
- container: true,
3056
- direction: "column",
3057
- justifyContent: "flex-start",
3058
- alignItems: "flex-start"
3059
- },
3060
- rollouts.map((rollout, i) => {
3061
- var _a, _b;
3062
- return /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
3063
- RolloutAccordion,
3064
- {
3065
- defaultExpanded,
3066
- matchingHpa: getMatchingHpa(
3067
- {
3068
- name: (_a = rollout.metadata) == null ? void 0 : _a.name,
3069
- namespace: (_b = rollout.metadata) == null ? void 0 : _b.namespace,
3070
- kind: "rollout"
3071
- },
3072
- groupedResponses.horizontalPodAutoscalers
3073
- ),
3074
- ownedPods: getOwnedPodsThroughReplicaSets(
3075
- rollout,
3076
- groupedResponses.replicaSets,
3077
- groupedResponses.pods
3078
- ),
3079
- rollout
3080
- }
3081
- )));
3082
- })
3083
- );
3084
- };
3085
-
3086
- const capitalize = (str) => str.charAt(0).toLocaleUpperCase("en-US") + str.slice(1);
3087
- const DefaultCustomResourceDrawer = ({
3088
- customResource,
3089
- customResourceName,
3090
- expanded
3091
- }) => {
3092
- var _a, _b;
3093
- const capitalizedName = capitalize(customResourceName);
3094
- return /* @__PURE__ */ React__default.createElement(
3095
- KubernetesStructuredMetadataTableDrawer,
3096
- {
3097
- object: customResource,
3098
- expanded,
3099
- kind: capitalizedName,
3100
- renderObject: (cr) => cr
3101
- },
3102
- /* @__PURE__ */ React__default.createElement(
3103
- Grid,
3104
- {
3105
- container: true,
3106
- direction: "column",
3107
- justifyContent: "flex-start",
3108
- alignItems: "flex-start",
3109
- spacing: 0
3110
- },
3111
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_b = (_a = customResource.metadata) == null ? void 0 : _a.name) != null ? _b : "unknown object")),
3112
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, capitalizedName))
3113
- )
3114
- );
3115
- };
3116
-
3117
- const DefaultCustomResourceSummary = ({
3118
- customResource,
3119
- customResourceName
3120
- }) => {
3121
- return /* @__PURE__ */ React__default.createElement(
3122
- Grid,
3123
- {
3124
- container: true,
3125
- direction: "row",
3126
- justifyContent: "space-between",
3127
- alignItems: "center",
3128
- spacing: 0
3129
- },
3130
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 12, item: true }, /* @__PURE__ */ React__default.createElement(
3131
- DefaultCustomResourceDrawer,
3132
- {
3133
- customResource,
3134
- customResourceName
3135
- }
3136
- ))
3137
- );
3138
- };
3139
- const DefaultCustomResourceAccordion = ({
3140
- customResource,
3141
- customResourceName,
3142
- defaultExpanded
3143
- }) => {
3144
- return /* @__PURE__ */ React__default.createElement(
3145
- Accordion,
3146
- {
3147
- defaultExpanded,
3148
- TransitionProps: { unmountOnExit: true },
3149
- variant: "outlined"
3150
- },
3151
- /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(
3152
- DefaultCustomResourceSummary,
3153
- {
3154
- customResource,
3155
- customResourceName
3156
- }
3157
- )),
3158
- /* @__PURE__ */ React__default.createElement(AccordionDetails, null, Object.prototype.hasOwnProperty.call(customResource, "status") && /* @__PURE__ */ React__default.createElement(StructuredMetadataTable, { metadata: customResource.status }))
3159
- );
3160
- };
3161
- const DefaultCustomResourceAccordions = ({
3162
- customResources,
3163
- customResourceName,
3164
- defaultExpanded = false
3165
- }) => {
3166
- return /* @__PURE__ */ React__default.createElement(
3167
- Grid,
3168
- {
3169
- container: true,
3170
- direction: "column",
3171
- justifyContent: "flex-start",
3172
- alignItems: "flex-start"
3173
- },
3174
- customResources.map((cr, i) => /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
3175
- DefaultCustomResourceAccordion,
3176
- {
3177
- defaultExpanded,
3178
- customResource: cr,
3179
- customResourceName
3180
- }
3181
- ))))
3182
- );
3183
- };
3184
-
3185
- const kindToResource = (customResources) => {
3186
- return lodash.groupBy(customResources, (value) => {
3187
- return value.kind;
3188
- });
3189
- };
3190
- const CustomResources = ({}) => {
3191
- const groupedResponses = useContext(GroupedResponsesContext);
3192
- const kindToResourceMap = kindToResource(groupedResponses.customResources);
3193
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, Object.entries(kindToResourceMap).map(([kind, resources], i) => {
3194
- switch (kind) {
3195
- case "Rollout":
3196
- return /* @__PURE__ */ React__default.createElement(RolloutAccordions, { key: i, rollouts: resources });
3197
- default:
3198
- return /* @__PURE__ */ React__default.createElement(
3199
- DefaultCustomResourceAccordions,
3200
- {
3201
- key: i,
3202
- customResources: resources,
3203
- customResourceName: kind
3204
- }
3205
- );
3206
- }
3207
- }));
3208
- };
3209
-
3210
- const DaemonSetDrawer = ({
3211
- daemonset,
3212
- expanded
3213
- }) => {
3214
- var _a, _b, _c;
3215
- const namespace = (_a = daemonset.metadata) == null ? void 0 : _a.namespace;
3216
- return /* @__PURE__ */ React__default.createElement(
3217
- KubernetesStructuredMetadataTableDrawer,
3218
- {
3219
- object: daemonset,
3220
- expanded,
3221
- kind: "DaemonSet",
3222
- renderObject: (daemonsetObj) => {
3223
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
3224
- return {
3225
- updateStrategyType: (_c2 = (_b2 = (_a2 = daemonsetObj.spec) == null ? void 0 : _a2.updateStrategy) == null ? void 0 : _b2.type) != null ? _c2 : "???",
3226
- minReadySeconds: (_e = (_d = daemonsetObj.spec) == null ? void 0 : _d.minReadySeconds) != null ? _e : "???",
3227
- revisionHistoryLimit: (_g = (_f = daemonsetObj.spec) == null ? void 0 : _f.revisionHistoryLimit) != null ? _g : "???",
3228
- currentNumberScheduled: (_i = (_h = daemonsetObj.status) == null ? void 0 : _h.currentNumberScheduled) != null ? _i : "???",
3229
- desiredNumberScheduled: (_k = (_j = daemonsetObj.status) == null ? void 0 : _j.desiredNumberScheduled) != null ? _k : "???",
3230
- numberAvailable: (_m = (_l = daemonsetObj.status) == null ? void 0 : _l.numberAvailable) != null ? _m : "???",
3231
- numberMisscheduled: (_o = (_n = daemonsetObj.status) == null ? void 0 : _n.numberMisscheduled) != null ? _o : "???",
3232
- numberReady: (_q = (_p = daemonsetObj.status) == null ? void 0 : _p.numberReady) != null ? _q : "???"
3233
- };
3234
- }
3235
- },
3236
- /* @__PURE__ */ React__default.createElement(
3237
- Grid,
3238
- {
3239
- container: true,
3240
- direction: "column",
3241
- justifyContent: "flex-start",
3242
- alignItems: "flex-start",
3243
- spacing: 0
3244
- },
3245
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, (_c = (_b = daemonset.metadata) == null ? void 0 : _b.name) != null ? _c : "unknown object")),
3246
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "DaemonSet")),
3247
- namespace && /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(Chip, { size: "small", label: `namespace: ${namespace}` }))
3248
- )
3249
- );
3250
- };
3251
-
3252
- const DaemonSetSummary = ({
3253
- daemonset,
3254
- numberOfCurrentPods,
3255
- numberOfPodsWithErrors
3256
- }) => {
3257
- return /* @__PURE__ */ React__default.createElement(
3258
- Grid,
3259
- {
3260
- container: true,
3261
- direction: "row",
3262
- justifyContent: "space-between",
3263
- alignItems: "center",
3264
- spacing: 0
3265
- },
3266
- /* @__PURE__ */ React__default.createElement(Grid, { xs: 4, item: true }, /* @__PURE__ */ React__default.createElement(DaemonSetDrawer, { daemonset })),
3267
- /* @__PURE__ */ React__default.createElement(
3268
- Grid,
3269
- {
3270
- item: true,
3271
- container: true,
3272
- xs: 4,
3273
- direction: "column",
3274
- justifyContent: "flex-start",
3275
- alignItems: "flex-end",
3276
- spacing: 0
3277
- },
3278
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(StatusOK, null, numberOfCurrentPods, " pods")),
3279
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, 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"))
3280
- )
3281
- );
3282
- };
3283
- const DaemonSetAccordion = ({
3284
- daemonset,
3285
- ownedPods
3286
- }) => {
3287
- const podNamesWithErrors = useContext(PodNamesWithErrorsContext);
3288
- const podsWithErrors = ownedPods.filter(
3289
- (p) => {
3290
- var _a, _b;
3291
- return podNamesWithErrors.has((_b = (_a = p.metadata) == null ? void 0 : _a.name) != null ? _b : "");
3292
- }
3293
- );
3294
- return /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, variant: "outlined" }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(
3295
- DaemonSetSummary,
3296
- {
3297
- daemonset,
3298
- numberOfCurrentPods: ownedPods.length,
3299
- numberOfPodsWithErrors: podsWithErrors.length
3300
- }
3301
- )), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(
3302
- PodsTable,
3303
- {
3304
- pods: ownedPods,
3305
- extraColumns: [READY_COLUMNS, RESOURCE_COLUMNS]
3306
- }
3307
- )));
3308
- };
3309
- const DaemonSetsAccordions = ({}) => {
3310
- const groupedResponses = useContext(GroupedResponsesContext);
3311
- return /* @__PURE__ */ React__default.createElement(
3312
- Grid,
3313
- {
3314
- container: true,
3315
- direction: "column",
3316
- justifyContent: "flex-start",
3317
- alignItems: "flex-start"
3318
- },
3319
- groupedResponses.daemonSets.map((daemonset, i) => /* @__PURE__ */ React__default.createElement(Grid, { container: true, item: true, key: i, xs: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(
3320
- DaemonSetAccordion,
3321
- {
3322
- ownedPods: getOwnedResources(daemonset, groupedResponses.pods),
3323
- daemonset
3324
- }
3325
- ))))
3326
- );
3327
- };
3328
-
3329
- const ClusterSummary = ({
3330
- clusterName,
3331
- totalNumberOfPods,
3332
- numberOfPodsWithErrors
3333
- }) => {
3334
- return /* @__PURE__ */ React__default.createElement(
3335
- Grid,
3336
- {
3337
- container: true,
3338
- direction: "row",
3339
- justifyContent: "space-between",
3340
- alignItems: "flex-start",
3341
- spacing: 0
3342
- },
3343
- /* @__PURE__ */ React__default.createElement(
3344
- Grid,
3345
- {
3346
- xs: 6,
3347
- item: true,
3348
- container: true,
3349
- direction: "column",
3350
- justifyContent: "flex-start",
3351
- alignItems: "flex-start",
3352
- spacing: 0
3353
- },
3354
- /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: true }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body1" }, clusterName), /* @__PURE__ */ React__default.createElement(Typography, { color: "textSecondary", variant: "subtitle1" }, "Cluster"))
3355
- ),
3356
- /* @__PURE__ */ React__default.createElement(
3357
- Grid,
3358
- {
3359
- item: true,
3360
- container: true,
3361
- xs: 3,
3362
- direction: "column",
3363
- justifyContent: "flex-start",
3364
- alignItems: "flex-end",
3365
- spacing: 0
3366
- },
3367
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(StatusOK, null, totalNumberOfPods, " pods")),
3368
- /* @__PURE__ */ React__default.createElement(Grid, { item: true }, numberOfPodsWithErrors > 0 ? /* @__PURE__ */ React__default.createElement(StatusError, null, numberOfPodsWithErrors, " pods with errors") : /* @__PURE__ */ React__default.createElement(StatusOK, null, "No pods with errors"))
3369
- )
3370
- );
3371
- };
3372
- const Cluster = ({ clusterObjects, podsWithErrors }) => {
3373
- const groupedResponses = groupResponses(clusterObjects.resources);
3374
- const podMetricsMap = /* @__PURE__ */ new Map();
3375
- podMetricsMap.set(clusterObjects.cluster.name, clusterObjects.podMetrics);
3376
- return /* @__PURE__ */ React__default.createElement(ClusterContext.Provider, { value: clusterObjects.cluster }, /* @__PURE__ */ React__default.createElement(GroupedResponsesContext.Provider, { value: groupedResponses }, /* @__PURE__ */ React__default.createElement(PodMetricsContext.Provider, { value: podMetricsMap }, /* @__PURE__ */ React__default.createElement(PodNamesWithErrorsContext.Provider, { value: podsWithErrors }, /* @__PURE__ */ React__default.createElement(Accordion, { TransitionProps: { unmountOnExit: true } }, /* @__PURE__ */ React__default.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React__default.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React__default.createElement(
3377
- ClusterSummary,
3378
- {
3379
- clusterName: clusterObjects.cluster.title || clusterObjects.cluster.name,
3380
- totalNumberOfPods: groupedResponses.pods.length,
3381
- numberOfPodsWithErrors: podsWithErrors.size
3382
- }
3383
- )), /* @__PURE__ */ React__default.createElement(AccordionDetails, null, /* @__PURE__ */ React__default.createElement(Grid, { container: true, direction: "column" }, groupedResponses.customResources.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(CustomResources, null)) : void 0, groupedResponses.deployments.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(DeploymentsAccordions, null)) : void 0, groupedResponses.daemonSets.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(DaemonSetsAccordions, null)) : void 0, groupedResponses.statefulsets.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(StatefulSetsAccordions, null)) : void 0, groupedResponses.ingresses.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(IngressesAccordions, null)) : void 0, groupedResponses.services.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(ServicesAccordions, null)) : void 0, groupedResponses.cronJobs.length > 0 ? /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(CronJobsAccordions, null)) : void 0)))))));
3384
- };
3385
-
3386
- const clustersWithErrorsToErrorMessage = (clustersWithErrors) => {
3387
- return clustersWithErrors.map((c, i) => {
3388
- return /* @__PURE__ */ React__default.createElement("div", { key: i }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "body2" }, `Cluster: ${c.cluster.title || c.cluster.name}`), c.errors.map((e, j) => {
3389
- return /* @__PURE__ */ React__default.createElement(Typography, { variant: "body2", key: j }, e.errorType === "FETCH_ERROR" ? `Error communicating with Kubernetes: ${e.errorType}, message: ${e.message}` : `Error fetching Kubernetes resource: '${e.resourcePath}', error: ${e.errorType}, status code: ${e.statusCode}`);
3390
- }), /* @__PURE__ */ React__default.createElement("br", null));
3391
- });
3392
- };
3393
- const ErrorPanel = ({
3394
- entityName,
3395
- errorMessage,
3396
- clustersWithErrors
3397
- }) => /* @__PURE__ */ React__default.createElement(
3398
- WarningPanel,
3399
- {
3400
- title: "There was a problem retrieving Kubernetes objects",
3401
- message: `There was a problem retrieving some Kubernetes resources for the entity: ${entityName}. This could mean that the Error Reporting card is not completely accurate.`
3402
- },
3403
- clustersWithErrors && /* @__PURE__ */ React__default.createElement("div", null, "Errors: ", clustersWithErrorsToErrorMessage(clustersWithErrors)),
3404
- errorMessage && /* @__PURE__ */ React__default.createElement(Typography, { variant: "body2" }, "Errors: ", errorMessage)
3405
- );
3406
-
3407
- const columns = [
3408
- {
3409
- title: "cluster",
3410
- width: "10%",
3411
- render: (row) => row.cluster.title || row.cluster.name
3412
- },
3413
- {
3414
- title: "namespace",
3415
- width: "10%",
3416
- render: (row) => row.error.sourceRef.namespace
3417
- },
3418
- {
3419
- title: "kind",
3420
- width: "10%",
3421
- render: (row) => row.error.sourceRef.kind
3422
- },
3423
- {
3424
- title: "name",
3425
- width: "30%",
3426
- render: (row) => {
3427
- return /* @__PURE__ */ React.createElement(React.Fragment, null, row.error.sourceRef.name, " ");
3428
- }
3429
- },
3430
- {
3431
- title: "messages",
3432
- width: "40%",
3433
- render: (row) => row.error.message
3434
- }
3435
- ];
3436
- const sortBySeverity = (a, b) => {
3437
- if (a.error.severity < b.error.severity) {
3438
- return 1;
3439
- } else if (b.error.severity < a.error.severity) {
3440
- return -1;
3441
- }
3442
- return 0;
3443
- };
3444
- const ErrorReporting = ({
3445
- detectedErrors,
3446
- clusters
3447
- }) => {
3448
- const errors = Array.from(detectedErrors.entries()).flatMap(([clusterName, resourceErrors]) => {
3449
- return resourceErrors.map((e) => ({
3450
- cluster: clusters.find((c) => c.name === clusterName),
3451
- error: e
3452
- }));
3453
- }).sort(sortBySeverity);
3454
- return /* @__PURE__ */ React.createElement(React.Fragment, null, errors.length !== 0 && /* @__PURE__ */ React.createElement(
3455
- Table,
3456
- {
3457
- title: "Error Reporting",
3458
- data: errors,
3459
- columns,
3460
- options: { paging: true, search: false, emptyRowsWhenPaging: false }
3461
- }
3462
- ));
3463
- };
3464
-
3465
- export { AksClusterLinksFormatter, AksKubernetesAuthProvider, Cluster, ClusterContext, ContainerCard, CronJobsAccordions, CustomResources, DEFAULT_FORMATTER_NAME, DetectedErrorsContext, EksClusterLinksFormatter, ErrorList, ErrorPanel, ErrorReporting, Events, EventsContent, FixDialog, GkeClusterLinksFormatter, GoogleKubernetesAuthProvider, GroupedResponsesContext, HorizontalPodAutoscalerDrawer, IngressesAccordions, JobsAccordions, KubernetesAuthProviders, KubernetesBackendClient, KubernetesClusterLinkFormatter, KubernetesDrawer, KubernetesProxyClient, KubernetesStructuredMetadataTableDrawer, LinkErrorPanel, ManifestYaml, OidcKubernetesAuthProvider, OpenshiftClusterLinksFormatter, PendingPodContent, PodDrawer, PodExecTerminal, PodExecTerminalDialog, PodLogs, PodLogsDialog, PodMetricsContext, PodNamesWithErrorsContext, PodNamesWithMetricsContext, PodsTable, READY_COLUMNS, RESOURCE_COLUMNS, RancherClusterLinksFormatter, ResourceUtilization, ServerSideKubernetesAuthProvider, ServicesAccordions, StandardClusterLinksFormatter, getDefaultFormatters, kubernetesApiRef, kubernetesAuthProvidersApiRef, kubernetesClusterLinkFormatterApiRef, kubernetesProxyApiRef, useCustomResources, useEvents, useIsPodExecTerminalEnabled, useIsPodExecTerminalSupported, useKubernetesObjects, useMatchingErrors, usePodLogs, usePodMetrics };
1
+ export { useIsPodExecTerminalEnabled } from './hooks/useIsPodExecTerminalEnabled.esm.js';
2
+ export { useIsPodExecTerminalSupported } from './hooks/useIsPodExecTerminalSupported.esm.js';
3
+ export { useKubernetesObjects } from './hooks/useKubernetesObjects.esm.js';
4
+ export { useCustomResources } from './hooks/useCustomResources.esm.js';
5
+ export { PodNamesWithErrorsContext } from './hooks/PodNamesWithErrors.esm.js';
6
+ export { PodNamesWithMetricsContext } from './hooks/PodNamesWithMetrics.esm.js';
7
+ export { GroupedResponsesContext } from './hooks/GroupedResponses.esm.js';
8
+ export { ClusterContext } from './hooks/Cluster.esm.js';
9
+ export { PodMetricsContext, usePodMetrics } from './hooks/usePodMetrics.esm.js';
10
+ export { DetectedErrorsContext, useMatchingErrors } from './hooks/useMatchingErrors.esm.js';
11
+ export { kubernetesApiRef, kubernetesClusterLinkFormatterApiRef, kubernetesProxyApiRef } from './api/types.esm.js';
12
+ export { KubernetesBackendClient } from './api/KubernetesBackendClient.esm.js';
13
+ export { KubernetesClusterLinkFormatter } from './api/KubernetesClusterLinkFormatter.esm.js';
14
+ export { KubernetesProxyClient } from './api/KubernetesProxyClient.esm.js';
15
+ export { DEFAULT_FORMATTER_NAME, getDefaultFormatters } from './api/formatters/index.esm.js';
16
+ export { kubernetesAuthProvidersApiRef } from './kubernetes-auth-provider/types.esm.js';
17
+ export { KubernetesAuthProviders } from './kubernetes-auth-provider/KubernetesAuthProviders.esm.js';
18
+ export { GoogleKubernetesAuthProvider } from './kubernetes-auth-provider/GoogleKubernetesAuthProvider.esm.js';
19
+ export { ServerSideKubernetesAuthProvider } from './kubernetes-auth-provider/ServerSideAuthProvider.esm.js';
20
+ export { OidcKubernetesAuthProvider } from './kubernetes-auth-provider/OidcKubernetesAuthProvider.esm.js';
21
+ export { AksKubernetesAuthProvider } from './kubernetes-auth-provider/AksKubernetesAuthProvider.esm.js';
22
+ export { Cluster } from './components/Cluster/Cluster.esm.js';
23
+ export { CronJobsAccordions } from './components/CronJobsAccordions/CronJobsAccordions.esm.js';
24
+ export { CustomResources } from './components/CustomResources/CustomResources.esm.js';
25
+ export { ErrorPanel } from './components/ErrorPanel/ErrorPanel.esm.js';
26
+ export { ErrorReporting } from './components/ErrorReporting/ErrorReporting.esm.js';
27
+ export { HorizontalPodAutoscalerDrawer } from './components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.esm.js';
28
+ export { IngressesAccordions } from './components/IngressesAccordions/IngressesAccordions.esm.js';
29
+ export { JobsAccordions } from './components/JobsAccordions/JobsAccordions.esm.js';
30
+ export { KubernetesStructuredMetadataTableDrawer, LinkErrorPanel } from './components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.esm.js';
31
+ export { KubernetesDrawer } from './components/KubernetesDrawer/KubernetesDrawer.esm.js';
32
+ export { ManifestYaml } from './components/KubernetesDrawer/ManifestYaml.esm.js';
33
+ export { PodDrawer } from './components/Pods/PodDrawer/PodDrawer.esm.js';
34
+ export { ContainerCard } from './components/Pods/PodDrawer/ContainerCard.esm.js';
35
+ export { PendingPodContent } from './components/Pods/PodDrawer/PendingPodContent.esm.js';
36
+ export { PodLogs } from './components/Pods/PodLogs/PodLogs.esm.js';
37
+ export { PodLogsDialog } from './components/Pods/PodLogs/PodLogsDialog.esm.js';
38
+ export { usePodLogs } from './components/Pods/PodLogs/usePodLogs.esm.js';
39
+ export { FixDialog } from './components/Pods/FixDialog/FixDialog.esm.js';
40
+ export { Events, EventsContent } from './components/Pods/Events/Events.esm.js';
41
+ export { useEvents } from './components/Pods/Events/useEvents.esm.js';
42
+ export { ErrorList } from './components/Pods/ErrorList/ErrorList.esm.js';
43
+ export { PodsTable, READY_COLUMNS, RESOURCE_COLUMNS } from './components/Pods/PodsTable.esm.js';
44
+ export { ServicesAccordions } from './components/ServicesAccordions/ServicesAccordions.esm.js';
45
+ export { ResourceUtilization } from './components/ResourceUtilization/ResourceUtilization.esm.js';
46
+ export { PodExecTerminal } from './components/PodExecTerminal/PodExecTerminal.esm.js';
47
+ export { PodExecTerminalDialog } from './components/PodExecTerminal/PodExecTerminalDialog.esm.js';
48
+ export { StandardClusterLinksFormatter } from './api/formatters/StandardClusterLinksFormatter.esm.js';
49
+ export { AksClusterLinksFormatter } from './api/formatters/AksClusterLinksFormatter.esm.js';
50
+ export { EksClusterLinksFormatter } from './api/formatters/EksClusterLinksFormatter.esm.js';
51
+ export { GkeClusterLinksFormatter } from './api/formatters/GkeClusterLinksFormatter.esm.js';
52
+ export { OpenshiftClusterLinksFormatter } from './api/formatters/OpenshiftClusterLinksFormatter.esm.js';
53
+ export { RancherClusterLinksFormatter } from './api/formatters/RancherClusterLinksFormatter.esm.js';
3466
54
  //# sourceMappingURL=index.esm.js.map