@intentius/chant-lexicon-helm 0.57.0 → 0.58.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/commands.d.ts.map +1 -1
- package/dist/integrity.json +2 -2
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-lineage.d.ts +10 -0
- package/dist/lint/audit-lineage.d.ts.map +1 -0
- package/dist/manifest.json +1 -1
- package/dist/op/activities/helm.d.ts +1 -1
- package/dist/op/activities/helm.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +4 -4
- package/dist/op/builders.d.ts +7 -7
- package/package.json +2 -2
- package/src/commands.test.ts +26 -1
- package/src/commands.ts +14 -0
- package/src/index.ts +3 -3
- package/src/lint/audit-catalog.ts +5 -1
- package/src/lint/audit-lineage.ts +62 -0
- package/src/op/activities/helm.test.ts +6 -2
- package/src/op/activities/helm.ts +4 -17
- package/src/op/activities/index.ts +4 -4
- package/src/op/builders.ts +7 -7
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,oCAAoC,CAAC;AAG5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAwEtD,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA8BzE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAqBxE;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,SAAS,EAAE,qBAAqB,GAC/B,MAAM,CAqBR;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA6B/D;AAwGD,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,oCAAoC,CAAC;AAG5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAwEtD,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA8BzE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAqBxE;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,SAAS,EAAE,qBAAqB,GAC/B,MAAM,CAqBR;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA6B/D;AAwGD,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CA2C7G;AAoDD,2CAA2C;AAC3C,wBAAgB,gBAAgB,IAAI,YAAY,CA4B/C"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "526933c04346b013042d73549162c3ac08c28d69b0a8d46f9a1bc1f30f6a9a1d",
|
|
5
5
|
"meta.json": "14243c5730a07c6a6edc35ddd351438547d58df5cf345f2233a355b0c7611ccc",
|
|
6
6
|
"types/index.d.ts": "5377696ca8698cd2999e4680feb8e8e4b54a7b49fb603a87b2f27356114d1794",
|
|
7
7
|
"rules/chart-metadata.ts": "8f3377e893d5e2828460b7fe5924fca098334245a9a2fdb90f6b67e490eaf091",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"skills/chant-helm-patterns.md": "9e79e6a46391da46709d8aa57e2825a7cd9eb981cd923f02ad60836c49b2561e",
|
|
37
37
|
"skills/chant-helm-security.md": "bfc367eabceed2e84f1cf94501b407df78aeed963cec104f24a321d0962063c9"
|
|
38
38
|
},
|
|
39
|
-
"composite": "
|
|
39
|
+
"composite": "2e8feeb1af653ef40ce335a8c96adc0a116f529fb04a18e17c93f9584537b947"
|
|
40
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-catalog.d.ts","sourceRoot":"","sources":["../../src/lint/audit-catalog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAqD,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"audit-catalog.d.ts","sourceRoot":"","sources":["../../src/lint/audit-catalog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAqD,KAAK,QAAQ,EAAgB,MAAM,gCAAgC,CAAC;AAGhI,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAwBrD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prior art for these audit rules: the open-source tools whose checks cover the
|
|
3
|
+
* same condition, credited per rule. See packages/core/src/audit/prior-art.ts for
|
|
4
|
+
* the registry, the relation vocabulary, and why this is credit rather than
|
|
5
|
+
* authority. Kept by hand; the prior-art sweep (scripts/prior-art-sweep.ts) reports
|
|
6
|
+
* when a credited tool's index no longer lists a rule cited here.
|
|
7
|
+
*/
|
|
8
|
+
import type { Lineage } from "@intentius/chant/audit/catalog";
|
|
9
|
+
export declare const helmAuditLineage: Record<string, Lineage[]>;
|
|
10
|
+
//# sourceMappingURL=audit-lineage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-lineage.d.ts","sourceRoot":"","sources":["../../src/lint/audit-lineage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAoDtD,CAAC"}
|
package/dist/manifest.json
CHANGED
|
@@ -186,7 +186,7 @@ export declare function helmInstallInputDigest(args: HelmInstallArgs): string;
|
|
|
186
186
|
* finished deploy into a failed activity — the record is observability, not
|
|
187
187
|
* part of the deploy itself.
|
|
188
188
|
*
|
|
189
|
-
* Uses longInfra profile
|
|
189
|
+
* Uses the longInfra profile: 20m timeout, three attempts backing off from 30s.
|
|
190
190
|
*/
|
|
191
191
|
export declare function helmInstall(args: HelmInstallArgs, signal?: AbortSignal): Promise<HelmInstallResult>;
|
|
192
192
|
//# sourceMappingURL=helm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helm.d.ts","sourceRoot":"","sources":["../../../src/op/activities/helm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helm.d.ts","sourceRoot":"","sources":["../../../src/op/activities/helm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* helm Op activities — resolved by the core activity registry when a project's
|
|
3
3
|
* `chant.config.ts` lists the `helm` lexicon. `helmInstall` shells out to the
|
|
4
|
-
* helm CLI
|
|
5
|
-
* (#809) so helm's imperative activity lives with its product
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* helm CLI, retried under the step's profile; relocated from the hosting
|
|
5
|
+
* lexicon (#809) so helm's imperative activity lives with its product. The
|
|
6
|
+
* `helmInstall` step builder stays in core and reaches authors through
|
|
7
|
+
* `@intentius/chant/op` like the other core builders.
|
|
8
8
|
*/
|
|
9
9
|
export { helmInstall, helmInstallInputDigest, CapabilityProfileMismatchError, PinnedRenderNotFoundError, PinnedRenderIntegrityError, PinnedInstallInputError, PinnedProfileMismatchError, } from "./helm.js";
|
|
10
10
|
export type { HelmInstallArgs, HelmInstallResult, HelmCapabilityProfile, HelmProfileAssertionOutcome, } from "./helm.js";
|
package/dist/op/builders.d.ts
CHANGED
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
* Every field also accepts a {@link StepOutputRef} in its place
|
|
14
14
|
* ({@link WithStepRefs}, chant #1950).
|
|
15
15
|
*
|
|
16
|
-
* `core`'s own `helmInstall`/`helmInstallPinned` (in `@intentius/chant/op
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
16
|
+
* `core`'s own `helmInstall`/`helmInstallPinned` (in `@intentius/chant/op`)
|
|
17
|
+
* are UNCHANGED and produce byte-identical `ActivityStep` output for the same
|
|
18
|
+
* inputs — these are purely additive. Deliberately not swapped into core's
|
|
19
|
+
* barrel (see `lexicons/k8s/src/op/builders.ts`'s module doc for why: it
|
|
20
|
+
* would make core depend on this package at runtime, undoing the
|
|
21
|
+
* product-agnostic split #809 did). An author who wants the typed surface
|
|
22
|
+
* imports it from
|
|
23
23
|
* here — `@intentius/chant-lexicon-helm` — which a project using
|
|
24
24
|
* `helmInstall` already depends on.
|
|
25
25
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-helm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.58.0",
|
|
4
4
|
"description": "Helm chart lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"@types/js-yaml": "^4.0.9"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
|
-
"@intentius/chant": "^0.
|
|
89
|
+
"@intentius/chant": "^0.58.0",
|
|
90
90
|
"typescript": "^5.9.3",
|
|
91
91
|
"zod": "^4.3.6"
|
|
92
92
|
}
|
package/src/commands.test.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { dirname, join } from "node:path";
|
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
20
|
|
|
21
21
|
import { RESERVED_COMMAND_NAMES } from "@intentius/chant/cli/command-group";
|
|
22
|
-
import { formatRenderDiff, formatRenderRecords, helmCommandGroup } from "./commands";
|
|
22
|
+
import { formatRenderDiff, formatRenderLiveDiff, formatRenderRecords, helmCommandGroup } from "./commands";
|
|
23
23
|
import { helmPlugin } from "./plugin";
|
|
24
24
|
import { renderStability } from "./render-digest";
|
|
25
25
|
import { persistHelmRender } from "./render-store";
|
|
@@ -417,6 +417,31 @@ describe("formatRenderDiff", () => {
|
|
|
417
417
|
});
|
|
418
418
|
});
|
|
419
419
|
|
|
420
|
+
describe("formatRenderLiveDiff", () => {
|
|
421
|
+
// #2181 - the bucket for a live value this render never set is `unclaimed`,
|
|
422
|
+
// which is a different fact from a property declared `heldElsewhere()`.
|
|
423
|
+
it("prints the unclaimed section for a live value the render never set", () => {
|
|
424
|
+
const out = formatRenderLiveDiff(`sha256:${"a".repeat(64)}`, "prod", {
|
|
425
|
+
drifted: [],
|
|
426
|
+
accepted: [],
|
|
427
|
+
unclaimed: [
|
|
428
|
+
{
|
|
429
|
+
name: "Deployment web/app",
|
|
430
|
+
type: "apps/v1 Deployment",
|
|
431
|
+
fields: [{ path: "spec.replicas", live: 7, heldBy: "hpa-controller", source: "field-manager" }],
|
|
432
|
+
},
|
|
433
|
+
],
|
|
434
|
+
held: [],
|
|
435
|
+
unchanged: [],
|
|
436
|
+
unobserved: [],
|
|
437
|
+
undeclaredEntities: [],
|
|
438
|
+
});
|
|
439
|
+
expect(out).toContain("1 unclaimed");
|
|
440
|
+
expect(out).toContain("UNCLAIMED (live values this render never sets; not drift):");
|
|
441
|
+
expect(out).toContain("spec.replicas: 7 [held by hpa-controller]");
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
420
445
|
describe("chant helm diff --live (#1250)", () => {
|
|
421
446
|
it("requires a content digest and an environment", async () => {
|
|
422
447
|
await expect(verb("diff").handler({ verb: "diff", rawArgs: ["--live"] })).rejects.toThrow(
|
package/src/commands.ts
CHANGED
|
@@ -334,10 +334,14 @@ function formatDeepValue(v: unknown): string {
|
|
|
334
334
|
/** The printed render-to-live diff report: property drift per document, then holes. */
|
|
335
335
|
export function formatRenderLiveDiff(contentDigest: string, environment: string, diff: DeepDiffResult): string {
|
|
336
336
|
const driftCount = diff.drifted.reduce((n, e) => n + e.changes.length, 0);
|
|
337
|
+
// Fields the render never sets (#2160). Live has them and this chart did not
|
|
338
|
+
// ask for them, so they are somebody else's, not a difference to reconcile.
|
|
339
|
+
const unclaimedCount = diff.unclaimed.reduce((n, e) => n + e.fields.length, 0);
|
|
337
340
|
const lines: string[] = [
|
|
338
341
|
`render ${contentDigest} vs live (${environment})`,
|
|
339
342
|
`${driftCount} property drift across ${diff.drifted.length} document(s), ` +
|
|
340
343
|
`${diff.accepted.length} accepted, ${diff.unchanged.length} unchanged` +
|
|
344
|
+
(unclaimedCount > 0 ? `, ${unclaimedCount} unclaimed` : "") +
|
|
341
345
|
(diff.unobserved.length > 0 ? `, ${diff.unobserved.length} unobserved` : "") +
|
|
342
346
|
(diff.undeclaredEntities.length > 0 ? `, ${diff.undeclaredEntities.length} undeclared` : ""),
|
|
343
347
|
];
|
|
@@ -356,6 +360,16 @@ export function formatRenderLiveDiff(contentDigest: string, environment: string,
|
|
|
356
360
|
}
|
|
357
361
|
}
|
|
358
362
|
}
|
|
363
|
+
if (diff.unclaimed.length > 0) {
|
|
364
|
+
lines.push("", "UNCLAIMED (live values this render never sets; not drift):");
|
|
365
|
+
for (const entity of diff.unclaimed) {
|
|
366
|
+
lines.push(` - ${entity.name} (${entity.type})`);
|
|
367
|
+
for (const field of entity.fields) {
|
|
368
|
+
const holder = field.heldBy ? ` [held by ${field.heldBy}]` : "";
|
|
369
|
+
lines.push(` ${field.path}: ${formatDeepValue(field.live)}${holder}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
359
373
|
if (diff.undeclaredEntities.length > 0) {
|
|
360
374
|
lines.push("", "UNDECLARED (live, not in this render):");
|
|
361
375
|
for (const name of diff.undeclaredEntities) lines.push(` - ${name}`);
|
package/src/index.ts
CHANGED
|
@@ -13,9 +13,9 @@ export { helmUpgradeCapability, createHelmUpgradeCapability, type HelmUpgradeInp
|
|
|
13
13
|
// Typed Op step-builder wrappers (chant #1288 Stage 2) — helmInstall/
|
|
14
14
|
// helmInstallPinned with authoring-time types derived from this lexicon's
|
|
15
15
|
// own HelmInstallArgs (see ./op/builders.ts's module doc for why these live
|
|
16
|
-
// here rather than in core
|
|
17
|
-
//
|
|
18
|
-
//
|
|
16
|
+
// here rather than in core). Opt-in: `@intentius/chant/op`'s same-named
|
|
17
|
+
// exports are core's original untyped builders, unchanged, for
|
|
18
|
+
// cloud-agnostic authoring.
|
|
19
19
|
export { helmInstall, helmInstallPinned } from "./op/builders";
|
|
20
20
|
|
|
21
21
|
// Resources
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* The helm lexicon's chant audit catalog — metadata for its post-synth rules
|
|
3
3
|
* (WHM Helm-chart rules). Contributed via helmPlugin.auditCatalog() (#687).
|
|
4
4
|
*/
|
|
5
|
-
import { auditRule, K8S_PSS, K8S_SECRETS, SCORECARD_PINNED, type RuleMeta } from "@intentius/chant/audit/catalog";
|
|
5
|
+
import { auditRule, K8S_PSS, K8S_SECRETS, SCORECARD_PINNED, type RuleMeta, applyLineage } from "@intentius/chant/audit/catalog";
|
|
6
|
+
import { helmAuditLineage } from "./audit-lineage";
|
|
6
7
|
|
|
7
8
|
export const helmAuditCatalog: Record<string, RuleMeta> = {
|
|
8
9
|
WHM005: auditRule("WHM005", "report-only", "guidance", "Sub-chart wrapper with no templates", "Deploy the upstream chart directly instead of an empty wrapper.", { category: "best-practice" }),
|
|
@@ -29,3 +30,6 @@ export const helmAuditCatalog: Record<string, RuleMeta> = {
|
|
|
29
30
|
WHM503: auditRule("WHM503", "merge-worthy", "guidance", "Pinned render carries Secret data", "Declare the value with runtimeSlot() or replace the Secret with HelmExternalSecret.", { authority: [K8S_SECRETS] }),
|
|
30
31
|
WHM504: auditRule("WHM504", "merge-worthy", "guidance", "Dead value assignment", "Remove supplied values that never survive coalescing (shadowed, disabled subchart, or unknown subchart).", { category: "correctness" }),
|
|
31
32
|
};
|
|
33
|
+
|
|
34
|
+
// Prior art credits live beside the rules in ./audit-lineage.ts (see core audit/prior-art.ts).
|
|
35
|
+
applyLineage(helmAuditCatalog, helmAuditLineage);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prior art for these audit rules: the open-source tools whose checks cover the
|
|
3
|
+
* same condition, credited per rule. See packages/core/src/audit/prior-art.ts for
|
|
4
|
+
* the registry, the relation vocabulary, and why this is credit rather than
|
|
5
|
+
* authority. Kept by hand; the prior-art sweep (scripts/prior-art-sweep.ts) reports
|
|
6
|
+
* when a credited tool's index no longer lists a rule cited here.
|
|
7
|
+
*/
|
|
8
|
+
import type { Lineage } from "@intentius/chant/audit/catalog";
|
|
9
|
+
|
|
10
|
+
export const helmAuditLineage: Record<string, Lineage[]> = {
|
|
11
|
+
WHM005: [
|
|
12
|
+
{ tool: "helm-lint", rule: "templatesDirExists", url: "https://github.com/helm/helm/blob/main/pkg/chart/v2/lint/rules/template.go", relation: "overlaps" },
|
|
13
|
+
],
|
|
14
|
+
WHM101: [
|
|
15
|
+
{ tool: "helm-lint", rule: "Chartfile (validateChartName, validateChartAPIVersion, validateChartVersion)", url: "https://github.com/helm/helm/blob/main/pkg/chart/v2/lint/rules/chartfile.go", relation: "equivalent" },
|
|
16
|
+
{ tool: "chart-testing", rule: "ct lint --chart-yaml-schema", url: "https://github.com/helm/chart-testing/blob/main/doc/ct_lint.md", relation: "overlaps" },
|
|
17
|
+
],
|
|
18
|
+
WHM103: [
|
|
19
|
+
{ tool: "helm-lint", rule: "Templates (render error)", url: "https://github.com/helm/helm/blob/main/pkg/chart/v2/lint/rules/template.go", relation: "equivalent" },
|
|
20
|
+
],
|
|
21
|
+
WHM302: [
|
|
22
|
+
{ tool: "kube-score", rule: "container-resources", url: "https://github.com/zegl/kube-score/blob/master/README_CHECKS.md", relation: "overlaps" },
|
|
23
|
+
{ tool: "kube-linter", rule: "unset-cpu-requirements", url: "https://github.com/stackrox/kube-linter/blob/main/docs/generated/checks.md#unset-cpu-requirements", relation: "overlaps" },
|
|
24
|
+
{ tool: "polaris", rule: "cpuRequestsMissing", url: "https://polaris.docs.fairwinds.com/checks/efficiency/", relation: "overlaps" },
|
|
25
|
+
],
|
|
26
|
+
WHM401: [
|
|
27
|
+
{ tool: "kube-score", rule: "container-image-tag", url: "https://github.com/zegl/kube-score/blob/master/README_CHECKS.md", relation: "equivalent" },
|
|
28
|
+
{ tool: "kics", rule: "Invalid Image Tag", url: "https://docs.kics.io/latest/queries/kubernetes-queries/583053b7-e632-46f0-b989-f81ff8045385/", relation: "equivalent" },
|
|
29
|
+
{ tool: "datree", rule: "ensure-image-pinned-version", url: "https://hub.datree.io/built-in-rules/ensure-image-pinned-version", relation: "equivalent" },
|
|
30
|
+
],
|
|
31
|
+
WHM402: [
|
|
32
|
+
{ tool: "kubesec", rule: "containers[] .securityContext .runAsNonRoot == true", url: "https://kubesec.io/basics/containers-securitycontext-runasnonroot-true/", relation: "equivalent" },
|
|
33
|
+
{ tool: "kics", rule: "Container Running As Root", url: "https://docs.kics.io/latest/queries/kubernetes-queries/cf34805e-3872-4c08-bf92-6ff7bb0cfadb/", relation: "equivalent" },
|
|
34
|
+
{ tool: "kube-score", rule: "container-security-context-user-group-id", url: "https://github.com/zegl/kube-score/blob/master/README_CHECKS.md", relation: "overlaps" },
|
|
35
|
+
],
|
|
36
|
+
WHM403: [
|
|
37
|
+
{ tool: "kubesec", rule: "containers[] .securityContext .readOnlyRootFilesystem == true", url: "https://kubesec.io/basics/containers-securitycontext-readonlyrootfilesystem-true/", relation: "equivalent" },
|
|
38
|
+
{ tool: "kics", rule: "Root Container Not Mounted Read-only", url: "https://docs.kics.io/latest/queries/kubernetes-queries/a9c2f49d-0671-4fc9-9ece-f4e261e128d0/", relation: "equivalent" },
|
|
39
|
+
{ tool: "kube-score", rule: "container-security-context-readonlyrootfilesystem", url: "https://github.com/zegl/kube-score/blob/master/README_CHECKS.md", relation: "equivalent" },
|
|
40
|
+
],
|
|
41
|
+
WHM404: [
|
|
42
|
+
{ tool: "kubesec", rule: "containers[] .securityContext .privileged == true", url: "https://kubesec.io/basics/containers-securitycontext-privileged-true/", relation: "equivalent" },
|
|
43
|
+
{ tool: "kics", rule: "Container Is Privileged", url: "https://docs.kics.io/latest/queries/kubernetes-queries/dd29336b-fe57-445b-a26e-e6aa867ae609/", relation: "equivalent" },
|
|
44
|
+
{ tool: "kube-score", rule: "container-security-context-privileged", url: "https://github.com/zegl/kube-score/blob/master/README_CHECKS.md", relation: "equivalent" },
|
|
45
|
+
],
|
|
46
|
+
WHM405: [
|
|
47
|
+
{ tool: "checkov", rule: "CKV_K8S_10", url: "https://www.checkov.io/5.Policy%20Index/kubernetes.html", relation: "overlaps" },
|
|
48
|
+
{ tool: "checkov", rule: "CKV_K8S_12", url: "https://www.checkov.io/5.Policy%20Index/kubernetes.html", relation: "overlaps" },
|
|
49
|
+
{ tool: "kubesec", rule: "containers[] .resources .limits .memory", url: "https://kubesec.io/basics/containers-resources-limits-memory/", relation: "overlaps" },
|
|
50
|
+
],
|
|
51
|
+
WHM407: [
|
|
52
|
+
{ tool: "kics", rule: "Using Kubernetes Native Secret Management", url: "https://docs.kics.io/latest/queries/kubernetes-queries/b9c83569-459b-4110-8f79-6305aa33cb37/", relation: "overlaps" },
|
|
53
|
+
],
|
|
54
|
+
WHM502: [
|
|
55
|
+
{ tool: "pluto", rule: "detect-files", url: "https://github.com/FairwindsOps/pluto", relation: "equivalent" },
|
|
56
|
+
{ tool: "helm-lint", rule: "validateNoDeprecations", url: "https://github.com/helm/helm/blob/main/pkg/chart/v2/lint/rules/deprecations.go", relation: "equivalent" },
|
|
57
|
+
{ tool: "kube-score", rule: "stable-version", url: "https://github.com/zegl/kube-score/blob/master/README_CHECKS.md", relation: "equivalent" },
|
|
58
|
+
],
|
|
59
|
+
WHM503: [
|
|
60
|
+
{ tool: "kics", rule: "Using Kubernetes Native Secret Management", url: "https://docs.kics.io/latest/queries/kubernetes-queries/b9c83569-459b-4110-8f79-6305aa33cb37/", relation: "overlaps" },
|
|
61
|
+
],
|
|
62
|
+
};
|
|
@@ -46,7 +46,11 @@ const ledger = vi.hoisted(() => ({
|
|
|
46
46
|
outcome: undefined as unknown,
|
|
47
47
|
}));
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
// Partial, via `importOriginal`: `@intentius/chant/op` reaches the base
|
|
50
|
+
// activities now (chant #2114), and modules on that path promisify
|
|
51
|
+
// `execFile` at load. A wholesale replacement of node:child_process would
|
|
52
|
+
// make them fail to import rather than fail an assertion.
|
|
53
|
+
vi.mock("node:child_process", async (importOriginal) => {
|
|
50
54
|
const { readFileSync, readdirSync, statSync } = await import("node:fs");
|
|
51
55
|
const { join } = await import("node:path");
|
|
52
56
|
const snapshotDir = (dir: string, rel = ""): Record<string, string> => {
|
|
@@ -99,7 +103,7 @@ vi.mock("node:child_process", async () => {
|
|
|
99
103
|
if (helm.fail) throw new Error("Error: UPGRADE FAILED: context deadline exceeded");
|
|
100
104
|
return { stdout: "Release deployed\n", stderr: "" };
|
|
101
105
|
};
|
|
102
|
-
return { exec };
|
|
106
|
+
return { ...(await importOriginal<typeof import("node:child_process")>()), exec };
|
|
103
107
|
});
|
|
104
108
|
|
|
105
109
|
vi.mock("@intentius/chant/components/auto-release", () => ({
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
compareCapabilityProfile,
|
|
15
15
|
probeClusterCapabilities,
|
|
16
16
|
} from "./cluster-probe";
|
|
17
|
-
import { safeHeartbeat } from "@intentius/chant/op";
|
|
18
17
|
import {
|
|
19
18
|
maybeRecordAutoRelease,
|
|
20
19
|
type AutoReleaseResult,
|
|
@@ -394,7 +393,7 @@ async function recordHelmRelease(
|
|
|
394
393
|
* finished deploy into a failed activity — the record is observability, not
|
|
395
394
|
* part of the deploy itself.
|
|
396
395
|
*
|
|
397
|
-
* Uses longInfra profile
|
|
396
|
+
* Uses the longInfra profile: 20m timeout, three attempts backing off from 30s.
|
|
398
397
|
*/
|
|
399
398
|
export async function helmInstall(
|
|
400
399
|
args: HelmInstallArgs,
|
|
@@ -431,17 +430,9 @@ export async function helmInstall(
|
|
|
431
430
|
if (args.values) parts.push("-f", args.values);
|
|
432
431
|
for (const [k, v] of Object.entries(args.set ?? {})) parts.push("--set", `${k}=${v}`);
|
|
433
432
|
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
try {
|
|
439
|
-
const { stdout, stderr } = await execAsync(parts.join(" "), { signal });
|
|
440
|
-
if (stdout) console.log(stdout);
|
|
441
|
-
if (stderr) console.error(stderr);
|
|
442
|
-
} finally {
|
|
443
|
-
clearInterval(heartbeatInterval);
|
|
444
|
-
}
|
|
433
|
+
const { stdout, stderr } = await execAsync(parts.join(" "), { signal });
|
|
434
|
+
if (stdout) console.log(stdout);
|
|
435
|
+
if (stderr) console.error(stderr);
|
|
445
436
|
|
|
446
437
|
const profileOverride =
|
|
447
438
|
profileAssertion && !profileAssertion.matched ? profileAssertion.divergences.join("; ") : undefined;
|
|
@@ -562,9 +553,6 @@ async function pinnedHelmInstall(
|
|
|
562
553
|
}
|
|
563
554
|
|
|
564
555
|
const wrapperDir = mkdtempSync(join(tmpdir(), "chant-helm-pinned-"));
|
|
565
|
-
const heartbeatInterval = setInterval(() => {
|
|
566
|
-
safeHeartbeat({ step: "helm install (pinned)", release: args.name });
|
|
567
|
-
}, 15_000);
|
|
568
556
|
try {
|
|
569
557
|
materializeWrapperChart(routed, wrapperDir);
|
|
570
558
|
const parts = ["helm", "upgrade", "--install", "--wait", args.name, wrapperDir];
|
|
@@ -573,7 +561,6 @@ async function pinnedHelmInstall(
|
|
|
573
561
|
if (stdout) console.log(stdout);
|
|
574
562
|
if (stderr) console.error(stderr);
|
|
575
563
|
} finally {
|
|
576
|
-
clearInterval(heartbeatInterval);
|
|
577
564
|
rmSync(wrapperDir, { recursive: true, force: true });
|
|
578
565
|
}
|
|
579
566
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* helm Op activities — resolved by the core activity registry when a project's
|
|
3
3
|
* `chant.config.ts` lists the `helm` lexicon. `helmInstall` shells out to the
|
|
4
|
-
* helm CLI
|
|
5
|
-
* (#809) so helm's imperative activity lives with its product
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* helm CLI, retried under the step's profile; relocated from the hosting
|
|
5
|
+
* lexicon (#809) so helm's imperative activity lives with its product. The
|
|
6
|
+
* `helmInstall` step builder stays in core and reaches authors through
|
|
7
|
+
* `@intentius/chant/op` like the other core builders.
|
|
8
8
|
*/
|
|
9
9
|
export {
|
|
10
10
|
helmInstall,
|
package/src/op/builders.ts
CHANGED
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
* Every field also accepts a {@link StepOutputRef} in its place
|
|
14
14
|
* ({@link WithStepRefs}, chant #1950).
|
|
15
15
|
*
|
|
16
|
-
* `core`'s own `helmInstall`/`helmInstallPinned` (in `@intentius/chant/op
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
16
|
+
* `core`'s own `helmInstall`/`helmInstallPinned` (in `@intentius/chant/op`)
|
|
17
|
+
* are UNCHANGED and produce byte-identical `ActivityStep` output for the same
|
|
18
|
+
* inputs — these are purely additive. Deliberately not swapped into core's
|
|
19
|
+
* barrel (see `lexicons/k8s/src/op/builders.ts`'s module doc for why: it
|
|
20
|
+
* would make core depend on this package at runtime, undoing the
|
|
21
|
+
* product-agnostic split #809 did). An author who wants the typed surface
|
|
22
|
+
* imports it from
|
|
23
23
|
* here — `@intentius/chant-lexicon-helm` — which a project using
|
|
24
24
|
* `helmInstall` already depends on.
|
|
25
25
|
*/
|