@backstage/plugin-kubernetes-common 0.7.6 → 0.8.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/error-detection/deployments.esm.js +12 -16
- package/dist/error-detection/deployments.esm.js.map +1 -1
- package/dist/error-detection/error-detection.esm.js.map +1 -1
- package/dist/error-detection/hpas.esm.js +5 -6
- package/dist/error-detection/hpas.esm.js.map +1 -1
- package/dist/error-detection/pods.esm.js +58 -86
- package/dist/error-detection/pods.esm.js.map +1 -1
- package/dist/index.cjs.js +75 -108
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,22 +3,18 @@ import { detectErrorsInObjects } from './common.esm.js';
|
|
|
3
3
|
const deploymentErrorMappers = [
|
|
4
4
|
{
|
|
5
5
|
detectErrors: (deployment) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
occurrenceCount: 1
|
|
20
|
-
};
|
|
21
|
-
});
|
|
6
|
+
return (deployment.status?.conditions ?? []).filter((c) => c.status === "False").filter((c) => c.message !== void 0).map((c) => ({
|
|
7
|
+
type: "condition-message-present",
|
|
8
|
+
message: c.message ?? "",
|
|
9
|
+
severity: 6,
|
|
10
|
+
sourceRef: {
|
|
11
|
+
name: deployment.metadata?.name ?? "unknown hpa",
|
|
12
|
+
namespace: deployment.metadata?.namespace ?? "unknown namespace",
|
|
13
|
+
kind: "Deployment",
|
|
14
|
+
apiGroup: "apps/v1"
|
|
15
|
+
},
|
|
16
|
+
occurrenceCount: 1
|
|
17
|
+
}));
|
|
22
18
|
}
|
|
23
19
|
}
|
|
24
20
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployments.esm.js","sources":["../../src/error-detection/deployments.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, ErrorMapper } from './types';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { detectErrorsInObjects } from './common';\n\nconst deploymentErrorMappers: ErrorMapper<Deployment>[] = [\n {\n detectErrors: deployment => {\n return (deployment.status?.conditions ?? [])\n .filter(c => c.status === 'False')\n .filter(c => c.message !== undefined)\n .map(c => ({\n type: 'condition-message-present',\n message: c.message ?? '',\n severity: 6,\n sourceRef: {\n name: deployment.metadata?.name ?? 'unknown hpa',\n namespace: deployment.metadata?.namespace ?? 'unknown namespace',\n kind: 'Deployment',\n apiGroup: 'apps/v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n];\n\nexport const detectErrorsInDeployments = (\n deployments: Deployment[],\n): DetectedError[] =>\n detectErrorsInObjects(deployments, deploymentErrorMappers);\n"],"names":[
|
|
1
|
+
{"version":3,"file":"deployments.esm.js","sources":["../../src/error-detection/deployments.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, ErrorMapper } from './types';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { detectErrorsInObjects } from './common';\n\nconst deploymentErrorMappers: ErrorMapper<Deployment>[] = [\n {\n detectErrors: deployment => {\n return (deployment.status?.conditions ?? [])\n .filter(c => c.status === 'False')\n .filter(c => c.message !== undefined)\n .map(c => ({\n type: 'condition-message-present',\n message: c.message ?? '',\n severity: 6,\n sourceRef: {\n name: deployment.metadata?.name ?? 'unknown hpa',\n namespace: deployment.metadata?.namespace ?? 'unknown namespace',\n kind: 'Deployment',\n apiGroup: 'apps/v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n];\n\nexport const detectErrorsInDeployments = (\n deployments: Deployment[],\n): DetectedError[] =>\n detectErrorsInObjects(deployments, deploymentErrorMappers);\n"],"names":[],"mappings":";;AAoBA,MAAM,sBAAoD,GAAA;AAAA,EACxD;AAAA,IACE,cAAc,CAAc,UAAA,KAAA;AAC1B,MAAA,OAAA,CAAQ,WAAW,MAAQ,EAAA,UAAA,IAAc,EACtC,EAAA,MAAA,CAAO,OAAK,CAAE,CAAA,MAAA,KAAW,OAAO,CAAA,CAChC,OAAO,CAAK,CAAA,KAAA,CAAA,CAAE,YAAY,KAAS,CAAA,CAAA,CACnC,IAAI,CAAM,CAAA,MAAA;AAAA,QACT,IAAM,EAAA,2BAAA;AAAA,QACN,OAAA,EAAS,EAAE,OAAW,IAAA,EAAA;AAAA,QACtB,QAAU,EAAA,CAAA;AAAA,QACV,SAAW,EAAA;AAAA,UACT,IAAA,EAAM,UAAW,CAAA,QAAA,EAAU,IAAQ,IAAA,aAAA;AAAA,UACnC,SAAA,EAAW,UAAW,CAAA,QAAA,EAAU,SAAa,IAAA,mBAAA;AAAA,UAC7C,IAAM,EAAA,YAAA;AAAA,UACN,QAAU,EAAA,SAAA;AAAA,SACZ;AAAA,QACA,eAAiB,EAAA,CAAA;AAAA,OACjB,CAAA,CAAA,CAAA;AAAA,KACN;AAAA,GACF;AACF,CAAA,CAAA;AAEO,MAAM,yBAA4B,GAAA,CACvC,WAEA,KAAA,qBAAA,CAAsB,aAAa,sBAAsB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-detection.esm.js","sources":["../../src/error-detection/error-detection.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, DetectedErrorsByCluster } from './types';\nimport { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';\nimport { groupResponses } from '../util';\nimport { detectErrorsInPods } from './pods';\nimport { detectErrorsInDeployments } from './deployments';\nimport { detectErrorsInHpa } from './hpas';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/
|
|
1
|
+
{"version":3,"file":"error-detection.esm.js","sources":["../../src/error-detection/error-detection.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, DetectedErrorsByCluster } from './types';\nimport { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';\nimport { groupResponses } from '../util';\nimport { detectErrorsInPods } from './pods';\nimport { detectErrorsInDeployments } from './deployments';\nimport { detectErrorsInHpa } from './hpas';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/v2';\nimport { Pod } from 'kubernetes-models/v1';\n\n/**\n * For each cluster try to find errors in each of the object types provided\n * returning a map of cluster names to errors in that cluster\n *\n * @public\n */\nexport const detectErrors = (\n objects: ObjectsByEntityResponse,\n): DetectedErrorsByCluster => {\n const errors: DetectedErrorsByCluster = new Map<string, DetectedError[]>();\n\n for (const clusterResponse of objects.items) {\n let clusterErrors: DetectedError[] = [];\n\n const groupedResponses = groupResponses(clusterResponse.resources);\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInPods(groupedResponses.pods as Pod[]),\n );\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInDeployments(groupedResponses.deployments as Deployment[]),\n );\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInHpa(\n groupedResponses.horizontalPodAutoscalers as HorizontalPodAutoscaler[],\n ),\n );\n\n errors.set(clusterResponse.cluster.name, clusterErrors);\n }\n\n return errors;\n};\n"],"names":[],"mappings":";;;;;AAgCa,MAAA,YAAA,GAAe,CAC1B,OAC4B,KAAA;AAC5B,EAAM,MAAA,MAAA,uBAAsC,GAA6B,EAAA,CAAA;AAEzE,EAAW,KAAA,MAAA,eAAA,IAAmB,QAAQ,KAAO,EAAA;AAC3C,IAAA,IAAI,gBAAiC,EAAC,CAAA;AAEtC,IAAM,MAAA,gBAAA,GAAmB,cAAe,CAAA,eAAA,CAAgB,SAAS,CAAA,CAAA;AAEjE,IAAA,aAAA,GAAgB,aAAc,CAAA,MAAA;AAAA,MAC5B,kBAAA,CAAmB,iBAAiB,IAAa,CAAA;AAAA,KACnD,CAAA;AAEA,IAAA,aAAA,GAAgB,aAAc,CAAA,MAAA;AAAA,MAC5B,yBAAA,CAA0B,iBAAiB,WAA2B,CAAA;AAAA,KACxE,CAAA;AAEA,IAAA,aAAA,GAAgB,aAAc,CAAA,MAAA;AAAA,MAC5B,iBAAA;AAAA,QACE,gBAAiB,CAAA,wBAAA;AAAA,OACnB;AAAA,KACF,CAAA;AAEA,IAAA,MAAA,CAAO,GAAI,CAAA,eAAA,CAAgB,OAAQ,CAAA,IAAA,EAAM,aAAa,CAAA,CAAA;AAAA,GACxD;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
|
|
@@ -3,18 +3,17 @@ import { detectErrorsInObjects } from './common.esm.js';
|
|
|
3
3
|
const hpaErrorMappers = [
|
|
4
4
|
{
|
|
5
5
|
detectErrors: (hpa) => {
|
|
6
|
-
|
|
7
|
-
if (((_b = (_a = hpa.spec) == null ? void 0 : _a.maxReplicas) != null ? _b : -1) === ((_c = hpa.status) == null ? void 0 : _c.currentReplicas)) {
|
|
6
|
+
if ((hpa.spec?.maxReplicas ?? -1) === hpa.status?.currentReplicas) {
|
|
8
7
|
return [
|
|
9
8
|
{
|
|
10
9
|
type: "hpa-max-current-replicas",
|
|
11
|
-
message: `Current number of replicas (${
|
|
10
|
+
message: `Current number of replicas (${hpa.status?.currentReplicas}) is equal to the configured max number of replicas (${hpa.spec?.maxReplicas ?? -1})`,
|
|
12
11
|
severity: 8,
|
|
13
12
|
sourceRef: {
|
|
14
|
-
name:
|
|
15
|
-
namespace:
|
|
13
|
+
name: hpa.metadata?.name ?? "unknown hpa",
|
|
14
|
+
namespace: hpa.metadata?.namespace ?? "unknown namespace",
|
|
16
15
|
kind: "HorizontalPodAutoscaler",
|
|
17
|
-
apiGroup: "autoscaling/
|
|
16
|
+
apiGroup: "autoscaling/v2"
|
|
18
17
|
},
|
|
19
18
|
occurrenceCount: 1
|
|
20
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hpas.esm.js","sources":["../../src/error-detection/hpas.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/
|
|
1
|
+
{"version":3,"file":"hpas.esm.js","sources":["../../src/error-detection/hpas.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/v2';\nimport { DetectedError, ErrorMapper } from './types';\nimport { detectErrorsInObjects } from './common';\n\nconst hpaErrorMappers: ErrorMapper<HorizontalPodAutoscaler>[] = [\n {\n detectErrors: hpa => {\n if ((hpa.spec?.maxReplicas ?? -1) === hpa.status?.currentReplicas) {\n return [\n {\n type: 'hpa-max-current-replicas',\n message: `Current number of replicas (${\n hpa.status?.currentReplicas\n }) is equal to the configured max number of replicas (${\n hpa.spec?.maxReplicas ?? -1\n })`,\n severity: 8,\n sourceRef: {\n name: hpa.metadata?.name ?? 'unknown hpa',\n namespace: hpa.metadata?.namespace ?? 'unknown namespace',\n kind: 'HorizontalPodAutoscaler',\n apiGroup: 'autoscaling/v2',\n },\n occurrenceCount: 1,\n },\n ];\n }\n return [];\n },\n },\n];\n\nexport const detectErrorsInHpa = (\n hpas: HorizontalPodAutoscaler[],\n): DetectedError[] => detectErrorsInObjects(hpas, hpaErrorMappers);\n"],"names":[],"mappings":";;AAoBA,MAAM,eAA0D,GAAA;AAAA,EAC9D;AAAA,IACE,cAAc,CAAO,GAAA,KAAA;AACnB,MAAA,IAAA,CAAK,IAAI,IAAM,EAAA,WAAA,IAAe,CAAQ,CAAA,MAAA,GAAA,CAAI,QAAQ,eAAiB,EAAA;AACjE,QAAO,OAAA;AAAA,UACL;AAAA,YACE,IAAM,EAAA,0BAAA;AAAA,YACN,OAAA,EAAS,+BACP,GAAI,CAAA,MAAA,EAAQ,eACd,CACE,qDAAA,EAAA,GAAA,CAAI,IAAM,EAAA,WAAA,IAAe,CAC3B,CAAA,CAAA,CAAA,CAAA;AAAA,YACA,QAAU,EAAA,CAAA;AAAA,YACV,SAAW,EAAA;AAAA,cACT,IAAA,EAAM,GAAI,CAAA,QAAA,EAAU,IAAQ,IAAA,aAAA;AAAA,cAC5B,SAAA,EAAW,GAAI,CAAA,QAAA,EAAU,SAAa,IAAA,mBAAA;AAAA,cACtC,IAAM,EAAA,yBAAA;AAAA,cACN,QAAU,EAAA,gBAAA;AAAA,aACZ;AAAA,YACA,eAAiB,EAAA,CAAA;AAAA,WACnB;AAAA,SACF,CAAA;AAAA,OACF;AACA,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AAAA,GACF;AACF,CAAA,CAAA;AAEO,MAAM,iBAAoB,GAAA,CAC/B,IACoB,KAAA,qBAAA,CAAsB,MAAM,eAAe;;;;"}
|
|
@@ -6,24 +6,22 @@ function isPodReadinessProbeUnready({
|
|
|
6
6
|
container,
|
|
7
7
|
containerStatus
|
|
8
8
|
}) {
|
|
9
|
-
|
|
10
|
-
if (containerStatus.ready || ((_b = (_a = containerStatus.state) == null ? void 0 : _a.running) == null ? void 0 : _b.startedAt) === void 0 || !container.readinessProbe) {
|
|
9
|
+
if (containerStatus.ready || containerStatus.state?.running?.startedAt === void 0 || !container.readinessProbe) {
|
|
11
10
|
return false;
|
|
12
11
|
}
|
|
13
12
|
const startDateTime = DateTime.fromISO(
|
|
14
|
-
|
|
13
|
+
containerStatus.state?.running?.startedAt
|
|
15
14
|
).plus({
|
|
16
|
-
seconds:
|
|
15
|
+
seconds: container.readinessProbe?.initialDelaySeconds ?? 0
|
|
17
16
|
}).plus({
|
|
18
|
-
seconds: (
|
|
17
|
+
seconds: (container.readinessProbe?.periodSeconds ?? 0) * (container.readinessProbe?.failureThreshold ?? 0)
|
|
19
18
|
});
|
|
20
19
|
return startDateTime < DateTime.now();
|
|
21
20
|
}
|
|
22
21
|
const podToContainerSpecsAndStatuses = (pod) => {
|
|
23
|
-
|
|
24
|
-
const specs = lodash.groupBy((_b = (_a = pod.spec) == null ? void 0 : _a.containers) != null ? _b : [], (value) => value.name);
|
|
22
|
+
const specs = lodash.groupBy(pod.spec?.containers ?? [], (value) => value.name);
|
|
25
23
|
const result = [];
|
|
26
|
-
for (const cs of
|
|
24
|
+
for (const cs of pod.status?.containerStatuses ?? []) {
|
|
27
25
|
const spec = specs[cs.name];
|
|
28
26
|
if (spec.length > 0) {
|
|
29
27
|
result.push({
|
|
@@ -35,36 +33,31 @@ const podToContainerSpecsAndStatuses = (pod) => {
|
|
|
35
33
|
return result;
|
|
36
34
|
};
|
|
37
35
|
const readinessProbeProposedFixes = (pod) => {
|
|
38
|
-
|
|
39
|
-
const firstUnreadyContainerStatus = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) == null ? void 0 : _b.find(
|
|
36
|
+
const firstUnreadyContainerStatus = pod.status?.containerStatuses?.find(
|
|
40
37
|
(cs) => {
|
|
41
38
|
return cs.ready === false;
|
|
42
39
|
}
|
|
43
40
|
);
|
|
44
41
|
return {
|
|
45
42
|
errorType: "ReadinessProbeFailed",
|
|
46
|
-
rootCauseExplanation: `The container ${firstUnreadyContainerStatus
|
|
43
|
+
rootCauseExplanation: `The container ${firstUnreadyContainerStatus?.name} failed to start properly, but is not crashing`,
|
|
47
44
|
actions: [
|
|
48
45
|
"Ensure that the container starts correctly locally",
|
|
49
46
|
"Check the container's logs looking for error during startup"
|
|
50
47
|
],
|
|
51
48
|
type: "events",
|
|
52
|
-
podName:
|
|
49
|
+
podName: pod.metadata?.name ?? ""
|
|
53
50
|
};
|
|
54
51
|
};
|
|
55
52
|
const restartingPodProposedFixes = (pod) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
(cs) => {
|
|
59
|
-
var _a2;
|
|
60
|
-
return ((_a2 = cs.lastState) == null ? void 0 : _a2.terminated) !== void 0;
|
|
61
|
-
}
|
|
53
|
+
const lastTerminatedCs = (pod.status?.containerStatuses ?? []).find(
|
|
54
|
+
(cs) => cs.lastState?.terminated !== void 0
|
|
62
55
|
);
|
|
63
|
-
const lastTerminated =
|
|
56
|
+
const lastTerminated = lastTerminatedCs?.lastState?.terminated;
|
|
64
57
|
if (!lastTerminated) {
|
|
65
58
|
return void 0;
|
|
66
59
|
}
|
|
67
|
-
switch (lastTerminated
|
|
60
|
+
switch (lastTerminated?.reason) {
|
|
68
61
|
case "Unknown":
|
|
69
62
|
return {
|
|
70
63
|
// TODO check this one, it's more likely a cluster issue
|
|
@@ -98,18 +91,11 @@ const restartingPodProposedFixes = (pod) => {
|
|
|
98
91
|
}
|
|
99
92
|
};
|
|
100
93
|
const waitingProposedFix = (pod) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
(cs) => {
|
|
104
|
-
var _a2;
|
|
105
|
-
return ((_a2 = cs.state) == null ? void 0 : _a2.waiting) !== void 0;
|
|
106
|
-
}
|
|
94
|
+
const waitingCs = (pod.status?.containerStatuses ?? []).find(
|
|
95
|
+
(cs) => cs.state?.waiting !== void 0
|
|
107
96
|
);
|
|
108
|
-
const waiting = (
|
|
109
|
-
|
|
110
|
-
return (_a2 = cs.state) == null ? void 0 : _a2.waiting;
|
|
111
|
-
}).find((w) => (w == null ? void 0 : w.reason) !== void 0);
|
|
112
|
-
switch (waiting == null ? void 0 : waiting.reason) {
|
|
97
|
+
const waiting = (pod.status?.containerStatuses ?? []).map((cs) => cs.state?.waiting).find((w) => w?.reason !== void 0);
|
|
98
|
+
switch (waiting?.reason) {
|
|
113
99
|
case "InvalidImageName":
|
|
114
100
|
return {
|
|
115
101
|
errorType: "InvalidImageName",
|
|
@@ -132,10 +118,10 @@ const waitingProposedFix = (pod) => {
|
|
|
132
118
|
case "CrashLoopBackOff":
|
|
133
119
|
return {
|
|
134
120
|
errorType: "CrashLoopBackOff",
|
|
135
|
-
rootCauseExplanation: `The container ${waitingCs
|
|
121
|
+
rootCauseExplanation: `The container ${waitingCs?.name} has crashed many times, it will be exponentially restarted until it stops crashing`,
|
|
136
122
|
actions: ["Check the crash logs for stacktraces"],
|
|
137
123
|
type: "logs",
|
|
138
|
-
container:
|
|
124
|
+
container: waitingCs?.name ?? "unknown"
|
|
139
125
|
};
|
|
140
126
|
case "CreateContainerConfigError":
|
|
141
127
|
return {
|
|
@@ -155,67 +141,53 @@ const waitingProposedFix = (pod) => {
|
|
|
155
141
|
const podErrorMappers = [
|
|
156
142
|
{
|
|
157
143
|
detectErrors: (pod) => {
|
|
158
|
-
return podToContainerSpecsAndStatuses(pod).filter(isPodReadinessProbeUnready).map((cs) => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
occurrenceCount: 1
|
|
172
|
-
};
|
|
173
|
-
});
|
|
144
|
+
return podToContainerSpecsAndStatuses(pod).filter(isPodReadinessProbeUnready).map((cs) => ({
|
|
145
|
+
type: "readiness-probe-taking-too-long",
|
|
146
|
+
message: `The container ${cs.container.name} failed to start properly, but is not crashing`,
|
|
147
|
+
severity: 4,
|
|
148
|
+
proposedFix: readinessProbeProposedFixes(pod),
|
|
149
|
+
sourceRef: {
|
|
150
|
+
name: pod.metadata?.name ?? "unknown pod",
|
|
151
|
+
namespace: pod.metadata?.namespace ?? "unknown namespace",
|
|
152
|
+
kind: "Pod",
|
|
153
|
+
apiGroup: "v1"
|
|
154
|
+
},
|
|
155
|
+
occurrenceCount: 1
|
|
156
|
+
}));
|
|
174
157
|
}
|
|
175
158
|
},
|
|
176
159
|
{
|
|
177
160
|
detectErrors: (pod) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
namespace: (_g = (_f = pod.metadata) == null ? void 0 : _f.namespace) != null ? _g : "unknown namespace",
|
|
192
|
-
kind: "Pod",
|
|
193
|
-
apiGroup: "v1"
|
|
194
|
-
},
|
|
195
|
-
occurrenceCount: 1
|
|
196
|
-
};
|
|
197
|
-
});
|
|
161
|
+
return (pod.status?.containerStatuses ?? []).filter((cs) => cs.state?.waiting?.message !== void 0).map((cs) => ({
|
|
162
|
+
type: "container-waiting",
|
|
163
|
+
message: cs.state?.waiting?.message ?? "container waiting",
|
|
164
|
+
severity: 4,
|
|
165
|
+
proposedFix: waitingProposedFix(pod),
|
|
166
|
+
sourceRef: {
|
|
167
|
+
name: pod.metadata?.name ?? "unknown pod",
|
|
168
|
+
namespace: pod.metadata?.namespace ?? "unknown namespace",
|
|
169
|
+
kind: "Pod",
|
|
170
|
+
apiGroup: "v1"
|
|
171
|
+
},
|
|
172
|
+
occurrenceCount: 1
|
|
173
|
+
}));
|
|
198
174
|
}
|
|
199
175
|
},
|
|
200
176
|
{
|
|
201
177
|
detectErrors: (pod) => {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
},
|
|
216
|
-
occurrenceCount: cs.restartCount
|
|
217
|
-
};
|
|
218
|
-
});
|
|
178
|
+
return (pod.status?.containerStatuses ?? []).filter((cs) => cs.restartCount > 0).map((cs) => ({
|
|
179
|
+
type: "containers-restarting",
|
|
180
|
+
message: `container=${cs.name} restarted ${cs.restartCount} times`,
|
|
181
|
+
severity: 4,
|
|
182
|
+
proposedFix: restartingPodProposedFixes(pod),
|
|
183
|
+
sourceRef: {
|
|
184
|
+
name: pod.metadata?.name ?? "unknown pod",
|
|
185
|
+
namespace: pod.metadata?.namespace ?? "unknown namespace",
|
|
186
|
+
kind: "Pod",
|
|
187
|
+
apiGroup: "v1"
|
|
188
|
+
},
|
|
189
|
+
occurrenceCount: cs.restartCount
|
|
190
|
+
}));
|
|
219
191
|
}
|
|
220
192
|
}
|
|
221
193
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pods.esm.js","sources":["../../src/error-detection/pods.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Pod, IContainerStatus, IContainer } from 'kubernetes-models/v1';\nimport { DetectedError, ErrorMapper, ProposedFix } from './types';\nimport { detectErrorsInObjects } from './common';\nimport lodash from 'lodash';\nimport { DateTime } from 'luxon';\n\nfunction isPodReadinessProbeUnready({\n container,\n containerStatus,\n}: ContainerSpecAndStatus): boolean {\n if (\n containerStatus.ready ||\n containerStatus.state?.running?.startedAt === undefined ||\n !container.readinessProbe\n ) {\n return false;\n }\n const startDateTime = DateTime.fromISO(\n containerStatus.state?.running?.startedAt,\n )\n // Add initial delay\n .plus({\n seconds: container.readinessProbe?.initialDelaySeconds ?? 0,\n })\n // Add failure threshold\n .plus({\n seconds:\n (container.readinessProbe?.periodSeconds ?? 0) *\n (container.readinessProbe?.failureThreshold ?? 0),\n });\n return startDateTime < DateTime.now();\n}\n\ninterface ContainerSpecAndStatus {\n container: IContainer;\n containerStatus: IContainerStatus;\n}\n\nconst podToContainerSpecsAndStatuses = (pod: Pod): ContainerSpecAndStatus[] => {\n const specs = lodash.groupBy(pod.spec?.containers ?? [], value => value.name);\n\n const result: ContainerSpecAndStatus[] = [];\n\n for (const cs of pod.status?.containerStatuses ?? []) {\n const spec = specs[cs.name];\n if (spec.length > 0) {\n result.push({\n container: spec[0],\n containerStatus: cs,\n });\n }\n }\n\n return result;\n};\n\nconst readinessProbeProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const firstUnreadyContainerStatus = pod.status?.containerStatuses?.find(\n cs => {\n return cs.ready === false;\n },\n );\n\n return {\n errorType: 'ReadinessProbeFailed',\n rootCauseExplanation: `The container ${firstUnreadyContainerStatus?.name} failed to start properly, but is not crashing`,\n actions: [\n 'Ensure that the container starts correctly locally',\n \"Check the container's logs looking for error during startup\",\n ],\n type: 'events',\n podName: pod.metadata?.name ?? '',\n };\n};\n\nconst restartingPodProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const lastTerminatedCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.lastState?.terminated !== undefined,\n );\n\n const lastTerminated = lastTerminatedCs?.lastState?.terminated;\n\n if (!lastTerminated) {\n return undefined;\n }\n\n switch (lastTerminated?.reason) {\n case 'Unknown':\n return {\n // TODO check this one, it's more likely a cluster issue\n errorType: 'Unknown',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'Error':\n return {\n errorType: 'Error',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'OOMKilled':\n return {\n errorType: 'OOMKilled',\n rootCauseExplanation: `The container \"${lastTerminatedCs.name}\" has crashed because it has tried to use more memory that it has been allocated`,\n actions: [\n `Increase the amount of memory assigned to the container`,\n 'Ensure the application is memory bounded and is not trying to consume too much memory',\n ],\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#exceed-a-container-s-memory-limit',\n type: 'docs',\n };\n default:\n return undefined;\n }\n};\n\nconst waitingProposedFix = (pod: Pod): ProposedFix | undefined => {\n const waitingCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.state?.waiting !== undefined,\n );\n\n const waiting = (pod.status?.containerStatuses ?? [])\n .map(cs => cs.state?.waiting)\n .find(w => w?.reason !== undefined);\n\n switch (waiting?.reason) {\n case 'InvalidImageName':\n return {\n errorType: 'InvalidImageName',\n rootCauseExplanation: 'The image in the pod is invalid',\n actions: ['Ensure the image name is correct and valid image name'],\n type: 'docs',\n docsLink:\n 'https://docs.docker.com/engine/reference/commandline/tag/#extended-description',\n };\n case 'ImagePullBackOff':\n return {\n errorType: 'ImagePullBackOff',\n rootCauseExplanation:\n 'The image either could not be found or Kubernetes does not have permission to pull it',\n actions: [\n 'Ensure the image name is correct',\n 'Ensure Kubernetes has permission to pull this image',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/concepts/containers/images/#imagepullbackoff',\n };\n case 'CrashLoopBackOff':\n return {\n errorType: 'CrashLoopBackOff',\n rootCauseExplanation: `The container ${waitingCs?.name} has crashed many times, it will be exponentially restarted until it stops crashing`,\n actions: ['Check the crash logs for stacktraces'],\n type: 'logs',\n container: waitingCs?.name ?? 'unknown',\n };\n case 'CreateContainerConfigError':\n return {\n errorType: 'CreateContainerConfigError',\n rootCauseExplanation:\n 'There is missing or mismatching configuration required to start the container',\n actions: [\n 'Ensure ConfigMaps references in the Deployment manifest are correct and the keys exist',\n 'Ensure Secrets references in the Deployment manifest are correct and the keys exist',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/',\n };\n default:\n return undefined;\n }\n};\n\nconst podErrorMappers: ErrorMapper<Pod>[] = [\n {\n detectErrors: pod => {\n return podToContainerSpecsAndStatuses(pod)\n .filter(isPodReadinessProbeUnready)\n .map(cs => ({\n type: 'readiness-probe-taking-too-long',\n message: `The container ${cs.container.name} failed to start properly, but is not crashing`,\n severity: 4,\n proposedFix: readinessProbeProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.state?.waiting?.message !== undefined)\n .map(cs => ({\n type: 'container-waiting',\n message: cs.state?.waiting?.message ?? 'container waiting',\n severity: 4,\n proposedFix: waitingProposedFix(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.restartCount > 0)\n .map(cs => ({\n type: 'containers-restarting',\n message: `container=${cs.name} restarted ${cs.restartCount} times`,\n severity: 4,\n proposedFix: restartingPodProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: cs.restartCount,\n }));\n },\n },\n];\n\nexport const detectErrorsInPods = (pods: Pod[]): DetectedError[] =>\n detectErrorsInObjects(pods, podErrorMappers);\n"],"names":["_a","_b"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pods.esm.js","sources":["../../src/error-detection/pods.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Pod, IContainerStatus, IContainer } from 'kubernetes-models/v1';\nimport { DetectedError, ErrorMapper, ProposedFix } from './types';\nimport { detectErrorsInObjects } from './common';\nimport lodash from 'lodash';\nimport { DateTime } from 'luxon';\n\nfunction isPodReadinessProbeUnready({\n container,\n containerStatus,\n}: ContainerSpecAndStatus): boolean {\n if (\n containerStatus.ready ||\n containerStatus.state?.running?.startedAt === undefined ||\n !container.readinessProbe\n ) {\n return false;\n }\n const startDateTime = DateTime.fromISO(\n containerStatus.state?.running?.startedAt,\n )\n // Add initial delay\n .plus({\n seconds: container.readinessProbe?.initialDelaySeconds ?? 0,\n })\n // Add failure threshold\n .plus({\n seconds:\n (container.readinessProbe?.periodSeconds ?? 0) *\n (container.readinessProbe?.failureThreshold ?? 0),\n });\n return startDateTime < DateTime.now();\n}\n\ninterface ContainerSpecAndStatus {\n container: IContainer;\n containerStatus: IContainerStatus;\n}\n\nconst podToContainerSpecsAndStatuses = (pod: Pod): ContainerSpecAndStatus[] => {\n const specs = lodash.groupBy(pod.spec?.containers ?? [], value => value.name);\n\n const result: ContainerSpecAndStatus[] = [];\n\n for (const cs of pod.status?.containerStatuses ?? []) {\n const spec = specs[cs.name];\n if (spec.length > 0) {\n result.push({\n container: spec[0],\n containerStatus: cs,\n });\n }\n }\n\n return result;\n};\n\nconst readinessProbeProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const firstUnreadyContainerStatus = pod.status?.containerStatuses?.find(\n cs => {\n return cs.ready === false;\n },\n );\n\n return {\n errorType: 'ReadinessProbeFailed',\n rootCauseExplanation: `The container ${firstUnreadyContainerStatus?.name} failed to start properly, but is not crashing`,\n actions: [\n 'Ensure that the container starts correctly locally',\n \"Check the container's logs looking for error during startup\",\n ],\n type: 'events',\n podName: pod.metadata?.name ?? '',\n };\n};\n\nconst restartingPodProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const lastTerminatedCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.lastState?.terminated !== undefined,\n );\n\n const lastTerminated = lastTerminatedCs?.lastState?.terminated;\n\n if (!lastTerminated) {\n return undefined;\n }\n\n switch (lastTerminated?.reason) {\n case 'Unknown':\n return {\n // TODO check this one, it's more likely a cluster issue\n errorType: 'Unknown',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'Error':\n return {\n errorType: 'Error',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'OOMKilled':\n return {\n errorType: 'OOMKilled',\n rootCauseExplanation: `The container \"${lastTerminatedCs.name}\" has crashed because it has tried to use more memory that it has been allocated`,\n actions: [\n `Increase the amount of memory assigned to the container`,\n 'Ensure the application is memory bounded and is not trying to consume too much memory',\n ],\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#exceed-a-container-s-memory-limit',\n type: 'docs',\n };\n default:\n return undefined;\n }\n};\n\nconst waitingProposedFix = (pod: Pod): ProposedFix | undefined => {\n const waitingCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.state?.waiting !== undefined,\n );\n\n const waiting = (pod.status?.containerStatuses ?? [])\n .map(cs => cs.state?.waiting)\n .find(w => w?.reason !== undefined);\n\n switch (waiting?.reason) {\n case 'InvalidImageName':\n return {\n errorType: 'InvalidImageName',\n rootCauseExplanation: 'The image in the pod is invalid',\n actions: ['Ensure the image name is correct and valid image name'],\n type: 'docs',\n docsLink:\n 'https://docs.docker.com/engine/reference/commandline/tag/#extended-description',\n };\n case 'ImagePullBackOff':\n return {\n errorType: 'ImagePullBackOff',\n rootCauseExplanation:\n 'The image either could not be found or Kubernetes does not have permission to pull it',\n actions: [\n 'Ensure the image name is correct',\n 'Ensure Kubernetes has permission to pull this image',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/concepts/containers/images/#imagepullbackoff',\n };\n case 'CrashLoopBackOff':\n return {\n errorType: 'CrashLoopBackOff',\n rootCauseExplanation: `The container ${waitingCs?.name} has crashed many times, it will be exponentially restarted until it stops crashing`,\n actions: ['Check the crash logs for stacktraces'],\n type: 'logs',\n container: waitingCs?.name ?? 'unknown',\n };\n case 'CreateContainerConfigError':\n return {\n errorType: 'CreateContainerConfigError',\n rootCauseExplanation:\n 'There is missing or mismatching configuration required to start the container',\n actions: [\n 'Ensure ConfigMaps references in the Deployment manifest are correct and the keys exist',\n 'Ensure Secrets references in the Deployment manifest are correct and the keys exist',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/',\n };\n default:\n return undefined;\n }\n};\n\nconst podErrorMappers: ErrorMapper<Pod>[] = [\n {\n detectErrors: pod => {\n return podToContainerSpecsAndStatuses(pod)\n .filter(isPodReadinessProbeUnready)\n .map(cs => ({\n type: 'readiness-probe-taking-too-long',\n message: `The container ${cs.container.name} failed to start properly, but is not crashing`,\n severity: 4,\n proposedFix: readinessProbeProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.state?.waiting?.message !== undefined)\n .map(cs => ({\n type: 'container-waiting',\n message: cs.state?.waiting?.message ?? 'container waiting',\n severity: 4,\n proposedFix: waitingProposedFix(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.restartCount > 0)\n .map(cs => ({\n type: 'containers-restarting',\n message: `container=${cs.name} restarted ${cs.restartCount} times`,\n severity: 4,\n proposedFix: restartingPodProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: cs.restartCount,\n }));\n },\n },\n];\n\nexport const detectErrorsInPods = (pods: Pod[]): DetectedError[] =>\n detectErrorsInObjects(pods, podErrorMappers);\n"],"names":[],"mappings":"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"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -97,24 +97,22 @@ function isPodReadinessProbeUnready({
|
|
|
97
97
|
container,
|
|
98
98
|
containerStatus
|
|
99
99
|
}) {
|
|
100
|
-
|
|
101
|
-
if (containerStatus.ready || ((_b = (_a = containerStatus.state) == null ? void 0 : _a.running) == null ? void 0 : _b.startedAt) === void 0 || !container.readinessProbe) {
|
|
100
|
+
if (containerStatus.ready || containerStatus.state?.running?.startedAt === void 0 || !container.readinessProbe) {
|
|
102
101
|
return false;
|
|
103
102
|
}
|
|
104
103
|
const startDateTime = luxon.DateTime.fromISO(
|
|
105
|
-
|
|
104
|
+
containerStatus.state?.running?.startedAt
|
|
106
105
|
).plus({
|
|
107
|
-
seconds:
|
|
106
|
+
seconds: container.readinessProbe?.initialDelaySeconds ?? 0
|
|
108
107
|
}).plus({
|
|
109
|
-
seconds: (
|
|
108
|
+
seconds: (container.readinessProbe?.periodSeconds ?? 0) * (container.readinessProbe?.failureThreshold ?? 0)
|
|
110
109
|
});
|
|
111
110
|
return startDateTime < luxon.DateTime.now();
|
|
112
111
|
}
|
|
113
112
|
const podToContainerSpecsAndStatuses = (pod) => {
|
|
114
|
-
|
|
115
|
-
const specs = lodash__default.default.groupBy((_b = (_a = pod.spec) == null ? void 0 : _a.containers) != null ? _b : [], (value) => value.name);
|
|
113
|
+
const specs = lodash__default.default.groupBy(pod.spec?.containers ?? [], (value) => value.name);
|
|
116
114
|
const result = [];
|
|
117
|
-
for (const cs of
|
|
115
|
+
for (const cs of pod.status?.containerStatuses ?? []) {
|
|
118
116
|
const spec = specs[cs.name];
|
|
119
117
|
if (spec.length > 0) {
|
|
120
118
|
result.push({
|
|
@@ -126,36 +124,31 @@ const podToContainerSpecsAndStatuses = (pod) => {
|
|
|
126
124
|
return result;
|
|
127
125
|
};
|
|
128
126
|
const readinessProbeProposedFixes = (pod) => {
|
|
129
|
-
|
|
130
|
-
const firstUnreadyContainerStatus = (_b = (_a = pod.status) == null ? void 0 : _a.containerStatuses) == null ? void 0 : _b.find(
|
|
127
|
+
const firstUnreadyContainerStatus = pod.status?.containerStatuses?.find(
|
|
131
128
|
(cs) => {
|
|
132
129
|
return cs.ready === false;
|
|
133
130
|
}
|
|
134
131
|
);
|
|
135
132
|
return {
|
|
136
133
|
errorType: "ReadinessProbeFailed",
|
|
137
|
-
rootCauseExplanation: `The container ${firstUnreadyContainerStatus
|
|
134
|
+
rootCauseExplanation: `The container ${firstUnreadyContainerStatus?.name} failed to start properly, but is not crashing`,
|
|
138
135
|
actions: [
|
|
139
136
|
"Ensure that the container starts correctly locally",
|
|
140
137
|
"Check the container's logs looking for error during startup"
|
|
141
138
|
],
|
|
142
139
|
type: "events",
|
|
143
|
-
podName:
|
|
140
|
+
podName: pod.metadata?.name ?? ""
|
|
144
141
|
};
|
|
145
142
|
};
|
|
146
143
|
const restartingPodProposedFixes = (pod) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
(cs) => {
|
|
150
|
-
var _a2;
|
|
151
|
-
return ((_a2 = cs.lastState) == null ? void 0 : _a2.terminated) !== void 0;
|
|
152
|
-
}
|
|
144
|
+
const lastTerminatedCs = (pod.status?.containerStatuses ?? []).find(
|
|
145
|
+
(cs) => cs.lastState?.terminated !== void 0
|
|
153
146
|
);
|
|
154
|
-
const lastTerminated =
|
|
147
|
+
const lastTerminated = lastTerminatedCs?.lastState?.terminated;
|
|
155
148
|
if (!lastTerminated) {
|
|
156
149
|
return void 0;
|
|
157
150
|
}
|
|
158
|
-
switch (lastTerminated
|
|
151
|
+
switch (lastTerminated?.reason) {
|
|
159
152
|
case "Unknown":
|
|
160
153
|
return {
|
|
161
154
|
// TODO check this one, it's more likely a cluster issue
|
|
@@ -189,18 +182,11 @@ const restartingPodProposedFixes = (pod) => {
|
|
|
189
182
|
}
|
|
190
183
|
};
|
|
191
184
|
const waitingProposedFix = (pod) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
(cs) => {
|
|
195
|
-
var _a2;
|
|
196
|
-
return ((_a2 = cs.state) == null ? void 0 : _a2.waiting) !== void 0;
|
|
197
|
-
}
|
|
185
|
+
const waitingCs = (pod.status?.containerStatuses ?? []).find(
|
|
186
|
+
(cs) => cs.state?.waiting !== void 0
|
|
198
187
|
);
|
|
199
|
-
const waiting = (
|
|
200
|
-
|
|
201
|
-
return (_a2 = cs.state) == null ? void 0 : _a2.waiting;
|
|
202
|
-
}).find((w) => (w == null ? void 0 : w.reason) !== void 0);
|
|
203
|
-
switch (waiting == null ? void 0 : waiting.reason) {
|
|
188
|
+
const waiting = (pod.status?.containerStatuses ?? []).map((cs) => cs.state?.waiting).find((w) => w?.reason !== void 0);
|
|
189
|
+
switch (waiting?.reason) {
|
|
204
190
|
case "InvalidImageName":
|
|
205
191
|
return {
|
|
206
192
|
errorType: "InvalidImageName",
|
|
@@ -223,10 +209,10 @@ const waitingProposedFix = (pod) => {
|
|
|
223
209
|
case "CrashLoopBackOff":
|
|
224
210
|
return {
|
|
225
211
|
errorType: "CrashLoopBackOff",
|
|
226
|
-
rootCauseExplanation: `The container ${waitingCs
|
|
212
|
+
rootCauseExplanation: `The container ${waitingCs?.name} has crashed many times, it will be exponentially restarted until it stops crashing`,
|
|
227
213
|
actions: ["Check the crash logs for stacktraces"],
|
|
228
214
|
type: "logs",
|
|
229
|
-
container:
|
|
215
|
+
container: waitingCs?.name ?? "unknown"
|
|
230
216
|
};
|
|
231
217
|
case "CreateContainerConfigError":
|
|
232
218
|
return {
|
|
@@ -246,67 +232,53 @@ const waitingProposedFix = (pod) => {
|
|
|
246
232
|
const podErrorMappers = [
|
|
247
233
|
{
|
|
248
234
|
detectErrors: (pod) => {
|
|
249
|
-
return podToContainerSpecsAndStatuses(pod).filter(isPodReadinessProbeUnready).map((cs) => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
occurrenceCount: 1
|
|
263
|
-
};
|
|
264
|
-
});
|
|
235
|
+
return podToContainerSpecsAndStatuses(pod).filter(isPodReadinessProbeUnready).map((cs) => ({
|
|
236
|
+
type: "readiness-probe-taking-too-long",
|
|
237
|
+
message: `The container ${cs.container.name} failed to start properly, but is not crashing`,
|
|
238
|
+
severity: 4,
|
|
239
|
+
proposedFix: readinessProbeProposedFixes(pod),
|
|
240
|
+
sourceRef: {
|
|
241
|
+
name: pod.metadata?.name ?? "unknown pod",
|
|
242
|
+
namespace: pod.metadata?.namespace ?? "unknown namespace",
|
|
243
|
+
kind: "Pod",
|
|
244
|
+
apiGroup: "v1"
|
|
245
|
+
},
|
|
246
|
+
occurrenceCount: 1
|
|
247
|
+
}));
|
|
265
248
|
}
|
|
266
249
|
},
|
|
267
250
|
{
|
|
268
251
|
detectErrors: (pod) => {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
namespace: (_g = (_f = pod.metadata) == null ? void 0 : _f.namespace) != null ? _g : "unknown namespace",
|
|
283
|
-
kind: "Pod",
|
|
284
|
-
apiGroup: "v1"
|
|
285
|
-
},
|
|
286
|
-
occurrenceCount: 1
|
|
287
|
-
};
|
|
288
|
-
});
|
|
252
|
+
return (pod.status?.containerStatuses ?? []).filter((cs) => cs.state?.waiting?.message !== void 0).map((cs) => ({
|
|
253
|
+
type: "container-waiting",
|
|
254
|
+
message: cs.state?.waiting?.message ?? "container waiting",
|
|
255
|
+
severity: 4,
|
|
256
|
+
proposedFix: waitingProposedFix(pod),
|
|
257
|
+
sourceRef: {
|
|
258
|
+
name: pod.metadata?.name ?? "unknown pod",
|
|
259
|
+
namespace: pod.metadata?.namespace ?? "unknown namespace",
|
|
260
|
+
kind: "Pod",
|
|
261
|
+
apiGroup: "v1"
|
|
262
|
+
},
|
|
263
|
+
occurrenceCount: 1
|
|
264
|
+
}));
|
|
289
265
|
}
|
|
290
266
|
},
|
|
291
267
|
{
|
|
292
268
|
detectErrors: (pod) => {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
},
|
|
307
|
-
occurrenceCount: cs.restartCount
|
|
308
|
-
};
|
|
309
|
-
});
|
|
269
|
+
return (pod.status?.containerStatuses ?? []).filter((cs) => cs.restartCount > 0).map((cs) => ({
|
|
270
|
+
type: "containers-restarting",
|
|
271
|
+
message: `container=${cs.name} restarted ${cs.restartCount} times`,
|
|
272
|
+
severity: 4,
|
|
273
|
+
proposedFix: restartingPodProposedFixes(pod),
|
|
274
|
+
sourceRef: {
|
|
275
|
+
name: pod.metadata?.name ?? "unknown pod",
|
|
276
|
+
namespace: pod.metadata?.namespace ?? "unknown namespace",
|
|
277
|
+
kind: "Pod",
|
|
278
|
+
apiGroup: "v1"
|
|
279
|
+
},
|
|
280
|
+
occurrenceCount: cs.restartCount
|
|
281
|
+
}));
|
|
310
282
|
}
|
|
311
283
|
}
|
|
312
284
|
];
|
|
@@ -315,22 +287,18 @@ const detectErrorsInPods = (pods) => detectErrorsInObjects(pods, podErrorMappers
|
|
|
315
287
|
const deploymentErrorMappers = [
|
|
316
288
|
{
|
|
317
289
|
detectErrors: (deployment) => {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
},
|
|
331
|
-
occurrenceCount: 1
|
|
332
|
-
};
|
|
333
|
-
});
|
|
290
|
+
return (deployment.status?.conditions ?? []).filter((c) => c.status === "False").filter((c) => c.message !== void 0).map((c) => ({
|
|
291
|
+
type: "condition-message-present",
|
|
292
|
+
message: c.message ?? "",
|
|
293
|
+
severity: 6,
|
|
294
|
+
sourceRef: {
|
|
295
|
+
name: deployment.metadata?.name ?? "unknown hpa",
|
|
296
|
+
namespace: deployment.metadata?.namespace ?? "unknown namespace",
|
|
297
|
+
kind: "Deployment",
|
|
298
|
+
apiGroup: "apps/v1"
|
|
299
|
+
},
|
|
300
|
+
occurrenceCount: 1
|
|
301
|
+
}));
|
|
334
302
|
}
|
|
335
303
|
}
|
|
336
304
|
];
|
|
@@ -339,18 +307,17 @@ const detectErrorsInDeployments = (deployments) => detectErrorsInObjects(deploym
|
|
|
339
307
|
const hpaErrorMappers = [
|
|
340
308
|
{
|
|
341
309
|
detectErrors: (hpa) => {
|
|
342
|
-
|
|
343
|
-
if (((_b = (_a = hpa.spec) == null ? void 0 : _a.maxReplicas) != null ? _b : -1) === ((_c = hpa.status) == null ? void 0 : _c.currentReplicas)) {
|
|
310
|
+
if ((hpa.spec?.maxReplicas ?? -1) === hpa.status?.currentReplicas) {
|
|
344
311
|
return [
|
|
345
312
|
{
|
|
346
313
|
type: "hpa-max-current-replicas",
|
|
347
|
-
message: `Current number of replicas (${
|
|
314
|
+
message: `Current number of replicas (${hpa.status?.currentReplicas}) is equal to the configured max number of replicas (${hpa.spec?.maxReplicas ?? -1})`,
|
|
348
315
|
severity: 8,
|
|
349
316
|
sourceRef: {
|
|
350
|
-
name:
|
|
351
|
-
namespace:
|
|
317
|
+
name: hpa.metadata?.name ?? "unknown hpa",
|
|
318
|
+
namespace: hpa.metadata?.namespace ?? "unknown namespace",
|
|
352
319
|
kind: "HorizontalPodAutoscaler",
|
|
353
|
-
apiGroup: "autoscaling/
|
|
320
|
+
apiGroup: "autoscaling/v2"
|
|
354
321
|
},
|
|
355
322
|
occurrenceCount: 1
|
|
356
323
|
}
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/catalog-entity-constants.ts","../src/permissions.ts","../src/util/response.ts","../src/error-detection/common.ts","../src/error-detection/pods.ts","../src/error-detection/deployments.ts","../src/error-detection/hpas.ts","../src/error-detection/error-detection.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Annotation for specifying the API server of a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_API_SERVER = 'kubernetes.io/api-server';\n\n/**\n * Annotation for specifying the Certificate Authority of an API server for a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_API_SERVER_CA =\n 'kubernetes.io/api-server-certificate-authority';\n\n/**\n * Annotation for specifying the auth provider for a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AUTH_PROVIDER =\n 'kubernetes.io/auth-provider';\n\n/**\n * Annotation for specifying the oidc provider used to get id tokens for a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER =\n 'kubernetes.io/oidc-token-provider';\n\n/**\n * Annotation for specifying boolean value for skip metric lookup.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP =\n 'kubernetes.io/skip-metrics-lookup';\n\n/**\n * Annotation for specifying boolean value for skip tls verify.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY =\n 'kubernetes.io/skip-tls-verify';\n\n/**\n * Annotation for specifying the dashboard url for a Kubernetes cluster.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_DASHBOARD_URL =\n 'kubernetes.io/dashboard-url';\n\n/**\n * Annotation for specifying the dashboard app for a Kubernetes cluster.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_DASHBOARD_APP =\n 'kubernetes.io/dashboard-app';\n\n/**\n * Annotation for specifying the dashboard app parameters for a Kubernetes cluster.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS =\n 'kubernetes.io/dashboard-parameters';\n\n/**\n * Annotation for specifying the assume role use to authenticate with AWS.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE =\n 'kubernetes.io/aws-assume-role';\n\n/**\n * Annotation for specifying the AWS ID of a cluster when signing STS tokens\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AWS_CLUSTER_ID =\n 'kubernetes.io/x-k8s-aws-id';\n\n/**\n * Annotation for specifying an external id when communicating with AWS\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID =\n 'kubernetes.io/aws-external-id';\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createPermission } from '@backstage/plugin-permission-common';\n\n/** This permission is used to check access to the proxy endpoint\n * @public\n */\nexport const kubernetesProxyPermission = createPermission({\n name: 'kubernetes.proxy',\n attributes: {},\n});\n\n/**\n * List of all Kubernetes permissions.\n * @public\n */\nexport const kubernetesPermissions = [kubernetesProxyPermission];\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FetchResponse } from '@backstage/plugin-kubernetes-common';\nimport { GroupedResponses } from '../types';\n\n/** @public */\nexport const groupResponses = (\n fetchResponse: FetchResponse[],\n): GroupedResponses => {\n // TODO this could probably be a lodash groupBy\n return fetchResponse.reduce(\n (prev, next) => {\n switch (next.type) {\n case 'deployments':\n prev.deployments.push(...next.resources);\n break;\n case 'pods':\n prev.pods.push(...next.resources);\n break;\n case 'replicasets':\n prev.replicaSets.push(...next.resources);\n break;\n case 'services':\n prev.services.push(...next.resources);\n break;\n case 'configmaps':\n prev.configMaps.push(...next.resources);\n break;\n case 'horizontalpodautoscalers':\n prev.horizontalPodAutoscalers.push(...next.resources);\n break;\n case 'ingresses':\n prev.ingresses.push(...next.resources);\n break;\n case 'jobs':\n prev.jobs.push(...next.resources);\n break;\n case 'cronjobs':\n prev.cronJobs.push(...next.resources);\n break;\n case 'customresources':\n prev.customResources.push(...next.resources);\n break;\n case 'statefulsets':\n prev.statefulsets.push(...next.resources);\n break;\n case 'daemonsets':\n prev.daemonSets.push(...next.resources);\n break;\n default:\n }\n return prev;\n },\n {\n pods: [],\n replicaSets: [],\n deployments: [],\n services: [],\n configMaps: [],\n horizontalPodAutoscalers: [],\n ingresses: [],\n jobs: [],\n cronJobs: [],\n customResources: [],\n statefulsets: [],\n daemonSets: [],\n } as GroupedResponses,\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, ErrorMapper } from './types';\n\n// Run through the each error mapper for each object\n// returning a deduplicated (mostly) result\nexport const detectErrorsInObjects = <T>(\n objects: T[],\n errorMappers: ErrorMapper<T>[],\n): DetectedError[] => {\n return objects.flatMap(o => {\n return errorMappers.flatMap(em => em.detectErrors(o));\n });\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Pod, IContainerStatus, IContainer } from 'kubernetes-models/v1';\nimport { DetectedError, ErrorMapper, ProposedFix } from './types';\nimport { detectErrorsInObjects } from './common';\nimport lodash from 'lodash';\nimport { DateTime } from 'luxon';\n\nfunction isPodReadinessProbeUnready({\n container,\n containerStatus,\n}: ContainerSpecAndStatus): boolean {\n if (\n containerStatus.ready ||\n containerStatus.state?.running?.startedAt === undefined ||\n !container.readinessProbe\n ) {\n return false;\n }\n const startDateTime = DateTime.fromISO(\n containerStatus.state?.running?.startedAt,\n )\n // Add initial delay\n .plus({\n seconds: container.readinessProbe?.initialDelaySeconds ?? 0,\n })\n // Add failure threshold\n .plus({\n seconds:\n (container.readinessProbe?.periodSeconds ?? 0) *\n (container.readinessProbe?.failureThreshold ?? 0),\n });\n return startDateTime < DateTime.now();\n}\n\ninterface ContainerSpecAndStatus {\n container: IContainer;\n containerStatus: IContainerStatus;\n}\n\nconst podToContainerSpecsAndStatuses = (pod: Pod): ContainerSpecAndStatus[] => {\n const specs = lodash.groupBy(pod.spec?.containers ?? [], value => value.name);\n\n const result: ContainerSpecAndStatus[] = [];\n\n for (const cs of pod.status?.containerStatuses ?? []) {\n const spec = specs[cs.name];\n if (spec.length > 0) {\n result.push({\n container: spec[0],\n containerStatus: cs,\n });\n }\n }\n\n return result;\n};\n\nconst readinessProbeProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const firstUnreadyContainerStatus = pod.status?.containerStatuses?.find(\n cs => {\n return cs.ready === false;\n },\n );\n\n return {\n errorType: 'ReadinessProbeFailed',\n rootCauseExplanation: `The container ${firstUnreadyContainerStatus?.name} failed to start properly, but is not crashing`,\n actions: [\n 'Ensure that the container starts correctly locally',\n \"Check the container's logs looking for error during startup\",\n ],\n type: 'events',\n podName: pod.metadata?.name ?? '',\n };\n};\n\nconst restartingPodProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const lastTerminatedCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.lastState?.terminated !== undefined,\n );\n\n const lastTerminated = lastTerminatedCs?.lastState?.terminated;\n\n if (!lastTerminated) {\n return undefined;\n }\n\n switch (lastTerminated?.reason) {\n case 'Unknown':\n return {\n // TODO check this one, it's more likely a cluster issue\n errorType: 'Unknown',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'Error':\n return {\n errorType: 'Error',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'OOMKilled':\n return {\n errorType: 'OOMKilled',\n rootCauseExplanation: `The container \"${lastTerminatedCs.name}\" has crashed because it has tried to use more memory that it has been allocated`,\n actions: [\n `Increase the amount of memory assigned to the container`,\n 'Ensure the application is memory bounded and is not trying to consume too much memory',\n ],\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#exceed-a-container-s-memory-limit',\n type: 'docs',\n };\n default:\n return undefined;\n }\n};\n\nconst waitingProposedFix = (pod: Pod): ProposedFix | undefined => {\n const waitingCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.state?.waiting !== undefined,\n );\n\n const waiting = (pod.status?.containerStatuses ?? [])\n .map(cs => cs.state?.waiting)\n .find(w => w?.reason !== undefined);\n\n switch (waiting?.reason) {\n case 'InvalidImageName':\n return {\n errorType: 'InvalidImageName',\n rootCauseExplanation: 'The image in the pod is invalid',\n actions: ['Ensure the image name is correct and valid image name'],\n type: 'docs',\n docsLink:\n 'https://docs.docker.com/engine/reference/commandline/tag/#extended-description',\n };\n case 'ImagePullBackOff':\n return {\n errorType: 'ImagePullBackOff',\n rootCauseExplanation:\n 'The image either could not be found or Kubernetes does not have permission to pull it',\n actions: [\n 'Ensure the image name is correct',\n 'Ensure Kubernetes has permission to pull this image',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/concepts/containers/images/#imagepullbackoff',\n };\n case 'CrashLoopBackOff':\n return {\n errorType: 'CrashLoopBackOff',\n rootCauseExplanation: `The container ${waitingCs?.name} has crashed many times, it will be exponentially restarted until it stops crashing`,\n actions: ['Check the crash logs for stacktraces'],\n type: 'logs',\n container: waitingCs?.name ?? 'unknown',\n };\n case 'CreateContainerConfigError':\n return {\n errorType: 'CreateContainerConfigError',\n rootCauseExplanation:\n 'There is missing or mismatching configuration required to start the container',\n actions: [\n 'Ensure ConfigMaps references in the Deployment manifest are correct and the keys exist',\n 'Ensure Secrets references in the Deployment manifest are correct and the keys exist',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/',\n };\n default:\n return undefined;\n }\n};\n\nconst podErrorMappers: ErrorMapper<Pod>[] = [\n {\n detectErrors: pod => {\n return podToContainerSpecsAndStatuses(pod)\n .filter(isPodReadinessProbeUnready)\n .map(cs => ({\n type: 'readiness-probe-taking-too-long',\n message: `The container ${cs.container.name} failed to start properly, but is not crashing`,\n severity: 4,\n proposedFix: readinessProbeProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.state?.waiting?.message !== undefined)\n .map(cs => ({\n type: 'container-waiting',\n message: cs.state?.waiting?.message ?? 'container waiting',\n severity: 4,\n proposedFix: waitingProposedFix(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.restartCount > 0)\n .map(cs => ({\n type: 'containers-restarting',\n message: `container=${cs.name} restarted ${cs.restartCount} times`,\n severity: 4,\n proposedFix: restartingPodProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: cs.restartCount,\n }));\n },\n },\n];\n\nexport const detectErrorsInPods = (pods: Pod[]): DetectedError[] =>\n detectErrorsInObjects(pods, podErrorMappers);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, ErrorMapper } from './types';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { detectErrorsInObjects } from './common';\n\nconst deploymentErrorMappers: ErrorMapper<Deployment>[] = [\n {\n detectErrors: deployment => {\n return (deployment.status?.conditions ?? [])\n .filter(c => c.status === 'False')\n .filter(c => c.message !== undefined)\n .map(c => ({\n type: 'condition-message-present',\n message: c.message ?? '',\n severity: 6,\n sourceRef: {\n name: deployment.metadata?.name ?? 'unknown hpa',\n namespace: deployment.metadata?.namespace ?? 'unknown namespace',\n kind: 'Deployment',\n apiGroup: 'apps/v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n];\n\nexport const detectErrorsInDeployments = (\n deployments: Deployment[],\n): DetectedError[] =>\n detectErrorsInObjects(deployments, deploymentErrorMappers);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/v1';\nimport { DetectedError, ErrorMapper } from './types';\nimport { detectErrorsInObjects } from './common';\n\nconst hpaErrorMappers: ErrorMapper<HorizontalPodAutoscaler>[] = [\n {\n detectErrors: hpa => {\n if ((hpa.spec?.maxReplicas ?? -1) === hpa.status?.currentReplicas) {\n return [\n {\n type: 'hpa-max-current-replicas',\n message: `Current number of replicas (${\n hpa.status?.currentReplicas\n }) is equal to the configured max number of replicas (${\n hpa.spec?.maxReplicas ?? -1\n })`,\n severity: 8,\n sourceRef: {\n name: hpa.metadata?.name ?? 'unknown hpa',\n namespace: hpa.metadata?.namespace ?? 'unknown namespace',\n kind: 'HorizontalPodAutoscaler',\n apiGroup: 'autoscaling/v1',\n },\n occurrenceCount: 1,\n },\n ];\n }\n return [];\n },\n },\n];\n\nexport const detectErrorsInHpa = (\n hpas: HorizontalPodAutoscaler[],\n): DetectedError[] => detectErrorsInObjects(hpas, hpaErrorMappers);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, DetectedErrorsByCluster } from './types';\nimport { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';\nimport { groupResponses } from '../util';\nimport { detectErrorsInPods } from './pods';\nimport { detectErrorsInDeployments } from './deployments';\nimport { detectErrorsInHpa } from './hpas';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/v1';\nimport { Pod } from 'kubernetes-models/v1';\n\n/**\n * For each cluster try to find errors in each of the object types provided\n * returning a map of cluster names to errors in that cluster\n *\n * @public\n */\nexport const detectErrors = (\n objects: ObjectsByEntityResponse,\n): DetectedErrorsByCluster => {\n const errors: DetectedErrorsByCluster = new Map<string, DetectedError[]>();\n\n for (const clusterResponse of objects.items) {\n let clusterErrors: DetectedError[] = [];\n\n const groupedResponses = groupResponses(clusterResponse.resources);\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInPods(groupedResponses.pods as Pod[]),\n );\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInDeployments(groupedResponses.deployments as Deployment[]),\n );\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInHpa(\n groupedResponses.horizontalPodAutoscalers as HorizontalPodAutoscaler[],\n ),\n );\n\n errors.set(clusterResponse.cluster.name, clusterErrors);\n }\n\n return errors;\n};\n"],"names":["createPermission","DateTime","lodash","_a","_b"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/catalog-entity-constants.ts","../src/permissions.ts","../src/util/response.ts","../src/error-detection/common.ts","../src/error-detection/pods.ts","../src/error-detection/deployments.ts","../src/error-detection/hpas.ts","../src/error-detection/error-detection.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Annotation for specifying the API server of a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_API_SERVER = 'kubernetes.io/api-server';\n\n/**\n * Annotation for specifying the Certificate Authority of an API server for a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_API_SERVER_CA =\n 'kubernetes.io/api-server-certificate-authority';\n\n/**\n * Annotation for specifying the auth provider for a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AUTH_PROVIDER =\n 'kubernetes.io/auth-provider';\n\n/**\n * Annotation for specifying the oidc provider used to get id tokens for a Kubernetes cluster\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER =\n 'kubernetes.io/oidc-token-provider';\n\n/**\n * Annotation for specifying boolean value for skip metric lookup.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP =\n 'kubernetes.io/skip-metrics-lookup';\n\n/**\n * Annotation for specifying boolean value for skip tls verify.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY =\n 'kubernetes.io/skip-tls-verify';\n\n/**\n * Annotation for specifying the dashboard url for a Kubernetes cluster.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_DASHBOARD_URL =\n 'kubernetes.io/dashboard-url';\n\n/**\n * Annotation for specifying the dashboard app for a Kubernetes cluster.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_DASHBOARD_APP =\n 'kubernetes.io/dashboard-app';\n\n/**\n * Annotation for specifying the dashboard app parameters for a Kubernetes cluster.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS =\n 'kubernetes.io/dashboard-parameters';\n\n/**\n * Annotation for specifying the assume role use to authenticate with AWS.\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE =\n 'kubernetes.io/aws-assume-role';\n\n/**\n * Annotation for specifying the AWS ID of a cluster when signing STS tokens\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AWS_CLUSTER_ID =\n 'kubernetes.io/x-k8s-aws-id';\n\n/**\n * Annotation for specifying an external id when communicating with AWS\n *\n * @public\n */\nexport const ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID =\n 'kubernetes.io/aws-external-id';\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createPermission } from '@backstage/plugin-permission-common';\n\n/** This permission is used to check access to the proxy endpoint\n * @public\n */\nexport const kubernetesProxyPermission = createPermission({\n name: 'kubernetes.proxy',\n attributes: {},\n});\n\n/**\n * List of all Kubernetes permissions.\n * @public\n */\nexport const kubernetesPermissions = [kubernetesProxyPermission];\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FetchResponse } from '@backstage/plugin-kubernetes-common';\nimport { GroupedResponses } from '../types';\n\n/** @public */\nexport const groupResponses = (\n fetchResponse: FetchResponse[],\n): GroupedResponses => {\n // TODO this could probably be a lodash groupBy\n return fetchResponse.reduce(\n (prev, next) => {\n switch (next.type) {\n case 'deployments':\n prev.deployments.push(...next.resources);\n break;\n case 'pods':\n prev.pods.push(...next.resources);\n break;\n case 'replicasets':\n prev.replicaSets.push(...next.resources);\n break;\n case 'services':\n prev.services.push(...next.resources);\n break;\n case 'configmaps':\n prev.configMaps.push(...next.resources);\n break;\n case 'horizontalpodautoscalers':\n prev.horizontalPodAutoscalers.push(...next.resources);\n break;\n case 'ingresses':\n prev.ingresses.push(...next.resources);\n break;\n case 'jobs':\n prev.jobs.push(...next.resources);\n break;\n case 'cronjobs':\n prev.cronJobs.push(...next.resources);\n break;\n case 'customresources':\n prev.customResources.push(...next.resources);\n break;\n case 'statefulsets':\n prev.statefulsets.push(...next.resources);\n break;\n case 'daemonsets':\n prev.daemonSets.push(...next.resources);\n break;\n default:\n }\n return prev;\n },\n {\n pods: [],\n replicaSets: [],\n deployments: [],\n services: [],\n configMaps: [],\n horizontalPodAutoscalers: [],\n ingresses: [],\n jobs: [],\n cronJobs: [],\n customResources: [],\n statefulsets: [],\n daemonSets: [],\n } as GroupedResponses,\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, ErrorMapper } from './types';\n\n// Run through the each error mapper for each object\n// returning a deduplicated (mostly) result\nexport const detectErrorsInObjects = <T>(\n objects: T[],\n errorMappers: ErrorMapper<T>[],\n): DetectedError[] => {\n return objects.flatMap(o => {\n return errorMappers.flatMap(em => em.detectErrors(o));\n });\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Pod, IContainerStatus, IContainer } from 'kubernetes-models/v1';\nimport { DetectedError, ErrorMapper, ProposedFix } from './types';\nimport { detectErrorsInObjects } from './common';\nimport lodash from 'lodash';\nimport { DateTime } from 'luxon';\n\nfunction isPodReadinessProbeUnready({\n container,\n containerStatus,\n}: ContainerSpecAndStatus): boolean {\n if (\n containerStatus.ready ||\n containerStatus.state?.running?.startedAt === undefined ||\n !container.readinessProbe\n ) {\n return false;\n }\n const startDateTime = DateTime.fromISO(\n containerStatus.state?.running?.startedAt,\n )\n // Add initial delay\n .plus({\n seconds: container.readinessProbe?.initialDelaySeconds ?? 0,\n })\n // Add failure threshold\n .plus({\n seconds:\n (container.readinessProbe?.periodSeconds ?? 0) *\n (container.readinessProbe?.failureThreshold ?? 0),\n });\n return startDateTime < DateTime.now();\n}\n\ninterface ContainerSpecAndStatus {\n container: IContainer;\n containerStatus: IContainerStatus;\n}\n\nconst podToContainerSpecsAndStatuses = (pod: Pod): ContainerSpecAndStatus[] => {\n const specs = lodash.groupBy(pod.spec?.containers ?? [], value => value.name);\n\n const result: ContainerSpecAndStatus[] = [];\n\n for (const cs of pod.status?.containerStatuses ?? []) {\n const spec = specs[cs.name];\n if (spec.length > 0) {\n result.push({\n container: spec[0],\n containerStatus: cs,\n });\n }\n }\n\n return result;\n};\n\nconst readinessProbeProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const firstUnreadyContainerStatus = pod.status?.containerStatuses?.find(\n cs => {\n return cs.ready === false;\n },\n );\n\n return {\n errorType: 'ReadinessProbeFailed',\n rootCauseExplanation: `The container ${firstUnreadyContainerStatus?.name} failed to start properly, but is not crashing`,\n actions: [\n 'Ensure that the container starts correctly locally',\n \"Check the container's logs looking for error during startup\",\n ],\n type: 'events',\n podName: pod.metadata?.name ?? '',\n };\n};\n\nconst restartingPodProposedFixes = (pod: Pod): ProposedFix | undefined => {\n const lastTerminatedCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.lastState?.terminated !== undefined,\n );\n\n const lastTerminated = lastTerminatedCs?.lastState?.terminated;\n\n if (!lastTerminated) {\n return undefined;\n }\n\n switch (lastTerminated?.reason) {\n case 'Unknown':\n return {\n // TODO check this one, it's more likely a cluster issue\n errorType: 'Unknown',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'Error':\n return {\n errorType: 'Error',\n rootCauseExplanation: `This container has exited with a non-zero exit code (${lastTerminated.exitCode})`,\n actions: ['Check the crash logs for stacktraces'],\n container: lastTerminatedCs.name,\n type: 'logs',\n };\n case 'OOMKilled':\n return {\n errorType: 'OOMKilled',\n rootCauseExplanation: `The container \"${lastTerminatedCs.name}\" has crashed because it has tried to use more memory that it has been allocated`,\n actions: [\n `Increase the amount of memory assigned to the container`,\n 'Ensure the application is memory bounded and is not trying to consume too much memory',\n ],\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#exceed-a-container-s-memory-limit',\n type: 'docs',\n };\n default:\n return undefined;\n }\n};\n\nconst waitingProposedFix = (pod: Pod): ProposedFix | undefined => {\n const waitingCs = (pod.status?.containerStatuses ?? []).find(\n cs => cs.state?.waiting !== undefined,\n );\n\n const waiting = (pod.status?.containerStatuses ?? [])\n .map(cs => cs.state?.waiting)\n .find(w => w?.reason !== undefined);\n\n switch (waiting?.reason) {\n case 'InvalidImageName':\n return {\n errorType: 'InvalidImageName',\n rootCauseExplanation: 'The image in the pod is invalid',\n actions: ['Ensure the image name is correct and valid image name'],\n type: 'docs',\n docsLink:\n 'https://docs.docker.com/engine/reference/commandline/tag/#extended-description',\n };\n case 'ImagePullBackOff':\n return {\n errorType: 'ImagePullBackOff',\n rootCauseExplanation:\n 'The image either could not be found or Kubernetes does not have permission to pull it',\n actions: [\n 'Ensure the image name is correct',\n 'Ensure Kubernetes has permission to pull this image',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/concepts/containers/images/#imagepullbackoff',\n };\n case 'CrashLoopBackOff':\n return {\n errorType: 'CrashLoopBackOff',\n rootCauseExplanation: `The container ${waitingCs?.name} has crashed many times, it will be exponentially restarted until it stops crashing`,\n actions: ['Check the crash logs for stacktraces'],\n type: 'logs',\n container: waitingCs?.name ?? 'unknown',\n };\n case 'CreateContainerConfigError':\n return {\n errorType: 'CreateContainerConfigError',\n rootCauseExplanation:\n 'There is missing or mismatching configuration required to start the container',\n actions: [\n 'Ensure ConfigMaps references in the Deployment manifest are correct and the keys exist',\n 'Ensure Secrets references in the Deployment manifest are correct and the keys exist',\n ],\n type: 'docs',\n docsLink:\n 'https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/',\n };\n default:\n return undefined;\n }\n};\n\nconst podErrorMappers: ErrorMapper<Pod>[] = [\n {\n detectErrors: pod => {\n return podToContainerSpecsAndStatuses(pod)\n .filter(isPodReadinessProbeUnready)\n .map(cs => ({\n type: 'readiness-probe-taking-too-long',\n message: `The container ${cs.container.name} failed to start properly, but is not crashing`,\n severity: 4,\n proposedFix: readinessProbeProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.state?.waiting?.message !== undefined)\n .map(cs => ({\n type: 'container-waiting',\n message: cs.state?.waiting?.message ?? 'container waiting',\n severity: 4,\n proposedFix: waitingProposedFix(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n {\n detectErrors: pod => {\n return (pod.status?.containerStatuses ?? [])\n .filter(cs => cs.restartCount > 0)\n .map(cs => ({\n type: 'containers-restarting',\n message: `container=${cs.name} restarted ${cs.restartCount} times`,\n severity: 4,\n proposedFix: restartingPodProposedFixes(pod),\n sourceRef: {\n name: pod.metadata?.name ?? 'unknown pod',\n namespace: pod.metadata?.namespace ?? 'unknown namespace',\n kind: 'Pod',\n apiGroup: 'v1',\n },\n occurrenceCount: cs.restartCount,\n }));\n },\n },\n];\n\nexport const detectErrorsInPods = (pods: Pod[]): DetectedError[] =>\n detectErrorsInObjects(pods, podErrorMappers);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, ErrorMapper } from './types';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { detectErrorsInObjects } from './common';\n\nconst deploymentErrorMappers: ErrorMapper<Deployment>[] = [\n {\n detectErrors: deployment => {\n return (deployment.status?.conditions ?? [])\n .filter(c => c.status === 'False')\n .filter(c => c.message !== undefined)\n .map(c => ({\n type: 'condition-message-present',\n message: c.message ?? '',\n severity: 6,\n sourceRef: {\n name: deployment.metadata?.name ?? 'unknown hpa',\n namespace: deployment.metadata?.namespace ?? 'unknown namespace',\n kind: 'Deployment',\n apiGroup: 'apps/v1',\n },\n occurrenceCount: 1,\n }));\n },\n },\n];\n\nexport const detectErrorsInDeployments = (\n deployments: Deployment[],\n): DetectedError[] =>\n detectErrorsInObjects(deployments, deploymentErrorMappers);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/v2';\nimport { DetectedError, ErrorMapper } from './types';\nimport { detectErrorsInObjects } from './common';\n\nconst hpaErrorMappers: ErrorMapper<HorizontalPodAutoscaler>[] = [\n {\n detectErrors: hpa => {\n if ((hpa.spec?.maxReplicas ?? -1) === hpa.status?.currentReplicas) {\n return [\n {\n type: 'hpa-max-current-replicas',\n message: `Current number of replicas (${\n hpa.status?.currentReplicas\n }) is equal to the configured max number of replicas (${\n hpa.spec?.maxReplicas ?? -1\n })`,\n severity: 8,\n sourceRef: {\n name: hpa.metadata?.name ?? 'unknown hpa',\n namespace: hpa.metadata?.namespace ?? 'unknown namespace',\n kind: 'HorizontalPodAutoscaler',\n apiGroup: 'autoscaling/v2',\n },\n occurrenceCount: 1,\n },\n ];\n }\n return [];\n },\n },\n];\n\nexport const detectErrorsInHpa = (\n hpas: HorizontalPodAutoscaler[],\n): DetectedError[] => detectErrorsInObjects(hpas, hpaErrorMappers);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DetectedError, DetectedErrorsByCluster } from './types';\nimport { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';\nimport { groupResponses } from '../util';\nimport { detectErrorsInPods } from './pods';\nimport { detectErrorsInDeployments } from './deployments';\nimport { detectErrorsInHpa } from './hpas';\nimport { Deployment } from 'kubernetes-models/apps/v1';\nimport { HorizontalPodAutoscaler } from 'kubernetes-models/autoscaling/v2';\nimport { Pod } from 'kubernetes-models/v1';\n\n/**\n * For each cluster try to find errors in each of the object types provided\n * returning a map of cluster names to errors in that cluster\n *\n * @public\n */\nexport const detectErrors = (\n objects: ObjectsByEntityResponse,\n): DetectedErrorsByCluster => {\n const errors: DetectedErrorsByCluster = new Map<string, DetectedError[]>();\n\n for (const clusterResponse of objects.items) {\n let clusterErrors: DetectedError[] = [];\n\n const groupedResponses = groupResponses(clusterResponse.resources);\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInPods(groupedResponses.pods as Pod[]),\n );\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInDeployments(groupedResponses.deployments as Deployment[]),\n );\n\n clusterErrors = clusterErrors.concat(\n detectErrorsInHpa(\n groupedResponses.horizontalPodAutoscalers as HorizontalPodAutoscaler[],\n ),\n );\n\n errors.set(clusterResponse.cluster.name, clusterErrors);\n }\n\n return errors;\n};\n"],"names":["createPermission","DateTime","lodash"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JsonValue, JsonObject } from '@backstage/types';
|
|
2
|
-
import { V1Pod, V1Service, V1ConfigMap, V1Deployment, V1ReplicaSet, V1LimitRange, V1ResourceQuota,
|
|
2
|
+
import { V1Pod, V1Service, V1ConfigMap, V1Deployment, V1ReplicaSet, V1LimitRange, V1ResourceQuota, V2HorizontalPodAutoscaler, V1Job, V1CronJob, V1Ingress, V1StatefulSet, V1DaemonSet, PodStatus } from '@kubernetes/client-node';
|
|
3
3
|
import { Entity } from '@backstage/catalog-model';
|
|
4
4
|
import * as _backstage_plugin_permission_common from '@backstage/plugin-permission-common';
|
|
5
5
|
import { ObjectsByEntityResponse as ObjectsByEntityResponse$1, FetchResponse as FetchResponse$1 } from '@backstage/plugin-kubernetes-common';
|
|
@@ -125,7 +125,7 @@ interface ResourceQuotaFetchResponse {
|
|
|
125
125
|
/** @public */
|
|
126
126
|
interface HorizontalPodAutoscalersFetchResponse {
|
|
127
127
|
type: 'horizontalpodautoscalers';
|
|
128
|
-
resources: Array<
|
|
128
|
+
resources: Array<V2HorizontalPodAutoscaler>;
|
|
129
129
|
}
|
|
130
130
|
/** @public */
|
|
131
131
|
interface JobsFetchResponse {
|
|
@@ -201,7 +201,7 @@ interface DeploymentResources {
|
|
|
201
201
|
pods: V1Pod[];
|
|
202
202
|
replicaSets: V1ReplicaSet[];
|
|
203
203
|
deployments: V1Deployment[];
|
|
204
|
-
horizontalPodAutoscalers:
|
|
204
|
+
horizontalPodAutoscalers: V2HorizontalPodAutoscaler[];
|
|
205
205
|
}
|
|
206
206
|
/** @public */
|
|
207
207
|
interface GroupedResponses extends DeploymentResources {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-kubernetes-common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-next.0",
|
|
4
4
|
"description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "common-library"
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"luxon": "^3.0.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@backstage/cli": "^0.26.
|
|
56
|
+
"@backstage/cli": "^0.26.7-next.1"
|
|
57
57
|
},
|
|
58
58
|
"module": "dist/index.esm.js"
|
|
59
59
|
}
|