@intentius/chant-lexicon-k8s 0.1.11 → 0.1.12
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/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/package.json +1 -1
- package/src/serializer.test.ts +46 -0
- package/src/serializer.ts +28 -2
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "c2d517a9bc677aa52f78ca66f3d25ac92f030517cf2f08914db1c24fa521bb5f",
|
|
5
5
|
"meta.json": "970c70eb6eea1686f7cb8ce6ceccc46ce2e57d696d344f1dd52460e266f9a56c",
|
|
6
6
|
"types/index.d.ts": "07473e029254345488bc9952585e88bcf18da79d1026cc26744027683f472554",
|
|
7
7
|
"rules/hardcoded-namespace.ts": "ba3f43f2adbffdd87db20a2c45839354ceecda1b9f04f29ae31c4c077dddc7ec",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"skills/chant-k8s-gke.md": "8938840bf9ef5ed58d6333fdd773b3dd54ecaf25a9df35e58f7f5c3355d4928f",
|
|
43
43
|
"skills/chant-k8s-aks.md": "e18f0e2b055f72cd7a37deaf258d7027c2d4d3e286e8fd4975b27a1f981a3ad9"
|
|
44
44
|
},
|
|
45
|
-
"composite": "
|
|
45
|
+
"composite": "f3433747d714fcfb8f6dba8ba120c1b2e6edb3109f8966dc324a3cba3a82b4ff"
|
|
46
46
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
package/src/serializer.test.ts
CHANGED
|
@@ -392,4 +392,50 @@ describe("k8sSerializer", () => {
|
|
|
392
392
|
expect(kindIdx).toBeLessThan(metaIdx);
|
|
393
393
|
expect(metaIdx).toBeLessThan(specIdx);
|
|
394
394
|
});
|
|
395
|
+
|
|
396
|
+
test("CRD-wrapper trick: props.apiVersion/kind override gvk-derived defaults", () => {
|
|
397
|
+
// The Deployment-as-generic-CRD-wrapper pattern: pass arbitrary
|
|
398
|
+
// apiVersion + kind in props and the serializer should respect them
|
|
399
|
+
// (for emitting non-built-in CRDs through chant).
|
|
400
|
+
const entities = new Map<string, any>();
|
|
401
|
+
entities.set(
|
|
402
|
+
"esoStore",
|
|
403
|
+
mockResource("K8s::Apps::Deployment", {
|
|
404
|
+
apiVersion: "external-secrets.io/v1beta1",
|
|
405
|
+
kind: "ClusterSecretStore",
|
|
406
|
+
metadata: { name: "my-store" },
|
|
407
|
+
spec: { provider: { gcpsm: { projectID: "my-proj" } } },
|
|
408
|
+
}),
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
const result = k8sSerializer.serialize(entities);
|
|
412
|
+
expect(result).toContain("apiVersion: external-secrets.io/v1beta1");
|
|
413
|
+
expect(result).toContain("kind: ClusterSecretStore");
|
|
414
|
+
expect(result).not.toContain("apiVersion: apps/v1");
|
|
415
|
+
expect(result).not.toContain("kind: Deployment");
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
test("RBAC-shaped resources (rules/subjects/roleRef) stay at top level, not pushed under spec", () => {
|
|
419
|
+
// ClusterRole / Role / RoleBinding / ClusterRoleBinding don't have a
|
|
420
|
+
// spec field; their data is at the manifest root. When such a resource
|
|
421
|
+
// arrives via the CRD-wrapper trick (no spec set in props), the
|
|
422
|
+
// serializer used to dump rules/subjects/roleRef into a synthetic spec
|
|
423
|
+
// — produced invalid manifests. Now they stay at top level.
|
|
424
|
+
const entities = new Map<string, any>();
|
|
425
|
+
entities.set(
|
|
426
|
+
"viewerRole",
|
|
427
|
+
mockResource("K8s::Apps::Deployment", {
|
|
428
|
+
apiVersion: "rbac.authorization.k8s.io/v1",
|
|
429
|
+
kind: "ClusterRole",
|
|
430
|
+
metadata: { name: "viewer" },
|
|
431
|
+
rules: [{ apiGroups: [""], resources: ["pods"], verbs: ["get", "list"] }],
|
|
432
|
+
}),
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
const result = k8sSerializer.serialize(entities);
|
|
436
|
+
expect(result).toContain("kind: ClusterRole");
|
|
437
|
+
expect(result).toMatch(/^rules:/m);
|
|
438
|
+
// The bug being guarded against: rules ending up under spec.
|
|
439
|
+
expect(result).not.toMatch(/^spec:\s*\n\s+rules:/m);
|
|
440
|
+
});
|
|
395
441
|
});
|
package/src/serializer.ts
CHANGED
|
@@ -218,6 +218,28 @@ export const k8sSerializer: Serializer = {
|
|
|
218
218
|
|
|
219
219
|
manifest.metadata = metadata;
|
|
220
220
|
|
|
221
|
+
// Properties that always belong at the manifest root, never inside
|
|
222
|
+
// spec. apiVersion/kind allow consumers to override the gvk-derived
|
|
223
|
+
// defaults (the "CRD wrapper" trick used to declare arbitrary K8s
|
|
224
|
+
// resources via a generic Declarable class). rules/subjects/roleRef
|
|
225
|
+
// are the top-level fields for RBAC kinds. data/stringData are for
|
|
226
|
+
// ConfigMap/Secret. binaryData covers ConfigMap binary entries.
|
|
227
|
+
const TOP_LEVEL_PROPS = new Set([
|
|
228
|
+
"apiVersion",
|
|
229
|
+
"kind",
|
|
230
|
+
"rules",
|
|
231
|
+
"subjects",
|
|
232
|
+
"roleRef",
|
|
233
|
+
"data",
|
|
234
|
+
"stringData",
|
|
235
|
+
"binaryData",
|
|
236
|
+
"type",
|
|
237
|
+
"immutable",
|
|
238
|
+
"automountServiceAccountToken",
|
|
239
|
+
"secrets",
|
|
240
|
+
"imagePullSecrets",
|
|
241
|
+
]);
|
|
242
|
+
|
|
221
243
|
// The remaining properties go under spec (or directly on the manifest for certain types)
|
|
222
244
|
if (SPECLESS_TYPES.has(gvk.kind)) {
|
|
223
245
|
// These types have their data directly on the manifest (data, stringData, etc.)
|
|
@@ -235,10 +257,14 @@ export const k8sSerializer: Serializer = {
|
|
|
235
257
|
}
|
|
236
258
|
}
|
|
237
259
|
} else {
|
|
238
|
-
// Place remaining props under spec
|
|
260
|
+
// Place remaining props under spec — except known top-level fields
|
|
261
|
+
// (apiVersion/kind for CRD-wrapper overrides; rules/subjects for RBAC).
|
|
239
262
|
const spec: Record<string, unknown> = {};
|
|
240
263
|
for (const [key, value] of Object.entries(props)) {
|
|
241
|
-
if (key
|
|
264
|
+
if (key === "metadata") continue;
|
|
265
|
+
if (TOP_LEVEL_PROPS.has(key)) {
|
|
266
|
+
manifest[key] = value;
|
|
267
|
+
} else {
|
|
242
268
|
spec[key] = value;
|
|
243
269
|
}
|
|
244
270
|
}
|