@intentius/chant-lexicon-k8s 0.46.0 → 0.50.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/dist/components/kubectl-apply.d.ts +5 -0
- package/dist/components/kubectl-apply.d.ts.map +1 -1
- package/dist/composites/flux-app.d.ts +12 -0
- package/dist/composites/flux-app.d.ts.map +1 -1
- package/dist/composites/index.d.ts +8 -0
- package/dist/composites/index.d.ts.map +1 -1
- package/dist/composites/inference-service.d.ts +86 -0
- package/dist/composites/inference-service.d.ts.map +1 -0
- package/dist/composites/model.d.ts +80 -0
- package/dist/composites/model.d.ts.map +1 -0
- package/dist/composites/operator-stack.d.ts +183 -0
- package/dist/composites/operator-stack.d.ts.map +1 -0
- package/dist/composites/vllm-serving-runtime.d.ts +100 -0
- package/dist/composites/vllm-serving-runtime.d.ts.map +1 -0
- package/dist/crd/crd-sources.d.ts.map +1 -1
- package/dist/deep-observe-hooks.d.ts.map +1 -1
- package/dist/generated/index.d.ts +167 -40
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/group-namespace.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +41 -33
- package/dist/kube/apply.d.ts.map +1 -1
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/post-synth/argo-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/crd-schema-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/k8s-helpers.d.ts +56 -6
- package/dist/lint/post-synth/k8s-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/sops-helpers.d.ts +38 -0
- package/dist/lint/post-synth/sops-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8005.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8006.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8041.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8042.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8101.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8102.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8103.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8104.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8105.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8201.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8202.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8203.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8204.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8205.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8207.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8208.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8209.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8301.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8302.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8303.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8304.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8305.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8306.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8401.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8402.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8403.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8404.d.ts +12 -0
- package/dist/lint/post-synth/wk8404.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8405.d.ts +13 -0
- package/dist/lint/post-synth/wk8405.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8406.d.ts +12 -0
- package/dist/lint/post-synth/wk8406.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8407.d.ts +21 -0
- package/dist/lint/post-synth/wk8407.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8503.d.ts +39 -0
- package/dist/lint/post-synth/wk8503.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8504.d.ts +28 -0
- package/dist/lint/post-synth/wk8504.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8505.d.ts +28 -0
- package/dist/lint/post-synth/wk8505.d.ts.map +1 -0
- package/dist/manifest.json +1 -1
- package/dist/meta.json +1039 -68
- package/dist/okf/index.md +26 -2
- package/dist/okf/rules/FLUX002.md +0 -1
- package/dist/okf/rules/WK8404.md +11 -0
- package/dist/okf/rules/WK8405.md +17 -0
- package/dist/okf/rules/WK8406.md +11 -0
- package/dist/okf/rules/WK8407.md +15 -0
- package/dist/okf/rules/WK8503.md +17 -0
- package/dist/okf/rules/WK8504.md +11 -0
- package/dist/okf/rules/WK8505.md +15 -0
- package/dist/okf/types/AWSClusterControllerIdentity.md +14 -0
- package/dist/okf/types/AWSManagedCluster.md +14 -0
- package/dist/okf/types/AWSManagedControlPlane.md +14 -0
- package/dist/okf/types/AWSManagedMachinePool.md +14 -0
- package/dist/okf/types/CAPICluster.md +14 -0
- package/dist/okf/types/Certificate.md +1 -0
- package/dist/okf/types/ClusterResourceSet.md +14 -0
- package/dist/okf/types/ClusterServingRuntime.md +14 -0
- package/dist/okf/types/{Cluster.md → CnpgCluster.md} +2 -2
- package/dist/okf/types/DBInstance.md +14 -0
- package/dist/okf/types/{Bucket.md → FluxBucket.md} +2 -6
- package/dist/okf/types/HelmChartProxy.md +14 -0
- package/dist/okf/types/IamRole.md +14 -0
- package/dist/okf/types/InferenceService.md +19 -0
- package/dist/okf/types/InfisicalDynamicSecret.md +4 -0
- package/dist/okf/types/InfisicalSecret.md +4 -0
- package/dist/okf/types/Kustomization.md +1 -0
- package/dist/okf/types/MachinePool.md +14 -0
- package/dist/okf/types/PDB.md +1 -0
- package/dist/okf/types/PodIdentityAssociation.md +14 -0
- package/dist/okf/types/Policy.md +14 -0
- package/dist/okf/types/S3Bucket.md +14 -0
- package/dist/okf/types/ServingRuntime.md +14 -0
- package/dist/okf/types/StatefulSet.md +1 -0
- package/dist/okf/types/User.md +14 -0
- package/dist/op/activities/ensure-secret.d.ts +41 -0
- package/dist/op/activities/ensure-secret.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +2 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/kubectl.d.ts +9 -0
- package/dist/op/activities/kubectl.d.ts.map +1 -1
- package/dist/op/activities/wait-for-ready.d.ts.map +1 -1
- package/dist/op/builders.d.ts +69 -0
- package/dist/op/builders.d.ts.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/rules/argo-helpers.ts +2 -6
- package/dist/rules/crd-schema-helpers.ts +4 -6
- package/dist/rules/k8s-helpers.ts +87 -24
- package/dist/rules/sops-helpers.ts +76 -0
- package/dist/rules/wk8005.ts +27 -32
- package/dist/rules/wk8006.ts +33 -38
- package/dist/rules/wk8041.ts +19 -24
- package/dist/rules/wk8042.ts +17 -22
- package/dist/rules/wk8101.ts +29 -34
- package/dist/rules/wk8102.ts +13 -18
- package/dist/rules/wk8103.ts +17 -22
- package/dist/rules/wk8104.ts +30 -35
- package/dist/rules/wk8105.ts +16 -21
- package/dist/rules/wk8201.ts +26 -31
- package/dist/rules/wk8202.ts +17 -22
- package/dist/rules/wk8203.ts +17 -22
- package/dist/rules/wk8204.ts +46 -51
- package/dist/rules/wk8205.ts +27 -32
- package/dist/rules/wk8207.ts +14 -19
- package/dist/rules/wk8208.ts +14 -19
- package/dist/rules/wk8209.ts +14 -19
- package/dist/rules/wk8301.ts +25 -30
- package/dist/rules/wk8302.ts +19 -24
- package/dist/rules/wk8303.ts +23 -26
- package/dist/rules/wk8304.ts +35 -40
- package/dist/rules/wk8305.ts +39 -42
- package/dist/rules/wk8306.ts +20 -25
- package/dist/rules/wk8401.ts +59 -64
- package/dist/rules/wk8402.ts +13 -18
- package/dist/rules/wk8403.ts +32 -37
- package/dist/rules/wk8404.ts +49 -0
- package/dist/rules/wk8405.ts +85 -0
- package/dist/rules/wk8406.ts +55 -0
- package/dist/rules/wk8407.ts +66 -0
- package/dist/rules/wk8503.ts +220 -0
- package/dist/rules/wk8504.ts +51 -0
- package/dist/rules/wk8505.ts +63 -0
- package/dist/secret-labels.d.ts +31 -0
- package/dist/secret-labels.d.ts.map +1 -0
- package/dist/secret-store.d.ts +73 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/sops/encrypted-secret-file.d.ts +52 -0
- package/dist/sops/encrypted-secret-file.d.ts.map +1 -0
- package/dist/sops/entity.d.ts +31 -0
- package/dist/sops/entity.d.ts.map +1 -0
- package/dist/teardown.d.ts.map +1 -1
- package/dist/types/index.d.ts +261 -9
- package/package.json +4 -4
- package/src/components/kubectl-apply.ts +5 -0
- package/src/composites/composites.test.ts +556 -0
- package/src/composites/flux-app.ts +23 -0
- package/src/composites/index.ts +15 -0
- package/src/composites/inference-service.ts +140 -0
- package/src/composites/model.ts +150 -0
- package/src/composites/operator-stack.ts +385 -0
- package/src/composites/vllm-serving-runtime.test.ts +167 -0
- package/src/composites/vllm-serving-runtime.ts +196 -0
- package/src/crd/cnpg.test.ts +8 -3
- package/src/crd/crd-sources.ts +183 -0
- package/src/crd/parser.test.ts +14 -0
- package/src/deep-observe-hooks.ts +24 -0
- package/src/deep-observe.test.ts +89 -0
- package/src/generated/index.d.ts +261 -9
- package/src/generated/index.ts +167 -40
- package/src/generated/lexicon-k8s.json +1039 -68
- package/src/generated/operations.json +272 -0
- package/src/group-namespace.test.ts +31 -0
- package/src/group-namespace.ts +13 -0
- package/src/index.ts +17 -0
- package/src/kube/apply.ts +5 -0
- package/src/lint/audit-catalog.ts +7 -0
- package/src/lint/post-synth/argo-helpers.ts +2 -6
- package/src/lint/post-synth/crd-schema-helpers.ts +4 -6
- package/src/lint/post-synth/index.ts +14 -0
- package/src/lint/post-synth/k8s-helpers.test.ts +26 -9
- package/src/lint/post-synth/k8s-helpers.ts +87 -24
- package/src/lint/post-synth/post-synth.test.ts +826 -0
- package/src/lint/post-synth/sops-helpers.ts +76 -0
- package/src/lint/post-synth/wk8005.ts +27 -32
- package/src/lint/post-synth/wk8006.ts +33 -38
- package/src/lint/post-synth/wk8041.ts +19 -24
- package/src/lint/post-synth/wk8042.ts +17 -22
- package/src/lint/post-synth/wk8101.ts +29 -34
- package/src/lint/post-synth/wk8102.ts +13 -18
- package/src/lint/post-synth/wk8103.ts +17 -22
- package/src/lint/post-synth/wk8104.ts +30 -35
- package/src/lint/post-synth/wk8105.ts +16 -21
- package/src/lint/post-synth/wk8201.ts +26 -31
- package/src/lint/post-synth/wk8202.ts +17 -22
- package/src/lint/post-synth/wk8203.ts +17 -22
- package/src/lint/post-synth/wk8204.ts +46 -51
- package/src/lint/post-synth/wk8205.ts +27 -32
- package/src/lint/post-synth/wk8207.ts +14 -19
- package/src/lint/post-synth/wk8208.ts +14 -19
- package/src/lint/post-synth/wk8209.ts +14 -19
- package/src/lint/post-synth/wk8301.ts +25 -30
- package/src/lint/post-synth/wk8302.ts +19 -24
- package/src/lint/post-synth/wk8303.ts +23 -26
- package/src/lint/post-synth/wk8304.ts +35 -40
- package/src/lint/post-synth/wk8305.ts +39 -42
- package/src/lint/post-synth/wk8306.ts +20 -25
- package/src/lint/post-synth/wk8401.ts +59 -64
- package/src/lint/post-synth/wk8402.ts +13 -18
- package/src/lint/post-synth/wk8403.ts +32 -37
- package/src/lint/post-synth/wk8404.ts +49 -0
- package/src/lint/post-synth/wk8405.ts +85 -0
- package/src/lint/post-synth/wk8406.ts +55 -0
- package/src/lint/post-synth/wk8407.ts +66 -0
- package/src/lint/post-synth/wk8503.ts +220 -0
- package/src/lint/post-synth/wk8504.ts +51 -0
- package/src/lint/post-synth/wk8505.ts +63 -0
- package/src/op/activities/ensure-secret.ts +71 -0
- package/src/op/activities/index.ts +7 -0
- package/src/op/activities/kubectl.test.ts +32 -0
- package/src/op/activities/kubectl.ts +28 -5
- package/src/op/activities/wait-for-ready.test.ts +34 -0
- package/src/op/activities/wait-for-ready.ts +26 -0
- package/src/op/builders.test.ts +82 -0
- package/src/op/builders.ts +95 -0
- package/src/plugin.ts +21 -2
- package/src/secret-labels.ts +36 -0
- package/src/secret-store.test.ts +184 -0
- package/src/secret-store.ts +165 -0
- package/src/serializer.ts +41 -2
- package/src/sops/encrypted-secret-file.test.ts +333 -0
- package/src/sops/encrypted-secret-file.ts +264 -0
- package/src/sops/entity.ts +53 -0
- package/src/teardown.test.ts +36 -0
- package/src/teardown.ts +14 -0
- package/src/testdata/sops/db-credentials.sops.yaml +23 -0
package/dist/rules/wk8204.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
14
|
-
import {
|
|
14
|
+
import { docsToManifests, extractContainers, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
15
15
|
|
|
16
16
|
export const wk8204: PostSynthCheck = {
|
|
17
17
|
id: "WK8204",
|
|
@@ -20,63 +20,58 @@ export const wk8204: PostSynthCheck = {
|
|
|
20
20
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
21
21
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
22
22
|
|
|
23
|
-
for (const
|
|
24
|
-
|
|
25
|
-
const manifests = parseK8sManifests(yaml);
|
|
23
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
24
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
27
|
+
const podSpec = extractPodSpec(manifest);
|
|
28
|
+
if (!podSpec) continue;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
// Check pod-level securityContext
|
|
31
|
+
const podSecCtx = podSpec.securityContext as Record<string, unknown> | undefined;
|
|
32
|
+
const podRunAsNonRoot = podSecCtx?.runAsNonRoot === true;
|
|
33
|
+
const podRunAsUser = podSecCtx?.runAsUser;
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
35
|
+
const containers = extractContainers(manifest);
|
|
36
|
+
for (const container of containers) {
|
|
37
|
+
const secCtx = container.securityContext;
|
|
38
|
+
const containerRunAsNonRoot = secCtx?.runAsNonRoot === true;
|
|
39
|
+
const containerRunAsUser = secCtx?.runAsUser;
|
|
38
40
|
|
|
39
|
-
const
|
|
40
|
-
for (const container of containers) {
|
|
41
|
-
const secCtx = container.securityContext;
|
|
42
|
-
const containerRunAsNonRoot = secCtx?.runAsNonRoot === true;
|
|
43
|
-
const containerRunAsUser = secCtx?.runAsUser;
|
|
41
|
+
const hasRunAsNonRoot = podRunAsNonRoot || containerRunAsNonRoot;
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
43
|
+
if (!hasRunAsNonRoot) {
|
|
44
|
+
diagnostics.push({
|
|
45
|
+
checkId: "WK8204",
|
|
46
|
+
severity: "warning",
|
|
47
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not set runAsNonRoot: true — set it at container or pod level`,
|
|
48
|
+
entity: resourceName,
|
|
49
|
+
lexicon: "k8s",
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
// runAsNonRoot is true — check for explicit runAsUser
|
|
55
|
+
const effectiveRunAsUser = containerRunAsUser ?? podRunAsUser;
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
57
|
+
if (effectiveRunAsUser === 0) {
|
|
58
|
+
// Contradictory: runAsNonRoot: true + runAsUser: 0
|
|
59
|
+
diagnostics.push({
|
|
60
|
+
checkId: "WK8204",
|
|
61
|
+
severity: "warning",
|
|
62
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has runAsNonRoot: true but runAsUser: 0 — these settings are contradictory and the container will fail to start`,
|
|
63
|
+
entity: resourceName,
|
|
64
|
+
lexicon: "k8s",
|
|
65
|
+
});
|
|
66
|
+
} else if (effectiveRunAsUser === undefined || effectiveRunAsUser === null) {
|
|
67
|
+
// runAsNonRoot: true but no explicit UID
|
|
68
|
+
diagnostics.push({
|
|
69
|
+
checkId: "WK8204",
|
|
70
|
+
severity: "warning",
|
|
71
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has runAsNonRoot: true but no explicit runAsUser — set a numeric UID to ensure the container doesn't run as root`,
|
|
72
|
+
entity: resourceName,
|
|
73
|
+
lexicon: "k8s",
|
|
74
|
+
});
|
|
80
75
|
}
|
|
81
76
|
}
|
|
82
77
|
}
|
package/dist/rules/wk8205.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8205: PostSynthCheck = {
|
|
13
13
|
id: "WK8205",
|
|
@@ -16,37 +16,32 @@ export const wk8205: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not drop ALL capabilities — add securityContext.capabilities.drop: ["ALL"]`,
|
|
46
|
-
entity: resourceName,
|
|
47
|
-
lexicon: "k8s",
|
|
48
|
-
});
|
|
49
|
-
}
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
21
|
+
|
|
22
|
+
const containers = extractContainers(manifest);
|
|
23
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
24
|
+
|
|
25
|
+
for (const container of containers) {
|
|
26
|
+
const secCtx = container.securityContext;
|
|
27
|
+
const capabilities = secCtx?.capabilities as Record<string, unknown> | undefined;
|
|
28
|
+
const drop = capabilities?.drop;
|
|
29
|
+
|
|
30
|
+
const dropsAll =
|
|
31
|
+
Array.isArray(drop) &&
|
|
32
|
+
drop.some(
|
|
33
|
+
(cap) =>
|
|
34
|
+
(typeof cap === "string" && cap.toUpperCase() === "ALL"),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
if (!dropsAll) {
|
|
38
|
+
diagnostics.push({
|
|
39
|
+
checkId: "WK8205",
|
|
40
|
+
severity: "warning",
|
|
41
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not drop ALL capabilities — add securityContext.capabilities.drop: ["ALL"]`,
|
|
42
|
+
entity: resourceName,
|
|
43
|
+
lexicon: "k8s",
|
|
44
|
+
});
|
|
50
45
|
}
|
|
51
46
|
}
|
|
52
47
|
}
|
package/dist/rules/wk8207.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8207: PostSynthCheck = {
|
|
13
13
|
id: "WK8207",
|
|
@@ -16,27 +16,22 @@ export const wk8207: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const podSpec = extractPodSpec(manifest);
|
|
23
|
+
if (!podSpec) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (!podSpec) continue;
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
27
|
+
if (podSpec.hostNetwork === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8207",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `${manifest.kind} "${resourceName}" uses hostNetwork: true — this bypasses network isolation and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
package/dist/rules/wk8208.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8208: PostSynthCheck = {
|
|
13
13
|
id: "WK8208",
|
|
@@ -16,27 +16,22 @@ export const wk8208: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const podSpec = extractPodSpec(manifest);
|
|
23
|
+
if (!podSpec) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (!podSpec) continue;
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
27
|
+
if (podSpec.hostPID === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8208",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `${manifest.kind} "${resourceName}" uses hostPID: true — this allows visibility into all host processes and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
package/dist/rules/wk8209.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8209: PostSynthCheck = {
|
|
13
13
|
id: "WK8209",
|
|
@@ -16,27 +16,22 @@ export const wk8209: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const podSpec = extractPodSpec(manifest);
|
|
23
|
+
if (!podSpec) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (!podSpec) continue;
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
27
|
+
if (podSpec.hostIPC === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8209",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `${manifest.kind} "${resourceName}" uses hostIPC: true — this exposes host shared memory segments and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
package/dist/rules/wk8301.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
15
|
-
import {
|
|
15
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
16
16
|
|
|
17
17
|
export const wk8301: PostSynthCheck = {
|
|
18
18
|
id: "WK8301",
|
|
@@ -21,35 +21,30 @@ export const wk8301: PostSynthCheck = {
|
|
|
21
21
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
22
22
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
23
23
|
|
|
24
|
-
for (const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" is missing ${missing.join(" and ")}`,
|
|
49
|
-
entity: resourceName,
|
|
50
|
-
lexicon: "k8s",
|
|
51
|
-
});
|
|
52
|
-
}
|
|
24
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
25
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
26
|
+
// CronJobs and Jobs are short-lived — probes are less relevant
|
|
27
|
+
if (manifest.kind === "Job" || manifest.kind === "CronJob") continue;
|
|
28
|
+
|
|
29
|
+
const containers = extractContainers(manifest);
|
|
30
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
31
|
+
|
|
32
|
+
for (const container of containers) {
|
|
33
|
+
// No declared port → no inbound traffic → nothing to HTTP-probe.
|
|
34
|
+
if (!container.ports || container.ports.length === 0) continue;
|
|
35
|
+
|
|
36
|
+
const missing: string[] = [];
|
|
37
|
+
if (!container.livenessProbe) missing.push("livenessProbe");
|
|
38
|
+
if (!container.readinessProbe) missing.push("readinessProbe");
|
|
39
|
+
|
|
40
|
+
if (missing.length > 0) {
|
|
41
|
+
diagnostics.push({
|
|
42
|
+
checkId: "WK8301",
|
|
43
|
+
severity: "warning",
|
|
44
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" is missing ${missing.join(" and ")}`,
|
|
45
|
+
entity: resourceName,
|
|
46
|
+
lexicon: "k8s",
|
|
47
|
+
});
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
50
|
}
|
package/dist/rules/wk8302.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
9
|
-
import {
|
|
9
|
+
import { docsToManifests } from "./k8s-helpers";
|
|
10
10
|
|
|
11
11
|
export const wk8302: PostSynthCheck = {
|
|
12
12
|
id: "WK8302",
|
|
@@ -15,29 +15,24 @@ export const wk8302: PostSynthCheck = {
|
|
|
15
15
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
16
16
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
17
17
|
|
|
18
|
-
for (const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
message: `Deployment "${resourceName}" has ${replicas ?? 1} replica(s) — consider at least 2 for high availability`,
|
|
37
|
-
entity: resourceName,
|
|
38
|
-
lexicon: "k8s",
|
|
39
|
-
});
|
|
40
|
-
}
|
|
18
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
19
|
+
if (manifest.kind !== "Deployment") continue;
|
|
20
|
+
|
|
21
|
+
const resourceName = manifest.metadata?.name ?? "Deployment";
|
|
22
|
+
const spec = manifest.spec;
|
|
23
|
+
if (!spec) continue;
|
|
24
|
+
|
|
25
|
+
const replicas = spec.replicas;
|
|
26
|
+
|
|
27
|
+
// If replicas is omitted, Kubernetes defaults to 1
|
|
28
|
+
if (replicas === undefined || replicas === null || replicas === 1) {
|
|
29
|
+
diagnostics.push({
|
|
30
|
+
checkId: "WK8302",
|
|
31
|
+
severity: "info",
|
|
32
|
+
message: `Deployment "${resourceName}" has ${replicas ?? 1} replica(s) — consider at least 2 for high availability`,
|
|
33
|
+
entity: resourceName,
|
|
34
|
+
lexicon: "k8s",
|
|
35
|
+
});
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
|
package/dist/rules/wk8303.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests } from "./k8s-helpers";
|
|
11
11
|
import type { K8sManifest } from "./k8s-helpers";
|
|
12
12
|
|
|
13
13
|
export const wk8303: PostSynthCheck = {
|
|
@@ -17,38 +17,35 @@ export const wk8303: PostSynthCheck = {
|
|
|
17
17
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
18
18
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
const yaml = getPrimaryOutput(output);
|
|
22
|
-
const manifests = parseK8sManifests(yaml);
|
|
20
|
+
const manifests = docsToManifests(ctx);
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
// Collect all PDB selectors to match against Deployments
|
|
23
|
+
const pdbSelectors = collectPdbSelectors(manifests);
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
for (const manifest of manifests) {
|
|
26
|
+
if (manifest.kind !== "Deployment") continue;
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const spec = manifest.spec;
|
|
29
|
+
if (!spec) continue;
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const replicas = spec.replicas;
|
|
32
|
+
// Only check HA deployments (replicas >= 2)
|
|
33
|
+
if (typeof replicas !== "number" || replicas < 2) continue;
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
const resourceName = manifest.metadata?.name ?? "Deployment";
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
// Check if any PDB targets this Deployment's labels
|
|
38
|
+
const selector = spec.selector as Record<string, unknown> | undefined;
|
|
39
|
+
const matchLabels = selector?.matchLabels as Record<string, string> | undefined;
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
41
|
+
if (!matchLabels || !hasCoveringPdb(matchLabels, pdbSelectors)) {
|
|
42
|
+
diagnostics.push({
|
|
43
|
+
checkId: "WK8303",
|
|
44
|
+
severity: "info",
|
|
45
|
+
message: `Deployment "${resourceName}" has ${replicas} replicas but no PodDisruptionBudget — add a PDB to ensure availability during voluntary disruptions`,
|
|
46
|
+
entity: resourceName,
|
|
47
|
+
lexicon: "k8s",
|
|
48
|
+
});
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
51
|
|
package/dist/rules/wk8304.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8304: PostSynthCheck = {
|
|
13
13
|
id: "WK8304",
|
|
@@ -16,51 +16,46 @@ export const wk8304: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (manifest.kind !== "Ingress") continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const annotations = manifest.metadata?.annotations as Record<string, string> | undefined;
|
|
23
|
+
if (!annotations) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const sslRedirect = annotations["alb.ingress.kubernetes.io/ssl-redirect"];
|
|
26
|
+
if (!sslRedirect) continue;
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const resourceName = manifest.metadata?.name ?? "Ingress";
|
|
29
|
+
const certArn = annotations["alb.ingress.kubernetes.io/certificate-arn"];
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
31
|
+
if (!certArn) {
|
|
32
|
+
diagnostics.push({
|
|
33
|
+
checkId: "WK8304",
|
|
34
|
+
severity: "warning",
|
|
35
|
+
message: `Ingress "${resourceName}" has ssl-redirect annotation but no certificate-arn — HTTPS redirect will fail without a TLS certificate`,
|
|
36
|
+
entity: resourceName,
|
|
37
|
+
lexicon: "k8s",
|
|
38
|
+
});
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
} catch {
|
|
62
|
-
// Can't parse listen-ports — skip this check
|
|
42
|
+
// Check listen-ports includes HTTPS
|
|
43
|
+
const listenPorts = annotations["alb.ingress.kubernetes.io/listen-ports"];
|
|
44
|
+
if (listenPorts) {
|
|
45
|
+
try {
|
|
46
|
+
const ports = JSON.parse(listenPorts) as Array<Record<string, number>>;
|
|
47
|
+
const hasHttps = ports.some((p) => "HTTPS" in p);
|
|
48
|
+
if (!hasHttps) {
|
|
49
|
+
diagnostics.push({
|
|
50
|
+
checkId: "WK8304",
|
|
51
|
+
severity: "warning",
|
|
52
|
+
message: `Ingress "${resourceName}" has ssl-redirect but listen-ports does not include HTTPS`,
|
|
53
|
+
entity: resourceName,
|
|
54
|
+
lexicon: "k8s",
|
|
55
|
+
});
|
|
63
56
|
}
|
|
57
|
+
} catch {
|
|
58
|
+
// Can't parse listen-ports — skip this check
|
|
64
59
|
}
|
|
65
60
|
}
|
|
66
61
|
}
|