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