@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
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
*/
|
|
20
20
|
export { kubectlApply, applyManifest, readManifestDocuments } from "./kubectl.js";
|
|
21
21
|
export type { KubectlApplyArgs, ApplyManifestResult, AppliedRef, ApplyDeleteMode } from "./kubectl.js";
|
|
22
|
+
export { ensureSecret } from "./ensure-secret.js";
|
|
23
|
+
export type { EnsureSecretActivityArgs } from "./ensure-secret.js";
|
|
22
24
|
export { waitForArgoSync, defaultArgoStatusFetcher, ArgoSyncFailedError } from "./argo.js";
|
|
23
25
|
export type { WaitForArgoSyncArgs, ArgoAppStatus, ArgoStatusFetcher } from "./argo.js";
|
|
24
26
|
export { waitForReady, defaultResourceFetcher, apiResourceFetcher, ReadinessFailedError, readinessFor, isReady, firstTerminal, DEFAULT_READINESS, READINESS_OVERRIDES, } from "./wait-for-ready.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAMpG,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxF,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEpF,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,cAAc,EACd,cAAc,EACd,SAAS,GACV,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AACrG,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -116,6 +116,15 @@ export interface ApplyManifestResult {
|
|
|
116
116
|
applied: AppliedRef[];
|
|
117
117
|
/** Objects deleted because they carried chant's marker and are no longer declared. */
|
|
118
118
|
pruned: AppliedRef[];
|
|
119
|
+
/**
|
|
120
|
+
* Owned, no longer declared, and deliberately KEPT (#1830, epic #1365
|
|
121
|
+
* decision 5): Secrets carrying the `chant.intentius.io/generated-once`
|
|
122
|
+
* label never enter the prunable set — the stored bytes are the only copy
|
|
123
|
+
* of material chant never held. Reported loudly here and on the console;
|
|
124
|
+
* deletion is an explicit act (`kubectl delete`, or a future gated op),
|
|
125
|
+
* never a prune's. Present whenever the prune ran.
|
|
126
|
+
*/
|
|
127
|
+
retained?: AppliedRef[];
|
|
119
128
|
}
|
|
120
129
|
/** Read a manifest path — one file, or every YAML/JSON file in a directory. */
|
|
121
130
|
export declare function readManifestDocuments(path: string): Record<string, unknown>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kubectl.d.ts","sourceRoot":"","sources":["../../../src/op/activities/kubectl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAYH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"kubectl.d.ts","sourceRoot":"","sources":["../../../src/op/activities/kubectl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAYH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAK3E;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,sCAAsC;AACtC,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,sFAAsF;IACtF,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAiB7E;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjF;AAqHD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,gBAAgB,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,mBAAmB,CAAC,CAkE9B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,gBAAgB,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait-for-ready.d.ts","sourceRoot":"","sources":["../../../src/op/activities/wait-for-ready.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;;;;;;;;;;;;;;;GAiBG;AAIH,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,2DAA2D;AAC3D,MAAM,WAAW,SAAS;IACxB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACnC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAEhC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,SAAS,GAAG,oBAAoB,CAAC;AAE/E,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAG/B,CAAC;
|
|
1
|
+
{"version":3,"file":"wait-for-ready.d.ts","sourceRoot":"","sources":["../../../src/op/activities/wait-for-ready.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed step-builder wrappers for this lexicon's activities (chant #1288
|
|
3
|
+
* Stage 2 — "regenerate the step builders as fully typed wrappers"). Core
|
|
4
|
+
* cannot import a lexicon's `*Args` types (lexicons depend on core, not the
|
|
5
|
+
* other way around — see `packages/core/src/op/activity-contract.ts`'s module
|
|
6
|
+
* doc for the same layering constraint on Stage 1's contracts), so a fully
|
|
7
|
+
* typed `kubectlApply`/`waitForReady`/`ensureSecret` has to live beside the
|
|
8
|
+
* `*Args` interface it derives from: here, next to `./activities/kubectl.ts`
|
|
9
|
+
* etc. `opts`'s type in each wrapper below IS the activity's own `*Args`
|
|
10
|
+
* interface (via `Omit`/`WithStepRefs`) — never a hand-restated mirror — so
|
|
11
|
+
* `kubectlApply`/`waitForReady`/`ensureSecret`'s full option surface (the
|
|
12
|
+
* dozen-plus cross-field options on `kubectlApply` that Stage 1's zod
|
|
13
|
+
* contracts deliberately skipped rather than duplicate) is authoring-time
|
|
14
|
+
* typed for free, and stays in sync with the implementation by construction.
|
|
15
|
+
*
|
|
16
|
+
* Every field also accepts a {@link StepOutputRef} in its place
|
|
17
|
+
* ({@link WithStepRefs}, chant #1950) — a later step's args can consume an
|
|
18
|
+
* earlier step's declared output.
|
|
19
|
+
*
|
|
20
|
+
* `core`'s own `kubectlApply`/`waitForReady`/`ensureSecret` (in
|
|
21
|
+
* `@intentius/chant/op`, re-exported from `@intentius/chant-lexicon-temporal`
|
|
22
|
+
* for lexicon-agnostic single-import convenience) are UNCHANGED and produce
|
|
23
|
+
* byte-identical `ActivityStep` output for the same inputs — these are purely
|
|
24
|
+
* additive. Deliberately not swapped into the temporal barrel: that would
|
|
25
|
+
* make `@intentius/chant-lexicon-temporal` depend on this package (and on
|
|
26
|
+
* helm, for `helmInstall`) at runtime, which is exactly the "a worker image
|
|
27
|
+
* needs no kubectl binary" / "temporal stays product-agnostic" property the
|
|
28
|
+
* `op/activities/index.ts` module docs across this repo call out on purpose
|
|
29
|
+
* (activities were moved OUT of temporal into per-product lexicons for this
|
|
30
|
+
* reason; the step-builder layer shouldn't reintroduce the coupling from the
|
|
31
|
+
* other direction). An author who wants the typed surface imports it from
|
|
32
|
+
* here — `@intentius/chant-lexicon-k8s` — which a project using `kubectlApply`
|
|
33
|
+
* already depends on; existing `@intentius/chant-lexicon-temporal` imports
|
|
34
|
+
* keep working exactly as before, opting in only if the import is changed.
|
|
35
|
+
*/
|
|
36
|
+
import { type ActivityStep, type NamedActivityStep, type WithStepRefs } from "@intentius/chant/op";
|
|
37
|
+
import type { KubectlApplyArgs } from "./activities/kubectl.js";
|
|
38
|
+
import type { WaitForReadyArgs } from "./activities/wait-for-ready.js";
|
|
39
|
+
import type { EnsureSecretActivityArgs } from "./activities/ensure-secret.js";
|
|
40
|
+
/** Extra opts every wrapper below accepts alongside its activity's own fields. */
|
|
41
|
+
type StepOpts = {
|
|
42
|
+
profile?: ActivityStep["profile"];
|
|
43
|
+
id?: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Run `kubectl apply -f <manifest>` — the fully typed twin of core's
|
|
47
|
+
* `kubectlApply` step-builder shortcut (chant #1288 Stage 2). `opts` is
|
|
48
|
+
* {@link KubectlApplyArgs} itself (minus the positional `manifest`) — every
|
|
49
|
+
* field `applyManifest` accepts, including `deleteMode`, `force`,
|
|
50
|
+
* `fieldManager`, `documents`, is authoring-time typed here, not just the
|
|
51
|
+
* subset a hand-written zod mirror would bother restating. Defaults to the
|
|
52
|
+
* `longInfra` profile (override via `opts.profile`).
|
|
53
|
+
*/
|
|
54
|
+
export declare const kubectlApply: (manifest: string, opts?: WithStepRefs<Omit<KubectlApplyArgs, "manifest">> & StepOpts) => NamedActivityStep;
|
|
55
|
+
/**
|
|
56
|
+
* Poll a Kubernetes resource until it reports ready, driven by a data-only
|
|
57
|
+
* readiness spec (CRD-aware; #365) — the fully typed twin of core's
|
|
58
|
+
* `waitForReady`. `opts` is {@link WaitForReadyArgs} itself, minus the
|
|
59
|
+
* positional `kind`/`name`. Defaults to the `k8sWait` profile.
|
|
60
|
+
*/
|
|
61
|
+
export declare const waitForReady: (kind: string, name: string, opts?: WithStepRefs<Omit<WaitForReadyArgs, "kind" | "name">> & StepOpts) => NamedActivityStep;
|
|
62
|
+
/**
|
|
63
|
+
* Ensure a `generated-once` secret exists in the target store (#1829) — the
|
|
64
|
+
* fully typed twin of core's `ensureSecret`. `opts` is
|
|
65
|
+
* {@link EnsureSecretActivityArgs} itself, minus the positional `name`/`keys`.
|
|
66
|
+
*/
|
|
67
|
+
export declare const ensureSecret: (name: string, keys: string[], opts?: WithStepRefs<Omit<EnsureSecretActivityArgs, "name" | "keys">> & StepOpts) => NamedActivityStep;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=builders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../src/op/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAE3E,kFAAkF;AAClF,KAAK,QAAQ,GAAG;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,OAAO,YAAY,CAAC,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,GAAG,QAAQ,KACjE,iBAGF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,QAAQ,KACtE,iBAGF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,MAAM,MAAM,EAAE,EACd,OAAO,YAAY,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9E,iBAGF,CAAC"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AA6BjG,eAAO,MAAM,SAAS,EAAE,aAmsBvB,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Excluded from check auto-discovery by the "helper" filename filter.
|
|
7
7
|
*/
|
|
8
8
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
9
|
-
import {
|
|
9
|
+
import { docsToManifests, type K8sManifest } from "./k8s-helpers";
|
|
10
10
|
|
|
11
11
|
/** The always-present, in-cluster Argo destination. */
|
|
12
12
|
export const IN_CLUSTER_SERVER = "https://kubernetes.default.svc";
|
|
@@ -17,11 +17,7 @@ export const CLUSTER_SECRET_TYPE_LABEL = "argocd.argoproj.io/secret-type";
|
|
|
17
17
|
|
|
18
18
|
/** All manifests across every lexicon output. */
|
|
19
19
|
export function allManifests(ctx: PostSynthContext): K8sManifest[] {
|
|
20
|
-
|
|
21
|
-
for (const [, output] of ctx.outputs) {
|
|
22
|
-
manifests.push(...parseK8sManifests(getPrimaryOutput(output)));
|
|
23
|
-
}
|
|
24
|
-
return manifests;
|
|
20
|
+
return docsToManifests(ctx);
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
/** Manifests of a given Argo kind. */
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { createRequire } from "module";
|
|
15
15
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
16
16
|
import type { CrdFieldSchema } from "../../spec/parse";
|
|
17
|
-
import {
|
|
17
|
+
import { docsToManifests, type K8sManifest } from "./k8s-helpers";
|
|
18
18
|
|
|
19
19
|
export type { CrdFieldSchema };
|
|
20
20
|
|
|
@@ -70,11 +70,9 @@ export function specSchemaFor(manifest: K8sManifest): CrdFieldSchema | undefined
|
|
|
70
70
|
/** Every manifest in the build that has a shipped spec schema, with that schema. */
|
|
71
71
|
export function customResources(ctx: PostSynthContext): Array<{ manifest: K8sManifest; schema: CrdFieldSchema }> {
|
|
72
72
|
const out: Array<{ manifest: K8sManifest; schema: CrdFieldSchema }> = [];
|
|
73
|
-
for (const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (schema) out.push({ manifest, schema });
|
|
77
|
-
}
|
|
73
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
74
|
+
const schema = specSchemaFor(manifest);
|
|
75
|
+
if (schema) out.push({ manifest, schema });
|
|
78
76
|
}
|
|
79
77
|
return out;
|
|
80
78
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared helpers for Kubernetes post-synthesis lint rules.
|
|
3
3
|
*
|
|
4
|
-
* Provides
|
|
5
|
-
* extraction logic that handles all common workload types.
|
|
4
|
+
* Provides the `ctx.docs` → `K8sManifest[]` bridge every check reads through,
|
|
5
|
+
* and container extraction logic that handles all common workload types.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
export { getPrimaryOutput } from "@intentius/chant/lint/post-synth";
|
|
8
|
+
import { parseOutputDocs, type PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
9
|
+
export { getPrimaryOutput, getAdditionalFiles } from "@intentius/chant/lint/post-synth";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* A parsed Kubernetes manifest (loosely typed).
|
|
@@ -45,27 +45,36 @@ export interface K8sContainer {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
48
|
+
* Every parsed Kubernetes manifest across all lexicon outputs, via `ctx.docs`
|
|
49
|
+
* (chant #975) — the shared, parse-once view every k8s post-synth check
|
|
50
|
+
* reads, in place of the old per-check `parseK8sManifests(getPrimaryOutput(output))`
|
|
51
|
+
* splitter (chant #976). Two documents are dropped rather than passed through
|
|
52
|
+
* as a "manifest":
|
|
53
|
+
*
|
|
54
|
+
* - `d.error` — a document `parseOutputDocs` could not make sense of.
|
|
55
|
+
* - `d.file` — a document that came from a `SerializerResult.files` sidecar
|
|
56
|
+
* (a committed-encrypted secret's ciphertext, in this lexicon) rather than
|
|
57
|
+
* a lexicon's primary output. `parseK8sManifests` only ever saw
|
|
58
|
+
* `getPrimaryOutput(output)`, so a sidecar was invisible to every general
|
|
59
|
+
* manifest-consuming check — see `getAdditionalFiles`'s doc comment on why
|
|
60
|
+
* that separation is deliberate. Only `sops-helpers.ts`'s
|
|
61
|
+
* `resolveEncryptedSecretClaims` (WK8504/WK8503's producer join) reads
|
|
62
|
+
* `.files` explicitly; this bridge must keep it that way.
|
|
63
|
+
*
|
|
64
|
+
* `ctx.docs` is populated by every context chant itself builds (`chant
|
|
65
|
+
* build`, `@intentius/chant-test-utils`'s `createPostSynthContext` /
|
|
66
|
+
* `makePostSynthCtx*`) — see `PostSynthContext.docs`'s doc comment for why
|
|
67
|
+
* it is still optional at the type level. A handful of this lexicon's own
|
|
68
|
+
* hand-rolled `PostSynthContext` test literals (`post-synth.test.ts`'s
|
|
69
|
+
* `makeCtx`) predate that field and never set it; for those, fall back to
|
|
70
|
+
* parsing `ctx.outputs` directly with the same `parseOutputDocs` primitive,
|
|
71
|
+
* rather than silently returning no manifests.
|
|
50
72
|
*/
|
|
51
|
-
export function
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const trimmed = doc.trim();
|
|
57
|
-
if (trimmed === "" || trimmed === "---") continue;
|
|
58
|
-
try {
|
|
59
|
-
const parsed = parseYAML(trimmed);
|
|
60
|
-
if (typeof parsed === "object" && parsed !== null) {
|
|
61
|
-
manifests.push(parsed as K8sManifest);
|
|
62
|
-
}
|
|
63
|
-
} catch {
|
|
64
|
-
// Skip unparseable documents
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return manifests;
|
|
73
|
+
export function docsToManifests(ctx: PostSynthContext): K8sManifest[] {
|
|
74
|
+
const docs = ctx.docs ?? parseOutputDocs(ctx.outputs);
|
|
75
|
+
return docs
|
|
76
|
+
.filter((d) => !d.error && !d.file)
|
|
77
|
+
.map((d) => d.value as K8sManifest);
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
/**
|
|
@@ -103,6 +112,13 @@ export function extractPodSpec(
|
|
|
103
112
|
return (template?.spec as Record<string, unknown>) ?? null;
|
|
104
113
|
}
|
|
105
114
|
|
|
115
|
+
// KServe ServingRuntime/ClusterServingRuntime carry `containers` and
|
|
116
|
+
// `tolerations` directly on spec — no template wrapper, unlike the
|
|
117
|
+
// built-in workload kinds above.
|
|
118
|
+
case "ServingRuntime":
|
|
119
|
+
case "ClusterServingRuntime":
|
|
120
|
+
return spec;
|
|
121
|
+
|
|
106
122
|
default:
|
|
107
123
|
return null;
|
|
108
124
|
}
|
|
@@ -148,6 +164,53 @@ export const WORKLOAD_KINDS = new Set([
|
|
|
148
164
|
"CronJob",
|
|
149
165
|
]);
|
|
150
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Workload kinds that can request `nvidia.com/gpu` — the built-in workload
|
|
169
|
+
* kinds plus KServe's ServingRuntime/ClusterServingRuntime, which declare
|
|
170
|
+
* `containers`/`tolerations` directly on spec (see `extractPodSpec`).
|
|
171
|
+
*/
|
|
172
|
+
export const GPU_POD_KINDS = new Set([
|
|
173
|
+
...WORKLOAD_KINDS,
|
|
174
|
+
"ServingRuntime",
|
|
175
|
+
"ClusterServingRuntime",
|
|
176
|
+
]);
|
|
177
|
+
|
|
178
|
+
/** A Kubernetes toleration (loosely typed). */
|
|
179
|
+
export interface K8sToleration {
|
|
180
|
+
key?: string;
|
|
181
|
+
operator?: "Exists" | "Equal";
|
|
182
|
+
value?: string;
|
|
183
|
+
effect?: string;
|
|
184
|
+
[key: string]: unknown;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Resource name used for GPU requests/limits across the lexicon. */
|
|
188
|
+
export const NVIDIA_GPU_RESOURCE = "nvidia.com/gpu";
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* True when any container in `containers` requests or limits
|
|
192
|
+
* `nvidia.com/gpu`.
|
|
193
|
+
*/
|
|
194
|
+
export function requestsGpu(containers: K8sContainer[]): boolean {
|
|
195
|
+
return containers.some((c) => {
|
|
196
|
+
const requests = c.resources?.requests as Record<string, unknown> | undefined;
|
|
197
|
+
const limits = c.resources?.limits as Record<string, unknown> | undefined;
|
|
198
|
+
return Boolean(requests?.[NVIDIA_GPU_RESOURCE]) || Boolean(limits?.[NVIDIA_GPU_RESOURCE]);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* True when `tolerations` includes one that tolerates the `nvidia.com/gpu`
|
|
204
|
+
* taint — either an explicit `key: "nvidia.com/gpu"` toleration, or a
|
|
205
|
+
* wildcard `{ operator: "Exists" }` with no key (tolerates every taint).
|
|
206
|
+
*/
|
|
207
|
+
export function toleratesGpu(tolerations: unknown): boolean {
|
|
208
|
+
if (!Array.isArray(tolerations)) return false;
|
|
209
|
+
return (tolerations as K8sToleration[]).some(
|
|
210
|
+
(t) => t.key === NVIDIA_GPU_RESOURCE || (t.operator === "Exists" && !t.key),
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
151
214
|
/**
|
|
152
215
|
* Parse a Kubernetes memory string to bytes.
|
|
153
216
|
*
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper for the committed-encrypted secret checks: join each
|
|
3
|
+
* `declareSecret({ provenance: "committed-encrypted" })` in the entity map to
|
|
4
|
+
* the sidecar file the build emitted for it.
|
|
5
|
+
*
|
|
6
|
+
* The join has to go through `output.files`, not `getPrimaryOutput`. The
|
|
7
|
+
* ciphertext is deliberately kept OUT of the primary output — that is what
|
|
8
|
+
* makes applying an undecrypted Secret structurally impossible — so a check
|
|
9
|
+
* that reads only the primary output sees nothing at all here.
|
|
10
|
+
*
|
|
11
|
+
* Excluded from check auto-discovery by the "helper" filename filter.
|
|
12
|
+
*/
|
|
13
|
+
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
14
|
+
import type { CommittedEncryptedSecretDeclaration } from "@intentius/chant/secret-provenance";
|
|
15
|
+
import { getAdditionalFiles } from "./k8s-helpers";
|
|
16
|
+
import { committedEncryptedDeclarations, sidecarFilename, validateEncryptedSecretDocument, type EncryptedSecretDocument } from "../../sops/encrypted-secret-file";
|
|
17
|
+
|
|
18
|
+
/** One committed-encrypted declaration, joined to what the build emitted for it. */
|
|
19
|
+
export interface ResolvedEncryptedSecret {
|
|
20
|
+
/** The entity-map key the declaration was discovered under. */
|
|
21
|
+
entityName: string;
|
|
22
|
+
declaration: CommittedEncryptedSecretDeclaration;
|
|
23
|
+
/** The sidecar filename the declaration's path maps to. */
|
|
24
|
+
filename: string;
|
|
25
|
+
/** Undefined when the build emitted no such sidecar — the file did not resolve. */
|
|
26
|
+
text?: string;
|
|
27
|
+
/** Everything wrong with the emitted document. Empty when it is clean. */
|
|
28
|
+
problems: string[];
|
|
29
|
+
/** Parsed structure, when the document parsed at all. */
|
|
30
|
+
document?: EncryptedSecretDocument;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Every sidecar file across every lexicon output, keyed by filename. */
|
|
34
|
+
export function allAdditionalFiles(ctx: PostSynthContext): Map<string, string> {
|
|
35
|
+
const files = new Map<string, string>();
|
|
36
|
+
for (const [, output] of ctx.outputs) {
|
|
37
|
+
for (const [filename, content] of Object.entries(getAdditionalFiles(output))) {
|
|
38
|
+
files.set(filename, content);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return files;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Join every committed-encrypted declaration to its emitted sidecar,
|
|
46
|
+
* validating the document as it goes. A declaration with no sidecar comes
|
|
47
|
+
* back with `text` undefined and one problem naming the missing file.
|
|
48
|
+
*/
|
|
49
|
+
export function resolveEncryptedSecretClaims(ctx: PostSynthContext): ResolvedEncryptedSecret[] {
|
|
50
|
+
const declarations = committedEncryptedDeclarations(ctx.entities);
|
|
51
|
+
if (declarations.size === 0) return [];
|
|
52
|
+
|
|
53
|
+
const files = allAdditionalFiles(ctx);
|
|
54
|
+
const resolved: ResolvedEncryptedSecret[] = [];
|
|
55
|
+
|
|
56
|
+
for (const [entityName, declaration] of declarations) {
|
|
57
|
+
const filename = sidecarFilename(declaration.file);
|
|
58
|
+
const text = files.get(filename);
|
|
59
|
+
if (text === undefined) {
|
|
60
|
+
resolved.push({
|
|
61
|
+
entityName,
|
|
62
|
+
declaration,
|
|
63
|
+
filename,
|
|
64
|
+
problems: [
|
|
65
|
+
`the build emitted no file for "${declaration.file}" — ` +
|
|
66
|
+
`the declared ciphertext did not resolve`,
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const { problems, document } = validateEncryptedSecretDocument(text, declaration);
|
|
72
|
+
resolved.push({ entityName, declaration, filename, text, problems, document });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
package/dist/rules/wk8005.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
|
const SENSITIVE_NAME_PATTERN = /password|token|key|secret/i;
|
|
13
13
|
|
|
@@ -18,37 +18,32 @@ export const wk8005: PostSynthCheck = {
|
|
|
18
18
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
19
19
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
20
20
|
|
|
21
|
-
for (const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has hardcoded value for sensitive env var "${envVar.name}" — use secretKeyRef instead`,
|
|
48
|
-
entity: resourceName,
|
|
49
|
-
lexicon: "k8s",
|
|
50
|
-
});
|
|
51
|
-
}
|
|
21
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
22
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
23
|
+
|
|
24
|
+
const containers = extractContainers(manifest);
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
26
|
+
|
|
27
|
+
for (const container of containers) {
|
|
28
|
+
if (!Array.isArray(container.env)) continue;
|
|
29
|
+
|
|
30
|
+
for (const envVar of container.env) {
|
|
31
|
+
if (
|
|
32
|
+
typeof envVar.name === "string" &&
|
|
33
|
+
SENSITIVE_NAME_PATTERN.test(envVar.name) &&
|
|
34
|
+
envVar.value !== undefined &&
|
|
35
|
+
envVar.value !== null &&
|
|
36
|
+
typeof envVar.value === "string" &&
|
|
37
|
+
envVar.value !== "" &&
|
|
38
|
+
!envVar.valueFrom
|
|
39
|
+
) {
|
|
40
|
+
diagnostics.push({
|
|
41
|
+
checkId: "WK8005",
|
|
42
|
+
severity: "error",
|
|
43
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has hardcoded value for sensitive env var "${envVar.name}" — use secretKeyRef instead`,
|
|
44
|
+
entity: resourceName,
|
|
45
|
+
lexicon: "k8s",
|
|
46
|
+
});
|
|
52
47
|
}
|
|
53
48
|
}
|
|
54
49
|
}
|
package/dist/rules/wk8006.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, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
10
10
|
|
|
11
11
|
export const wk8006: PostSynthCheck = {
|
|
12
12
|
id: "WK8006",
|
|
@@ -15,49 +15,44 @@ export const wk8006: PostSynthCheck = {
|
|
|
15
15
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
16
16
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
17
17
|
|
|
18
|
-
for (const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
18
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
19
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
20
|
+
|
|
21
|
+
const containers = extractContainers(manifest);
|
|
22
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
23
|
+
|
|
24
|
+
for (const container of containers) {
|
|
25
|
+
const image = container.image;
|
|
26
|
+
if (typeof image !== "string" || image === "") continue;
|
|
27
|
+
|
|
28
|
+
// Split off digest (@sha256:...) — those are pinned and fine
|
|
29
|
+
if (image.includes("@")) continue;
|
|
30
|
+
|
|
31
|
+
// Extract the tag portion (after the last colon that isn't part of a port)
|
|
32
|
+
// Images can be: name, name:tag, registry:port/name, registry:port/name:tag
|
|
33
|
+
const slashIndex = image.lastIndexOf("/");
|
|
34
|
+
const afterSlash = slashIndex >= 0 ? image.slice(slashIndex + 1) : image;
|
|
35
|
+
const colonIndex = afterSlash.lastIndexOf(":");
|
|
36
|
+
|
|
37
|
+
if (colonIndex === -1) {
|
|
38
|
+
// No tag at all
|
|
39
|
+
diagnostics.push({
|
|
40
|
+
checkId: "WK8006",
|
|
41
|
+
severity: "warning",
|
|
42
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" uses untagged image "${image}" — specify an explicit version tag`,
|
|
43
|
+
entity: resourceName,
|
|
44
|
+
lexicon: "k8s",
|
|
45
|
+
});
|
|
46
|
+
} else {
|
|
47
|
+
const tag = afterSlash.slice(colonIndex + 1);
|
|
48
|
+
if (tag === "latest") {
|
|
43
49
|
diagnostics.push({
|
|
44
50
|
checkId: "WK8006",
|
|
45
51
|
severity: "warning",
|
|
46
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" uses
|
|
52
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" uses :latest tag on image "${image}" — use a specific version tag`,
|
|
47
53
|
entity: resourceName,
|
|
48
54
|
lexicon: "k8s",
|
|
49
55
|
});
|
|
50
|
-
} else {
|
|
51
|
-
const tag = afterSlash.slice(colonIndex + 1);
|
|
52
|
-
if (tag === "latest") {
|
|
53
|
-
diagnostics.push({
|
|
54
|
-
checkId: "WK8006",
|
|
55
|
-
severity: "warning",
|
|
56
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" uses :latest tag on image "${image}" — use a specific version tag`,
|
|
57
|
-
entity: resourceName,
|
|
58
|
-
lexicon: "k8s",
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
56
|
}
|
|
62
57
|
}
|
|
63
58
|
}
|
package/dist/rules/wk8041.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
|
/**
|
|
13
13
|
* Known API key patterns and their descriptions.
|
|
@@ -35,33 +35,28 @@ export const wk8041: PostSynthCheck = {
|
|
|
35
35
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
36
36
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
37
37
|
|
|
38
|
-
for (const
|
|
39
|
-
|
|
40
|
-
const manifests = parseK8sManifests(yaml);
|
|
38
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
39
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const containers = extractContainers(manifest);
|
|
42
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
for (const container of containers) {
|
|
45
|
+
if (!Array.isArray(container.env)) continue;
|
|
47
46
|
|
|
48
|
-
for (const
|
|
49
|
-
if (
|
|
47
|
+
for (const envVar of container.env) {
|
|
48
|
+
if (typeof envVar.value !== "string" || envVar.value === "") continue;
|
|
50
49
|
|
|
51
|
-
for (const
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
lexicon: "k8s",
|
|
62
|
-
});
|
|
63
|
-
break; // One match per env var is sufficient
|
|
64
|
-
}
|
|
50
|
+
for (const { pattern, label } of API_KEY_PATTERNS) {
|
|
51
|
+
if (pattern.test(envVar.value)) {
|
|
52
|
+
diagnostics.push({
|
|
53
|
+
checkId: "WK8041",
|
|
54
|
+
severity: "error",
|
|
55
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has a ${label} hardcoded in env var "${envVar.name ?? "(unnamed)"}" — use a Secret reference instead`,
|
|
56
|
+
entity: resourceName,
|
|
57
|
+
lexicon: "k8s",
|
|
58
|
+
});
|
|
59
|
+
break; // One match per env var is sufficient
|
|
65
60
|
}
|
|
66
61
|
}
|
|
67
62
|
}
|