@intentius/chant-lexicon-k8s 0.41.14 → 0.41.16
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/deep-observe-hooks.d.ts.map +1 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/dist/op/activities/kubectl.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/deep-observe-hooks.ts +10 -0
- package/src/op/activities/kubectl.test.ts +46 -0
- package/src/op/activities/kubectl.ts +39 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-observe-hooks.d.ts","sourceRoot":"","sources":["../src/deep-observe-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;
|
|
1
|
+
{"version":3,"file":"deep-observe-hooks.d.ts","sourceRoot":"","sources":["../src/deep-observe-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAY,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAYnG;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAcxE,CAAC;AA+EF;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAYnF;AAMD,eAAO,MAAM,yBAAyB,EAAE,sBAWvC,CAAC"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "528b5cb5e20dcb4ab991f8ab6d98da91f361d833b65d8e40bdb62867498ddc0e",
|
|
5
5
|
"meta.json": "c0b141b882c51483c1d1aead748a0eb171aceca7432edd2a0404b062bf6d7831",
|
|
6
6
|
"types/index.d.ts": "3be2af7494aca94adfa16269cb9c4e7a155529872207a3d70b0c4d39914f9eec",
|
|
7
7
|
"rules/argo-appset-single-project.ts": "afa9f310753aa2d475f35012b13135b2dfaebed2a35d44edbe185ebc07673674",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"skills/chant-k8s-aks.md": "e18f0e2b055f72cd7a37deaf258d7027c2d4d3e286e8fd4975b27a1f981a3ad9",
|
|
51
51
|
"skills/chant-k8s-argo.md": "b1a0b826559d8c5033a479c5781efaf650320f0aee4419d8841170bd3393cea5"
|
|
52
52
|
},
|
|
53
|
-
"composite": "
|
|
53
|
+
"composite": "f895a3588933ce1fa536eeceb58265524ea731115d96b1ca7b3a93df9c19d1e1"
|
|
54
54
|
}
|
package/dist/manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kubectl.d.ts","sourceRoot":"","sources":["../../../src/op/activities/kubectl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAaH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI3E;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;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;CACtB;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;
|
|
1
|
+
{"version":3,"file":"kubectl.d.ts","sourceRoot":"","sources":["../../../src/op/activities/kubectl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAaH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI3E;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;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;CACtB;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;AA0ED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,gBAAgB,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,mBAAmB,CAAC,CAoD9B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,gBAAgB,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-k8s",
|
|
3
|
-
"version": "0.41.
|
|
3
|
+
"version": "0.41.16",
|
|
4
4
|
"description": "Kubernetes lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
86
|
"zod": "^4.3.6",
|
|
87
|
-
"@intentius/chant": "^0.41.
|
|
87
|
+
"@intentius/chant": "^0.41.16",
|
|
88
88
|
"typescript": "^5.9.3"
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -41,9 +41,19 @@
|
|
|
41
41
|
* keyed by chant's own k8s entityType catalog.
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
|
+
import { createRequire } from "module";
|
|
44
45
|
import type { DeepArrayElement, DeepNode, DeepNormalizationHooks } from "@intentius/chant/lexicon";
|
|
45
46
|
import { K8S_OBJECT_ENVELOPE_PRUNE_PATTERNS, k8sListMapOrderKey } from "@intentius/chant/managed-fields";
|
|
46
47
|
|
|
48
|
+
// This module ships as ESM (tsx strips types from src/ directly), where a bare
|
|
49
|
+
// `require` is not defined — the same reason serializer.ts and the LSP modules
|
|
50
|
+
// already build one. The bug only surfaced on a LIVE deep read that meets an
|
|
51
|
+
// associative list (every k8s estate does: a Deployment's containers), so
|
|
52
|
+
// `lifecycle diff --live` crashed with `require is not defined` on exactly the
|
|
53
|
+
// estates the generated table exists for (#1441 regression, found on
|
|
54
|
+
// kubemicrovm-ops).
|
|
55
|
+
const require = createRequire(import.meta.url);
|
|
56
|
+
|
|
47
57
|
/**
|
|
48
58
|
* Kubernetes-defaulted fields, per entity type, as index-erased property
|
|
49
59
|
* paths. Subtracted only where source never declared the property
|
|
@@ -132,6 +132,52 @@ describe("kubectlApply", () => {
|
|
|
132
132
|
}
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
+
test("the apply stamps its resolved stack onto every document's labels — the identity the prune and the status sweep query", async () => {
|
|
136
|
+
// The serializer bakes the PROJECT stack (`ownership.stack`) into what it
|
|
137
|
+
// emits, but a component's kubectl-apply step applies under its own unit
|
|
138
|
+
// stack — and that is what both label readers select on. A manifest with
|
|
139
|
+
// the project label (or none at all: upstream CRDs) must leave the apply
|
|
140
|
+
// carrying the unit's identity, or the unit reads absent forever.
|
|
141
|
+
const file = join(dir, "k8s.yaml");
|
|
142
|
+
const labeled = deploymentYaml.replace(
|
|
143
|
+
" name: web\n namespace: prod\n",
|
|
144
|
+
" name: web\n namespace: prod\n labels:\n app.kubernetes.io/managed-by: chant\n chant.intentius.io/stack: whole-project\n chant.intentius.io/env: dev\n",
|
|
145
|
+
);
|
|
146
|
+
writeFileSync(file, labeled);
|
|
147
|
+
const cluster = fakeCluster({ respond: echoApplies });
|
|
148
|
+
|
|
149
|
+
await applyManifest({ manifest: file, stack: "kmv-workload" }, undefined, cluster.connector);
|
|
150
|
+
|
|
151
|
+
const bodies = cluster.layer.requests
|
|
152
|
+
.filter((r) => r.method === "PATCH")
|
|
153
|
+
.map((r) => JSON.parse(String(r.body)) as { metadata?: { labels?: Record<string, string> } });
|
|
154
|
+
expect(bodies).toHaveLength(2);
|
|
155
|
+
for (const body of bodies) {
|
|
156
|
+
expect(body.metadata?.labels).toMatchObject({
|
|
157
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
158
|
+
"chant.intentius.io/stack": "kmv-workload",
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// The env label is the serializer's channel — restamped never, kept as-is.
|
|
162
|
+
expect(bodies[0].metadata?.labels?.["chant.intentius.io/env"]).toBe("dev");
|
|
163
|
+
// The previously-unlabeled Service now carries the marker too.
|
|
164
|
+
expect(bodies[1].metadata?.labels?.["chant.intentius.io/env"]).toBeUndefined();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("no resolvable stack applies the documents verbatim — no marker invented", async () => {
|
|
168
|
+
const file = join(dir, "k8s.yaml");
|
|
169
|
+
writeFileSync(file, deploymentYaml);
|
|
170
|
+
const cluster = fakeCluster({ respond: echoApplies });
|
|
171
|
+
|
|
172
|
+
// No stack arg, no project config: identity resolution yields none.
|
|
173
|
+
await applyManifest({ manifest: file, cwd: dir }, undefined, cluster.connector);
|
|
174
|
+
|
|
175
|
+
const body = JSON.parse(
|
|
176
|
+
String(cluster.layer.requests.find((r) => r.method === "PATCH")!.body),
|
|
177
|
+
) as { metadata?: { labels?: Record<string, string> } };
|
|
178
|
+
expect(body.metadata?.labels).toBeUndefined();
|
|
179
|
+
});
|
|
180
|
+
|
|
135
181
|
test("an explicit context is honored and skips the environment lookup entirely", async () => {
|
|
136
182
|
const file = join(dir, "k8s.yaml");
|
|
137
183
|
writeFileSync(file, deploymentYaml);
|
|
@@ -191,6 +191,44 @@ async function resolveApplyIdentity(
|
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Stamp the apply's own stack identity onto a document's labels.
|
|
196
|
+
*
|
|
197
|
+
* The serializer bakes `ownership.stack` — the *project* identity from
|
|
198
|
+
* `chant.config.ts` — into every manifest it emits. But the apply's identity
|
|
199
|
+
* is the *stack argument it resolved* (a component's `kubectl-apply` step
|
|
200
|
+
* names its own deploy unit, e.g. `kmv-workload`), and that is the value both
|
|
201
|
+
* consumers of the label query for: the owned-only prune's selector and
|
|
202
|
+
* `describeStackStatus`'s presence sweep. Applying the manifest verbatim left
|
|
203
|
+
* the label saying `kubemicrovm-ops` while both readers asked for
|
|
204
|
+
* `kmv-workload` — the prune silently matched nothing and every kubectl-apply
|
|
205
|
+
* unit read absent in `components status --live` (a green estate painted
|
|
206
|
+
* dead). A manifest chant never serialized (upstream CRDs pinned into a
|
|
207
|
+
* `crds` unit) carried no marker at all, with the same two failures.
|
|
208
|
+
*
|
|
209
|
+
* So the apply now re-stamps what it applies: `managed-by=chant` plus the
|
|
210
|
+
* resolved stack. The ownership *verdict* keys on `managed-by` alone
|
|
211
|
+
* (core/ownership.ts `hasOwnershipMarker`), so overlay classification is
|
|
212
|
+
* unchanged; the env label is the serializer's to write and is left as-is.
|
|
213
|
+
* No stack resolved (no explicit arg, no project ownership) applies verbatim,
|
|
214
|
+
* exactly as before.
|
|
215
|
+
*/
|
|
216
|
+
function stampOwnership(document: K8sObject, stack: string | undefined): K8sObject {
|
|
217
|
+
if (stack === undefined) return document;
|
|
218
|
+
const metadata = (document.metadata ?? {}) as { labels?: Record<string, string> };
|
|
219
|
+
return {
|
|
220
|
+
...document,
|
|
221
|
+
metadata: {
|
|
222
|
+
...metadata,
|
|
223
|
+
labels: {
|
|
224
|
+
...(metadata.labels ?? {}),
|
|
225
|
+
[LABEL_OWNERSHIP_KEYS.managedBy]: OWNERSHIP_MANAGED_BY_VALUE,
|
|
226
|
+
[LABEL_OWNERSHIP_KEYS.stack]: stack,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
} as K8sObject;
|
|
230
|
+
}
|
|
231
|
+
|
|
194
232
|
/**
|
|
195
233
|
* Apply every document in `args.manifest`, then prune when asked.
|
|
196
234
|
*
|
|
@@ -219,7 +257,7 @@ export async function applyManifest(
|
|
|
219
257
|
|
|
220
258
|
const applied: AppliedRef[] = [];
|
|
221
259
|
for (const document of documents) {
|
|
222
|
-
const result = await client.apply(document as K8sObject, {
|
|
260
|
+
const result = await client.apply(stampOwnership(document as K8sObject, stack), {
|
|
223
261
|
fieldManager,
|
|
224
262
|
force: args.force ?? false,
|
|
225
263
|
dryRun: args.dryRun,
|