@intentius/chant-lexicon-k8s 0.57.0 → 0.59.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/api/fake-cluster.d.ts +7 -6
- package/dist/api/fake-cluster.d.ts.map +1 -1
- package/dist/api/sweep-types.d.ts +1 -2
- package/dist/api/sweep-types.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/composites/cron-schedule.d.ts +26 -0
- package/dist/composites/cron-schedule.d.ts.map +1 -0
- package/dist/composites/cron-workload.d.ts +1 -1
- package/dist/composites/cron-workload.d.ts.map +1 -1
- package/dist/composites/operator-stack.d.ts +20 -19
- package/dist/composites/operator-stack.d.ts.map +1 -1
- package/dist/config-schema.d.ts +3 -0
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config.d.ts +26 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/deep-observe-hooks.d.ts +4 -4
- package/dist/deep-observe.d.ts +23 -16
- package/dist/deep-observe.d.ts.map +1 -1
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/effect-receipt-row.d.ts +164 -0
- package/dist/effect-receipt-row.d.ts.map +1 -0
- package/dist/export-resources.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +4 -4
- 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/lint/post-synth/wk8505.d.ts +3 -1
- package/dist/lint/post-synth/wk8505.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/okf/index.md +1 -1
- package/dist/okf/rules/WK8505.md +2 -2
- package/dist/okf/types/Kustomization.md +1 -1
- package/dist/op/activities/argo.d.ts +4 -4
- package/dist/op/activities/argo.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +15 -7
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/kubectl.d.ts +7 -7
- package/dist/op/activities/kubectl.d.ts.map +1 -1
- package/dist/op/activities/wait-for-ready.d.ts +6 -5
- package/dist/op/activities/wait-for-ready.d.ts.map +1 -1
- package/dist/op/builders.d.ts +13 -13
- package/dist/plugin.d.ts.map +1 -1
- package/dist/receipt-store.d.ts +113 -0
- package/dist/receipt-store.d.ts.map +1 -0
- package/dist/rules/wk8505.ts +4 -2
- package/dist/serializer.d.ts.map +1 -1
- package/dist/skills/chant-k8s-argo.md +27 -13
- package/dist/subscribe-changes.d.ts +84 -0
- package/dist/subscribe-changes.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/api/fake-cluster.ts +17 -4
- package/src/api/sweep-types.ts +1 -2
- package/src/codegen/docs.ts +7 -0
- package/src/composites/composites.test.ts +72 -3
- package/src/composites/cron-schedule.ts +47 -0
- package/src/composites/cron-workload.ts +4 -1
- package/src/composites/operator-stack.ts +25 -24
- package/src/config-schema.ts +5 -0
- package/src/config.ts +27 -4
- package/src/crd/crd-sources.ts +4 -4
- package/src/deep-observe-hooks.ts +4 -4
- package/src/deep-observe.test.ts +219 -46
- package/src/deep-observe.ts +54 -28
- package/src/describe-resources.ts +31 -7
- package/src/effect-receipt-row.test.ts +285 -0
- package/src/effect-receipt-row.ts +268 -0
- package/src/export-resources.ts +1 -1
- package/src/index.ts +22 -0
- package/src/lint/audit-catalog.ts +6 -2
- package/src/lint/audit-lineage.ts +127 -0
- package/src/lint/post-synth/wk8505.ts +4 -2
- package/src/op/activities/argo.test.ts +7 -8
- package/src/op/activities/argo.ts +4 -4
- package/src/op/activities/index.ts +23 -7
- package/src/op/activities/kubectl.test.ts +43 -4
- package/src/op/activities/kubectl.ts +67 -67
- package/src/op/activities/wait-for-ready.test.ts +2 -2
- package/src/op/activities/wait-for-ready.ts +7 -7
- package/src/op/builders.ts +13 -13
- package/src/plugin.ts +16 -1
- package/src/receipt-store.test.ts +380 -0
- package/src/receipt-store.ts +290 -0
- package/src/serializer.test.ts +26 -0
- package/src/serializer.ts +92 -1
- package/src/skills/chant-k8s-argo.md +27 -13
- package/src/subscribe-changes.test.ts +368 -0
- package/src/subscribe-changes.ts +210 -0
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* all need the same thing.
|
|
14
14
|
*/
|
|
15
15
|
import type { K8sObject } from "@intentius/chant-k8s-client";
|
|
16
|
-
import type { FakeRequestLayer, RecordedRequest } from "@intentius/chant-k8s-client/testing";
|
|
16
|
+
import type { FakeRequestLayer, FakeResponse, RecordedRequest } from "@intentius/chant-k8s-client/testing";
|
|
17
17
|
import type { ConnectOptions, K8sConnector } from "./connect.js";
|
|
18
18
|
export interface FakeClusterOptions {
|
|
19
19
|
/**
|
|
@@ -28,11 +28,12 @@ export interface FakeClusterOptions {
|
|
|
28
28
|
* CRD resolvable in a test without registering anything.
|
|
29
29
|
*/
|
|
30
30
|
serves?: readonly string[];
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Full control: return a response for a request, or undefined to fall
|
|
33
|
+
* through. A `stream` on the response is what a watch reads (chant #1981);
|
|
34
|
+
* see `fakeWatchStream` in the client's testing harness.
|
|
35
|
+
*/
|
|
36
|
+
respond?: (request: RecordedRequest) => FakeResponse | undefined;
|
|
36
37
|
/** Kubeconfig to hand the client. Defaults to a single-context one. */
|
|
37
38
|
kubeconfig?: string;
|
|
38
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-cluster.d.ts","sourceRoot":"","sources":["../../src/api/fake-cluster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"fake-cluster.d.ts","sourceRoot":"","sources":["../../src/api/fake-cluster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAE3G,OAAO,KAAK,EAAmB,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG/E,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,YAAY,GAAG,SAAS,CAAC;IACjE,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,2EAA2E;IAC3E,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpG;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,GAAE,OAAO,CAAC,SAAS,CAAM,GAC7B,SAAS,CAcX;AAwBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAwGzE"}
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* It lives in its own module, with no imports of its own, because both
|
|
12
12
|
* consumers reach it from different directions — `../export-resources.ts`
|
|
13
|
-
* pulls in the whole import parser, and
|
|
14
|
-
* activity should not.
|
|
13
|
+
* pulls in the whole import parser, and the apply activity should not.
|
|
15
14
|
*/
|
|
16
15
|
export declare const DEFAULT_IMPORT_TYPES: readonly string[];
|
|
17
16
|
//# sourceMappingURL=sweep-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sweep-types.d.ts","sourceRoot":"","sources":["../../src/api/sweep-types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sweep-types.d.ts","sourceRoot":"","sources":["../../src/api/sweep-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAoBjD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4HH;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB9E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CronJob schedule validation (issue #2071 item 4).
|
|
3
|
+
*
|
|
4
|
+
* `OperatorStack` and `CronWorkload` both hand their `schedule` field
|
|
5
|
+
* straight to a k8s `CronJob`, which parses only five fields (minute hour
|
|
6
|
+
* day-of-month month day-of-week). Core's own cron parser
|
|
7
|
+
* (`isValidCronExpression`, `packages/core/src/op/cron.ts`, #2120) is
|
|
8
|
+
* deliberately more permissive: it also accepts the 6-field Quartz form
|
|
9
|
+
* (`second minute hour dom month dow`) that a `ConvergeOp`'s own `schedule`
|
|
10
|
+
* may legitimately carry, since the final word on cron syntax belongs to
|
|
11
|
+
* whichever scheduler runs the string. A k8s CronJob is that scheduler here,
|
|
12
|
+
* and it is stricter than core's parser, so a 6-field `ConvergeOp` schedule
|
|
13
|
+
* reused as-is on a CronJob fails at `kubectl apply`, not at build time.
|
|
14
|
+
*
|
|
15
|
+
* This module gives both composites one place to catch that at construction,
|
|
16
|
+
* reusing core's parser rather than a second copy of it.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Validate `schedule` for a k8s CronJob, throwing before a bad value ever
|
|
20
|
+
* reaches `kubectl apply`. `context` names the composite (and host, for
|
|
21
|
+
* `OperatorStack`) so the thrown message reads like the rest of that
|
|
22
|
+
* composite's build-time refusals, e.g. `OperatorStack "chant-operator",
|
|
23
|
+
* host "fountain-observe"` or `CronWorkload "backup"`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateCronJobSchedule(context: string, schedule: string): void;
|
|
26
|
+
//# sourceMappingURL=cron-schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-schedule.d.ts","sourceRoot":"","sources":["../../src/composites/cron-schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAmB/E"}
|
|
@@ -11,7 +11,7 @@ export interface CronWorkloadProps {
|
|
|
11
11
|
name: string;
|
|
12
12
|
/** Container image. */
|
|
13
13
|
image: string;
|
|
14
|
-
/** Cron schedule expression (e.g., "0 * * * *"). */
|
|
14
|
+
/** Cron schedule expression (e.g., "0 * * * *"). Validated at construction: a k8s CronJob takes five fields only, so a 6-field (seconds) form is refused (`./cron-schedule.ts`, #2071). */
|
|
15
15
|
schedule: string;
|
|
16
16
|
/** Command to run in the container. */
|
|
17
17
|
command?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cron-workload.d.ts","sourceRoot":"","sources":["../../src/composites/cron-workload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"cron-workload.d.ts","sourceRoot":"","sources":["../../src/composites/cron-workload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAGnE,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,2LAA2L;IAC3L,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC,CAAC;IACH,0BAA0B;IAC1B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,GAAG,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,mEAAmE;IACnE,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,sDAAsD;IACtD,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3C,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACxC,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KAChD,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,YAAY,CAAC,OAAO,OAAO,CAAC,CAAC;IACtC,cAAc,EAAE,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;IACpD,IAAI,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC;IAChC,WAAW,EAAE,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY;;;;;EAuGP,CAAC"}
|
|
@@ -16,39 +16,40 @@
|
|
|
16
16
|
* (lease fencing, `chant operator status`, durable gate-as-fact semantics).
|
|
17
17
|
* `OperatorStack`'s container command is deliberately `chant run <name>`,
|
|
18
18
|
* the one-shot local tick `ConvergeOp` (#1484) already ships and tests
|
|
19
|
-
* against (`
|
|
19
|
+
* against (`packages/core/src/op/composites/converge-op.ts`'s own doc:
|
|
20
20
|
* "one-shot runnable locally for a single tick"). When #1485 lands, a
|
|
21
21
|
* caller can override `command` to shell out to `chant operator tick`
|
|
22
22
|
* instead — this composite doesn't need to change for that; only the
|
|
23
23
|
* command a caller passes does.
|
|
24
24
|
*
|
|
25
25
|
* `concurrencyPolicy: "Forbid"` is the k8s-native analogue of
|
|
26
|
-
* `ConvergeOp`'s own
|
|
27
|
-
*
|
|
26
|
+
* `ConvergeOp`'s own `schedule.overlap: "skip"` policy — never queue a
|
|
27
|
+
* second tick behind one still running.
|
|
28
28
|
*
|
|
29
29
|
* ## RBAC derivation
|
|
30
30
|
*
|
|
31
31
|
* `ConvergeOp` adds no authority an environment did not already grant
|
|
32
32
|
* (#1484's Autonomy table). `OperatorStack` re-derives the same bound at the
|
|
33
|
-
* k8s RBAC layer,
|
|
34
|
-
*
|
|
33
|
+
* k8s RBAC layer, from the Op configs alone (see the Layering note below for
|
|
34
|
+
* what this module imports and what it restates): for each hosted
|
|
35
35
|
* ConvergeOp, walk its `dispatchTargets` (the OpConfigs its rule table's
|
|
36
36
|
* `run()` actions may name) through `classifyOpVerbClass`
|
|
37
37
|
* (`packages/core/src/op/op-verb-class.ts`, #1954), then keep only the
|
|
38
38
|
* highest verb class this host's `dial` could ever actually free-run —
|
|
39
39
|
* exactly `convergeTick`'s own `verbClassAllowedToDispatch` gate and
|
|
40
|
-
* `
|
|
40
|
+
* `OPS014`'s build-time refusal, restated as an RBAC ceiling:
|
|
41
41
|
*
|
|
42
42
|
* - `dial: "observe"` never dispatches (report-only) → read-only RBAC,
|
|
43
43
|
* regardless of what the rule table's targets could otherwise do.
|
|
44
|
-
* - `dial: "reconcile"` only free-runs a read-only target (
|
|
44
|
+
* - `dial: "reconcile"` only free-runs a read-only target (OPS014 refuses a
|
|
45
45
|
* mutating dispatch under reconcile in v1) → read-only RBAC.
|
|
46
46
|
* - `dial: "apply"` free-runs read-only and mutating targets → RBAC gains
|
|
47
47
|
* create/update/patch, never delete.
|
|
48
48
|
* - A `dispatchTargets` entry that itself classifies `destructive` is
|
|
49
|
-
* refused outright, at construction —
|
|
50
|
-
* destructive `run()` target under any dial in v1 (
|
|
51
|
-
*
|
|
49
|
+
* refused outright, at construction — OPS014 already refuses a
|
|
50
|
+
* destructive `run()` target under any dial in v1 (a converge tick runs
|
|
51
|
+
* unattended, and a destructive dispatch needs a person's approval before
|
|
52
|
+
* it is attempted, not a gate read after the fact), so a `destructive` target
|
|
52
53
|
* reaching this composite is either a config bypassing that build check
|
|
53
54
|
* or a target `OperatorStack` should never grant permission toward.
|
|
54
55
|
* `never delete`, unconditionally, in v1 — no verb class here ever grants
|
|
@@ -61,11 +62,11 @@
|
|
|
61
62
|
*
|
|
62
63
|
* ## Layering
|
|
63
64
|
*
|
|
64
|
-
* `
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
65
|
+
* `OperatorStackConvergeHost` restates the handful of `ConvergeOp` fields
|
|
66
|
+
* this composite actually needs (`name`, `schedule`, `env`, `dial`)
|
|
67
|
+
* structurally rather than importing `ConvergeOpConfig`: the CronJob is
|
|
68
|
+
* built from a host description, not from an Op config, and a caller that
|
|
69
|
+
* has neither should still be able to describe one. `dispatchTargets` takes
|
|
69
70
|
* plain `OpConfig`-shaped values from `@intentius/chant/op` (a dependency
|
|
70
71
|
* this lexicon already has via the `@intentius/chant` peer dependency),
|
|
71
72
|
* the same type `classifyOpVerbClass` itself takes.
|
|
@@ -74,7 +75,7 @@ import type { OpConfig, OpVerbClass } from "@intentius/chant/op";
|
|
|
74
75
|
import { Namespace, CronJob, ServiceAccount, Role, RoleBinding } from "../generated/index.js";
|
|
75
76
|
/**
|
|
76
77
|
* Mirrors `ConvergeOp`'s own `ConvergeDial`
|
|
77
|
-
* (`
|
|
78
|
+
* (`packages/core/src/op/composites/converge-op.ts`) structurally — see
|
|
78
79
|
* this module's Layering doc for why it's restated rather than imported.
|
|
79
80
|
*/
|
|
80
81
|
export type OperatorDial = "observe" | "reconcile" | "apply";
|
|
@@ -87,7 +88,7 @@ export interface OperatorRbacResourceRule {
|
|
|
87
88
|
export interface OperatorStackConvergeHost {
|
|
88
89
|
/** ConvergeOp's own name (`ConvergeOpConfig.name`) — the CronJob, ServiceAccount, Role, and RoleBinding name stem for this host. */
|
|
89
90
|
name: string;
|
|
90
|
-
/** Cron expression driving the tick — the same string passed to `ConvergeOp`'s own `schedule`. */
|
|
91
|
+
/** Cron expression driving the tick — the same string passed to `ConvergeOp`'s own `schedule`. Validated at construction: a 6-field (seconds) form, which `ConvergeOp` accepts, is refused here since a k8s CronJob takes five fields only (`./cron-schedule.ts`, #2071). */
|
|
91
92
|
schedule: string;
|
|
92
93
|
/** Environment this ConvergeOp converges (`ConvergeOpConfig.env`) — carried onto the container as `CHANT_CONVERGE_ENV`, for log/estate readability only (`chant run <name>` needs no `--env`: the target op already carries it). */
|
|
93
94
|
env: string;
|
|
@@ -96,7 +97,7 @@ export interface OperatorStackConvergeHost {
|
|
|
96
97
|
/**
|
|
97
98
|
* OpConfigs for every op this ConvergeOp's rule table may `run()` — the
|
|
98
99
|
* sibling `*.op.ts` declarations its `run()` actions name. Used to derive
|
|
99
|
-
* least-privilege RBAC the same way `
|
|
100
|
+
* least-privilege RBAC the same way `OPS014` derives its build-time
|
|
100
101
|
* refusals. Omit or leave empty when every rule only `report()`s; the
|
|
101
102
|
* host still gets read-only RBAC for its own observation.
|
|
102
103
|
*/
|
|
@@ -153,7 +154,7 @@ export declare const DEFAULT_RESOURCE_RULES: OperatorRbacResourceRule[];
|
|
|
153
154
|
* Derive the highest verb class a host's ServiceAccount actually needs:
|
|
154
155
|
* the max, across `dispatchTargets`, of each target's own class — but only
|
|
155
156
|
* counting a target `dial` could ever actually dispatch (one it can't just
|
|
156
|
-
* gets reported, per `
|
|
157
|
+
* gets reported, per `OPS014`/`convergeTick`, and needs no elevated grant).
|
|
157
158
|
* A `dispatchTargets` entry that classifies `destructive` is refused
|
|
158
159
|
* outright rather than silently ignored — see this module's RBAC
|
|
159
160
|
* derivation doc on why a destructive target reaching this composite is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator-stack.d.ts","sourceRoot":"","sources":["../../src/composites/operator-stack.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"operator-stack.d.ts","sourceRoot":"","sources":["../../src/composites/operator-stack.ts"],"names":[],"mappings":"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"}
|
package/dist/config-schema.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ export declare const k8sConfigSchema: z.ZodObject<{
|
|
|
25
25
|
kustomize: z.ZodOptional<z.ZodObject<{
|
|
26
26
|
roots: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
27
27
|
}, z.core.$strict>>;
|
|
28
|
+
receipts: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
namespace: z.ZodOptional<z.ZodString>;
|
|
30
|
+
}, z.core.$strict>>;
|
|
28
31
|
}, z.core.$strict>;
|
|
29
32
|
declare module "@intentius/chant/config" {
|
|
30
33
|
interface ChantConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,eAAO,MAAM,uBAAuB;;kBAElC,CAAC;AAEH,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,eAAO,MAAM,uBAAuB;;kBAElC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;kBAa1B,CAAC;AAEH,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,WAAW;QACnB,GAAG,CAAC,EAAE,cAAc,CAAC;KACtB;CACF;AAED,iEAAiE;AACjE,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AAEjE;;;GAGG;AACH,KAAK,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,SAAS,cAAc,GAChF,cAAc,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,GACpD,IAAI,GACJ,KAAK,GACP,KAAK,CAAC;AACV,MAAM,MAAM,0BAA0B,GAAG,sBAAsB,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* K8s environment → cluster binding — chant #1100.
|
|
3
3
|
*
|
|
4
4
|
* Every cloud lexicon binds an environment to a scope: AWS resolves `<env>`
|
|
5
|
-
* to a CloudFormation stack, Azure treats `<env>` as the resource group
|
|
6
|
-
*
|
|
5
|
+
* to a CloudFormation stack, Azure treats `<env>` as the resource group.
|
|
6
|
+
* Before this, k8s bound
|
|
7
7
|
* nothing — `describeResources` shelled out to `kubectl get` with no
|
|
8
8
|
* `--context`, so `chant lifecycle diff prod --live` read whichever cluster
|
|
9
9
|
* `kubectl config current-context` happened to point at.
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
* and the missing binding.
|
|
41
41
|
*
|
|
42
42
|
* `ChantConfig` uses `.passthrough()` in its Zod schema so the `k8s` key is
|
|
43
|
-
* accepted at runtime without core changes, exactly like `
|
|
44
|
-
* (see `lexicons/
|
|
43
|
+
* accepted at runtime without core changes, exactly like the `terraform` key
|
|
44
|
+
* (see `lexicons/terraform/src/config.ts`). The type side is the declaration
|
|
45
45
|
* merge at the bottom of this file — without it the snippet above compiles
|
|
46
46
|
* only until someone adds `satisfies ChantConfig`, which every example
|
|
47
47
|
* project does and which is the only thing type-checking the rest of the
|
|
@@ -107,6 +107,28 @@ export interface K8sChantConfig {
|
|
|
107
107
|
/** Kustomization directories to render into the build. */
|
|
108
108
|
roots?: string[];
|
|
109
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* Effect receipt settings (#2074, epic #1703).
|
|
112
|
+
*
|
|
113
|
+
* `namespace` is where this project's receipt ConfigMaps live. The name is
|
|
114
|
+
* derived from the ownership fields (`chant-receipt.<stack>.<env>.<effect>`,
|
|
115
|
+
* see `./effect-receipt-row.ts`); the namespace is the one part of the
|
|
116
|
+
* address the ownership block cannot answer, so it is declared here. Unset,
|
|
117
|
+
* receipts land in `default`, the same namespace every other namespace-less
|
|
118
|
+
* k8s read and write in this lexicon falls through to. It is never derived
|
|
119
|
+
* from the stack or the environment: a guessed namespace is one chant would
|
|
120
|
+
* have to create, and the receipt row creates nothing but the receipt.
|
|
121
|
+
*
|
|
122
|
+
* ```ts
|
|
123
|
+
* k8s: {
|
|
124
|
+
* receipts: { namespace: "chant-system" },
|
|
125
|
+
* } satisfies K8sChantConfig
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
receipts?: {
|
|
129
|
+
/** Namespace the receipt ConfigMaps live in. Defaults to `default`. */
|
|
130
|
+
namespace?: string;
|
|
131
|
+
};
|
|
110
132
|
}
|
|
111
133
|
declare module "@intentius/chant/config" {
|
|
112
134
|
interface ChantConfig {
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,EAAE;QACV,0DAA0D;QAC1D,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;CACH;AAED,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,WAAW;QACnB,GAAG,CAAC,EAAE,cAAc,CAAC;KACtB;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,EAAE;QACV,0DAA0D;QAC1D,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IAEF;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,EAAE;QACT,uEAAuE;QACvE,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,WAAW;QACnB,GAAG,CAAC,EAAE,cAAc,CAAC;KACtB;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC"}
|
|
@@ -49,7 +49,8 @@ import type { DeepArrayElement, DeepNormalizationHooks } from "@intentius/chant/
|
|
|
49
49
|
* Kubernetes-defaulted fields, per entity type, as index-erased property
|
|
50
50
|
* paths. Subtracted only where source never declared the property
|
|
51
51
|
* (`side === "live" && counterpart === "absent"`) — cdk-real-drift's default
|
|
52
|
-
* subtraction, same convention as AWS
|
|
52
|
+
* subtraction, same convention as the AWS and Azure tables
|
|
53
|
+
* (`AWS_SERVICE_DEFAULTS`, `AZURE_SERVICE_DEFAULTS`).
|
|
53
54
|
*
|
|
54
55
|
* Sparse and evidence-based rather than derived from the generated schema:
|
|
55
56
|
* the k8s OpenAPI spec this lexicon's codegen consumes
|
|
@@ -58,9 +59,8 @@ import type { DeepArrayElement, DeepNormalizationHooks } from "@intentius/chant/
|
|
|
58
59
|
* actually expressible today. Widening this table is additive and needs no
|
|
59
60
|
* contract change.
|
|
60
61
|
*
|
|
61
|
-
* `spec.strategy` is listed whole
|
|
62
|
-
*
|
|
63
|
-
* only the leaf would still recurse into the object, and a nested default the
|
|
62
|
+
* `spec.strategy` is listed whole rather than as `spec.strategy.type`, because
|
|
63
|
+
* pruning only the leaf would still recurse into the object, and a nested default the
|
|
64
64
|
* table does not separately name (`rollingUpdate.maxSurge`/`maxUnavailable`,
|
|
65
65
|
* both `"25%"` when `spec.strategy` is omitted entirely) would leave behind an
|
|
66
66
|
* empty `strategy: {}` — a value distinct from no `strategy` key at all, and
|
package/dist/deep-observe.d.ts
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
*
|
|
10
10
|
* ## What managedFields decides, and what it does not
|
|
11
11
|
*
|
|
12
|
-
* AWS
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* The AWS and Azure rows both prune by a **static, entityType-keyed** table
|
|
13
|
+
* (`AWS_SERVICE_DEFAULTS`, `AZURE_SERVICE_DEFAULTS`): an ARN always looks like
|
|
14
|
+
* an ARN, `provisioningState` is always server-populated. Neither needs the
|
|
15
|
+
* specific live object in hand — it is exactly
|
|
16
16
|
* what `./deep-observe-hooks.ts`'s `k8sDeepNormalizationHooks` is, and it
|
|
17
17
|
* covers Kubernetes' *equivalent* static noise (`status`,
|
|
18
18
|
* `metadata.{uid,resourceVersion,generation,creationTimestamp}`, a handful of
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* was controller noise. It silenced exactly the case the deep read exists
|
|
32
32
|
* for — `kubectl label deploy web team=platform` is foreign-owned
|
|
33
33
|
* (`kubectl-edit`) and undeclared, and never appeared in fieldDrift. The
|
|
34
|
-
* policy now (recorded on #1202) is:
|
|
34
|
+
* policy now (recorded on #1202, refined by #2160) is:
|
|
35
35
|
*
|
|
36
36
|
* 1. **Chant-owned** (`chant`, `chant:<stack>` — chant #1075, matched on the
|
|
37
37
|
* family so a stack rename does not stop recognizing its own history) is
|
|
@@ -41,18 +41,25 @@
|
|
|
41
41
|
* write currently holds the field, and a foreign write that overrides a
|
|
42
42
|
* value chant's manifest asks for is the thing `lifecycle diff --live`
|
|
43
43
|
* exists to surface. It reports as `changed`.
|
|
44
|
-
* 3. **
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* 3. **Undeclared** — a path outside the declaration's claimed-field set
|
|
45
|
+
* (`@intentius/chant/claimed-fields`) — is reported as unclaimed and
|
|
46
|
+
* is not drift at all. Before #2160 it was `undeclared` drift that the
|
|
47
|
+
* accepted baseline had to absorb one path at a time; the declaration
|
|
48
|
+
* answers on the first read instead, so an HPA that owns `spec.replicas`
|
|
49
|
+
* on a Deployment whose source is silent about replicas is quiet with
|
|
50
|
+
* nothing recorded anywhere.
|
|
49
51
|
*
|
|
50
|
-
* So ownership decides nothing about *whether* a path is compared
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
52
|
+
* So ownership decides nothing about *whether* a path is compared, and since
|
|
53
|
+
* #2160 it no longer decides the verdict either — the declaration does. What
|
|
54
|
+
* it contributes is `fieldOwners` (#1189), and that is worth more here than
|
|
55
|
+
* anywhere else: on every other substrate a held field can only be reported
|
|
56
|
+
* as "not chant's", while here it is reported as `hpa-controller`'s or
|
|
57
|
+
* `kubectl-edit`'s by name, which is the difference between a controller
|
|
58
|
+
* doing its job and somebody bypassing the pipeline. Core takes the manager
|
|
59
|
+
* where this reader supplies one and falls back to the claim where it does
|
|
60
|
+
* not (a path inside a key-addressed list, which no `fieldsV1` entry names in
|
|
61
|
+
* that form). The only fields subtracted because a foreign manager wrote them
|
|
62
|
+
* are the well-known system ones on the static allowlist.
|
|
56
63
|
*
|
|
57
64
|
* ## Resolving a managedFields entry against a live array
|
|
58
65
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-observe.d.ts","sourceRoot":"","sources":["../src/deep-observe.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"deep-observe.d.ts","sourceRoot":"","sources":["../src/deep-observe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGG;AAGH,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACzF,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAQvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAUjE,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAQD;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,qBAAqB,EAC9B,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,qBAAqB,CAAC,CAkIhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAwD,MAAM,0BAA0B,CAAC;AAGxH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAwD,MAAM,0BAA0B,CAAC;AAGxH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAoBvE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CA2CvD;AA4FD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAuBtE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG;IAClD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAUA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACzC,GAAG,EAAE,SAAS,GACb,MAAM,GAAG,SAAS,CAIpB;AAQD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CA0L5B"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The k8s effect-receipt materialization row (#2074, epic #1703): an effect
|
|
3
|
+
* receipt stored as a core `ConfigMap`, named
|
|
4
|
+
* `chant-receipt.<stack>.<env>.<effect>`, holding the expectation under
|
|
5
|
+
* `data.expectation`.
|
|
6
|
+
*
|
|
7
|
+
* Core's `EffectReceipt` factory (#1831) declares a receipt under the `chant`
|
|
8
|
+
* pseudo-lexicon, which no serializer claims. This module is the k8s
|
|
9
|
+
* materialization, built to the same shape as the aws SSM row (#1835,
|
|
10
|
+
* `lexicons/aws/src/effect-receipt-row.ts`): the {@link EffectReceipt} factory
|
|
11
|
+
* here produces core's declaration under `lexicon: "k8s"`, so the build
|
|
12
|
+
* partitions it to the k8s serializer, #1832's write-exclusion seam withholds
|
|
13
|
+
* it from the apply-bound entity set, and the serializer renders it for
|
|
14
|
+
* visibility through `SerializeContext.receipts` (see ./serializer.ts).
|
|
15
|
+
*
|
|
16
|
+
* Where the aws row parks its rendered rows in the CloudFormation template's
|
|
17
|
+
* `Metadata` (deliberately outside `Resources`, the section an applier writes
|
|
18
|
+
* from), this row parks them in a YAML COMMENT at the end of the manifest
|
|
19
|
+
* stream. Kubernetes YAML has no metadata channel outside the documents
|
|
20
|
+
* themselves, and a document is exactly what an applier applies: `loadAll`
|
|
21
|
+
* yields no object for a comment, so the receipt block is structurally
|
|
22
|
+
* unreachable from `applyManifest` while still riding the one build output the
|
|
23
|
+
* observation leg is handed. See {@link EFFECT_RECEIPTS_COMMENT_MARKER}.
|
|
24
|
+
*
|
|
25
|
+
* ## Name and namespace
|
|
26
|
+
*
|
|
27
|
+
* Path identity (epic decision 4): the ConfigMap name derives from the SAME
|
|
28
|
+
* ownership-block fields that stamp markers, `ownership.stack` and an explicit
|
|
29
|
+
* `ownership.env`, plus the receipt's `effect`. The separator is `.`, which no
|
|
30
|
+
* segment may contain, so `stack=a-b env=c` and `stack=a env=b-c` cannot
|
|
31
|
+
* produce the same name. The result is a valid RFC 1123 DNS subdomain, which
|
|
32
|
+
* is what a ConfigMap name has to be.
|
|
33
|
+
*
|
|
34
|
+
* The namespace is the project's `k8s.receipts.namespace`, and `default` when
|
|
35
|
+
* the project sets none, which is where every other namespace-less k8s read
|
|
36
|
+
* and write in this lexicon already lands. It is never invented from the stack
|
|
37
|
+
* or the environment: a namespace chant guessed would be a namespace chant has
|
|
38
|
+
* to create, and the receipt row creates nothing but the receipt.
|
|
39
|
+
*
|
|
40
|
+
* ## Ownership, and why the prune leaves it alone
|
|
41
|
+
*
|
|
42
|
+
* Every receipt ConfigMap carries chant's ownership marker labels plus
|
|
43
|
+
* {@link RECEIPT_LABEL_KEY}. The marker is what makes `chant kube get` and the
|
|
44
|
+
* observation classify it as chant's rather than foreign. The receipt label is
|
|
45
|
+
* what keeps `delete: "owned-only"` from pruning it: the receipt is owned and
|
|
46
|
+
* is never in any apply set (the effect step is its sole writer), which is the
|
|
47
|
+
* exact shape the owned-only sweep deletes. `pruneOrphans`
|
|
48
|
+
* (./op/activities/kubectl.ts) reports it `retained` instead, the same
|
|
49
|
+
* treatment a generated-once Secret gets (./secret-labels.ts) and for the same
|
|
50
|
+
* reason: destroying it silently converts at-least-once into a re-run nobody
|
|
51
|
+
* asked for, or worse, into never.
|
|
52
|
+
*
|
|
53
|
+
* Plain store (#1833's COR023): a ConfigMap is the plain half of the
|
|
54
|
+
* ConfigMap/Secret pair, and the entityType alone is what the guard reads. A
|
|
55
|
+
* receipt value is a witness (an existence marker or a `sha256:` digest),
|
|
56
|
+
* never a secret; materializing one into a `K8s::Core::Secret` fails COR023.
|
|
57
|
+
*/
|
|
58
|
+
import { type Declarable } from "@intentius/chant/declarable";
|
|
59
|
+
import { EFFECT_RECEIPT_MARKER, type EffectReceiptFlavor, type EffectReceiptOptions } from "@intentius/chant/effect-receipt";
|
|
60
|
+
/** The entityType of the k8s materialization row, the real resource kind the
|
|
61
|
+
* receipt is stored as, which is what lint's plain-store guard checks. */
|
|
62
|
+
export declare const K8S_EFFECT_RECEIPT_ENTITY_TYPE = "K8s::Core::ConfigMap";
|
|
63
|
+
/** apiVersion/kind of the materialized row, for the client reads and writes. */
|
|
64
|
+
export declare const RECEIPT_CONFIGMAP_REF: {
|
|
65
|
+
readonly apiVersion: "v1";
|
|
66
|
+
readonly kind: "ConfigMap";
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* The line prefix the serializer renders receipt rows behind, and the
|
|
70
|
+
* observation leg reads them back from. A YAML comment: an applier's `loadAll`
|
|
71
|
+
* produces no document for it, so a receipt can never enter an apply set, and
|
|
72
|
+
* `kubectl apply -f` ignores it exactly as it ignores every other comment.
|
|
73
|
+
* The remainder of the line is one JSON object keyed by entity name.
|
|
74
|
+
*/
|
|
75
|
+
export declare const EFFECT_RECEIPTS_COMMENT_MARKER = "# chant:effect-receipts ";
|
|
76
|
+
/** First segment of every receipt ConfigMap name. */
|
|
77
|
+
export declare const RECEIPT_NAME_PREFIX = "chant-receipt";
|
|
78
|
+
/** The `data` key the expectation is stored under. One key, the same single
|
|
79
|
+
* value the aws row puts in the SSM parameter's `Value`. */
|
|
80
|
+
export declare const RECEIPT_DATA_KEY = "expectation";
|
|
81
|
+
/** The label a live receipt ConfigMap carries, valued with the effect it
|
|
82
|
+
* witnesses. Recognition for the observation leg and, more importantly, the
|
|
83
|
+
* exclusion the owned-only prune keys on. */
|
|
84
|
+
export declare const RECEIPT_LABEL_KEY = "chant.intentius.io/effect-receipt";
|
|
85
|
+
/** Where receipts live when the project names no namespace. */
|
|
86
|
+
export declare const RECEIPT_DEFAULT_NAMESPACE = "default";
|
|
87
|
+
/**
|
|
88
|
+
* The rendered value of a hash-flavor receipt that still carries reference
|
|
89
|
+
* inputs at synthesis. References resolve at plan and at run, never at
|
|
90
|
+
* synthesis (epic decision 5), so the row carries this note instead of a
|
|
91
|
+
* digest hashed over placeholders.
|
|
92
|
+
*/
|
|
93
|
+
export declare const RECEIPT_UNRESOLVED_VALUE_NOTE = "unresolved at synthesis, reference inputs; the expectation resolves at plan and at run (chant #1703, decision 5)";
|
|
94
|
+
/**
|
|
95
|
+
* The ConfigMap name of one effect's receipt:
|
|
96
|
+
* `chant-receipt.<stack>.<env>.<effect>`, from the resolved ownership marker
|
|
97
|
+
* fields (epic decision 4). The single source of the name identity: the
|
|
98
|
+
* serializer's rendered row, the receipt store's reads and writes, and the
|
|
99
|
+
* observation leg all call this.
|
|
100
|
+
*/
|
|
101
|
+
export declare function receiptConfigMapName(stack: string, env: string, effect: string): string;
|
|
102
|
+
/** The project's receipt namespace: `k8s.receipts.namespace`, else `default`.
|
|
103
|
+
* The serializer reads it off `SerializeContext.config` and the store reads it
|
|
104
|
+
* off the project config, so both derive one namespace from one setting. */
|
|
105
|
+
export declare function receiptNamespaceFrom(config: Record<string, unknown> | undefined): string;
|
|
106
|
+
/** Name and namespace of one effect's receipt ConfigMap. */
|
|
107
|
+
export interface ReceiptConfigMapRef {
|
|
108
|
+
name: string;
|
|
109
|
+
namespace: string;
|
|
110
|
+
}
|
|
111
|
+
/** The full address of one effect's receipt ConfigMap. */
|
|
112
|
+
export declare function receiptConfigMapRef(stack: string, env: string, effect: string, namespace?: string): ReceiptConfigMapRef;
|
|
113
|
+
/** True when a live object's labels mark it a chant effect receipt. Any
|
|
114
|
+
* non-empty value counts: the label's presence is the claim, and a sweep must
|
|
115
|
+
* err on the side of keeping. */
|
|
116
|
+
export declare function isEffectReceiptObject(labels: Record<string, unknown> | undefined): boolean;
|
|
117
|
+
/** One rendered receipt row, as the comment block carries it. */
|
|
118
|
+
export interface RenderedReceiptRow {
|
|
119
|
+
kind: typeof RECEIPT_CONFIGMAP_REF.kind;
|
|
120
|
+
namespace: string;
|
|
121
|
+
name: string;
|
|
122
|
+
data: Record<string, string>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Render the receipt block the serializer appends to the manifest stream.
|
|
126
|
+
* Deterministic: one line, entity names sorted.
|
|
127
|
+
*/
|
|
128
|
+
export declare function renderReceiptComment(rows: Record<string, RenderedReceiptRow>): string;
|
|
129
|
+
/**
|
|
130
|
+
* Read the receipt rows back out of a build output. Returns an empty record
|
|
131
|
+
* for an output that carries no block, which is every project that declares no
|
|
132
|
+
* receipt. Never throws: an unparseable block is no block, and the observation
|
|
133
|
+
* leg reports the receipts it could not address as absent rather than
|
|
134
|
+
* inventing one.
|
|
135
|
+
*/
|
|
136
|
+
export declare function parseReceiptComment(buildOutput: string): Record<string, RenderedReceiptRow>;
|
|
137
|
+
/**
|
|
138
|
+
* A k8s-materialized effect receipt: core's declaration shape (so
|
|
139
|
+
* `isEffectReceipt`, `effect(...)`, lint, and the plan engine all recognize it
|
|
140
|
+
* through the marker), under the k8s lexicon and the real resource kind.
|
|
141
|
+
*/
|
|
142
|
+
export interface K8sEffectReceiptDeclaration extends Declarable {
|
|
143
|
+
readonly [EFFECT_RECEIPT_MARKER]: true;
|
|
144
|
+
readonly lexicon: "k8s";
|
|
145
|
+
readonly entityType: typeof K8S_EFFECT_RECEIPT_ENTITY_TYPE;
|
|
146
|
+
/** The receipt's own name (the export-level identity of the witness). */
|
|
147
|
+
readonly name: string;
|
|
148
|
+
/** The effect this receipt witnesses, the name's final segment. */
|
|
149
|
+
readonly effect: string;
|
|
150
|
+
/** How the receipt is compared: mere presence, or a digest of the inputs. */
|
|
151
|
+
readonly flavor: EffectReceiptFlavor;
|
|
152
|
+
/** The effect's inputs as recorded at synthesis (references as placeholders). */
|
|
153
|
+
readonly inputs: Readonly<Record<string, unknown>>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Declare a k8s-materialized effect receipt. Same signature and semantics as
|
|
157
|
+
* core's `EffectReceipt` (#1831), whose factory validates and freezes the
|
|
158
|
+
* options, but the declaration lands in the k8s partition, so the k8s
|
|
159
|
+
* serializer renders the ConfigMap row and the receipt store
|
|
160
|
+
* (./receipt-store.ts) is its writer. Pass the returned const straight to the
|
|
161
|
+
* `effect(...)` op step.
|
|
162
|
+
*/
|
|
163
|
+
export declare function EffectReceipt(name: string, options: EffectReceiptOptions): K8sEffectReceiptDeclaration;
|
|
164
|
+
//# sourceMappingURL=effect-receipt-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-receipt-row.d.ts","sourceRoot":"","sources":["../src/effect-receipt-row.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ import { DEFAULT_IMPORT_TYPES } from "./api/sweep-types.js";
|
|
|
25
25
|
* reachable by naming it with `--selector type=...`. Defined in
|
|
26
26
|
* `./api/sweep-types.ts` and re-exported here, its original home — chant
|
|
27
27
|
* #1075's ownership-scoped prune needs the same list without pulling the
|
|
28
|
-
* import parser
|
|
28
|
+
* import parser in behind the apply activity.
|
|
29
29
|
*/
|
|
30
30
|
export { DEFAULT_IMPORT_TYPES };
|
|
31
31
|
export declare function exportResources(options: {
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export { kustomizeApplyCapability, createKustomizeApplyCapability, type Kustomiz
|
|
|
6
6
|
export { defaultLabels, defaultAnnotations, isDefaultLabels, isDefaultAnnotations } from "./default-labels.js";
|
|
7
7
|
export { DEFAULT_LABELS_MARKER, DEFAULT_ANNOTATIONS_MARKER } from "./default-labels.js";
|
|
8
8
|
export { K8sLabels, K8sAnnotations } from "./variables.js";
|
|
9
|
+
export { EffectReceipt, receiptConfigMapName, receiptConfigMapRef, receiptNamespaceFrom, isEffectReceiptObject, K8S_EFFECT_RECEIPT_ENTITY_TYPE, EFFECT_RECEIPTS_COMMENT_MARKER, RECEIPT_NAME_PREFIX, RECEIPT_DATA_KEY, RECEIPT_LABEL_KEY, RECEIPT_DEFAULT_NAMESPACE, RECEIPT_UNRESOLVED_VALUE_NOTE, parseReceiptComment, renderReceiptComment, } from "./effect-receipt-row.js";
|
|
10
|
+
export type { K8sEffectReceiptDeclaration, ReceiptConfigMapRef, RenderedReceiptRow } from "./effect-receipt-row.js";
|
|
9
11
|
export { GENERATED_ONCE_LABEL_KEY, GENERATED_ONCE_LABEL_VALUE, isGeneratedOnce } from "./secret-labels.js";
|
|
10
12
|
export { microTime, isMicroTimeFormatted } from "./micro-time.js";
|
|
11
13
|
export { k8sManifest } from "./manifest-entity.js";
|