@intentius/chant-lexicon-k8s 0.44.14 → 0.45.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/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/generate-lexicon.d.ts +15 -1
- package/dist/codegen/generate-lexicon.d.ts.map +1 -1
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/crd/parser.d.ts +28 -1
- package/dist/crd/parser.d.ts.map +1 -1
- package/dist/deep-observe-hooks.d.ts +60 -4
- package/dist/deep-observe-hooks.d.ts.map +1 -1
- package/dist/deep-observe.d.ts +36 -61
- package/dist/deep-observe.d.ts.map +1 -1
- package/dist/integrity.json +6 -3
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/post-synth/crd-schema-helpers.d.ts +49 -0
- package/dist/lint/post-synth/crd-schema-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8501.d.ts +14 -0
- package/dist/lint/post-synth/wk8501.d.ts.map +1 -0
- package/dist/lint/post-synth/wk8502.d.ts +13 -0
- package/dist/lint/post-synth/wk8502.d.ts.map +1 -0
- package/dist/manifest.json +1 -1
- package/dist/meta.json +126 -63
- package/dist/okf/index.md +2 -0
- package/dist/okf/rules/WK8501.md +11 -0
- package/dist/okf/rules/WK8502.md +11 -0
- package/dist/rules/crd-schema-helpers.ts +228 -0
- package/dist/rules/wk8501.ts +40 -0
- package/dist/rules/wk8502.ts +39 -0
- package/dist/spec/parse.d.ts +32 -0
- package/dist/spec/parse.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/codegen/docs.ts +0 -1044
- package/src/codegen/generate-lexicon.ts +38 -2
- package/src/codegen/snapshot.test.ts +20 -0
- package/src/components/capability-plugin.test.ts +20 -0
- package/src/components/capability-plugin.ts +5 -2
- package/src/crd/cnpg.test.ts +1 -1
- package/src/crd/infisical.test.ts +1 -1
- package/src/crd/parser.test.ts +117 -1
- package/src/crd/parser.ts +71 -5
- package/src/crd/traefik.test.ts +1 -1
- package/src/deep-observe-hooks.ts +78 -16
- package/src/deep-observe.test.ts +145 -29
- package/src/deep-observe.ts +43 -85
- package/src/generated/lexicon-k8s.json +126 -63
- package/src/lint/audit-catalog.ts +2 -0
- package/src/lint/post-synth/crd-schema-helpers.ts +228 -0
- package/src/lint/post-synth/index.ts +4 -0
- package/src/lint/post-synth/post-synth.test.ts +156 -0
- package/src/lint/post-synth/wk8501.ts +40 -0
- package/src/lint/post-synth/wk8502.ts +39 -0
- package/src/list-map-key-table.test.ts +83 -0
- package/src/op/activities/kubectl.ts +2 -2
- package/src/serializer.test.ts +4 -4
- package/src/spec/parse.ts +33 -0
- package/src/validate.ts +7 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqHH;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqHH;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB9E"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* for all Kubernetes resource and property types.
|
|
4
4
|
*/
|
|
5
5
|
import type { PropertyConstraints } from "@intentius/chant/codegen/json-schema";
|
|
6
|
-
import type { K8sParseResult } from "../spec/parse.js";
|
|
6
|
+
import type { K8sParseResult, CrdFieldSchema } from "../spec/parse.js";
|
|
7
7
|
import type { NamingStrategy } from "./naming.js";
|
|
8
8
|
export interface K8sLexiconEntry {
|
|
9
9
|
resourceType: string;
|
|
@@ -13,9 +13,23 @@ export interface K8sLexiconEntry {
|
|
|
13
13
|
gvkKind?: string;
|
|
14
14
|
deprecatedProperties?: string[];
|
|
15
15
|
constraints?: Record<string, PropertyConstraints>;
|
|
16
|
+
/**
|
|
17
|
+
* Field schema of a custom resource's `spec` (chant #1372). Only CRD-derived
|
|
18
|
+
* kinds carry one; built-in kinds are typed by the `.d.ts`. Consumed by the
|
|
19
|
+
* WK8501/WK8502 post-synth checks and the MCP catalog.
|
|
20
|
+
*/
|
|
21
|
+
specSchema?: CrdFieldSchema;
|
|
16
22
|
}
|
|
17
23
|
/**
|
|
18
24
|
* Generate the lexicon-k8s.json content.
|
|
19
25
|
*/
|
|
20
26
|
export declare function generateLexiconJSON(results: K8sParseResult[], naming: NamingStrategy): string;
|
|
27
|
+
/**
|
|
28
|
+
* Pretty-print the registry the way every lexicon does, but keep each
|
|
29
|
+
* `specSchema` on one line (chant #1372). A CRD schema nests deeply — an
|
|
30
|
+
* ApplicationSet or RayCluster embeds a whole PodTemplateSpec — and two-space
|
|
31
|
+
* indentation on that tree quadruples the file for no reader's benefit.
|
|
32
|
+
* Compact, the schemas add ~0.8 MB to the registry; pretty, ~3.9 MB.
|
|
33
|
+
*/
|
|
34
|
+
export declare function serializeWithCompactSchemas(entries: Record<string, K8sLexiconEntry>): string;
|
|
21
35
|
//# sourceMappingURL=generate-lexicon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-lexicon.d.ts","sourceRoot":"","sources":["../../src/codegen/generate-lexicon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"generate-lexicon.d.ts","sourceRoot":"","sources":["../../src/codegen/generate-lexicon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAO/C,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC9B,OAAO,EAAE,KAAK,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAClD;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,cAAc,EAAE,EACzB,MAAM,EAAE,cAAc,GACrB,MAAM,CAwCR;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,MAAM,CAkB5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-plugin.d.ts","sourceRoot":"","sources":["../../src/components/capability-plugin.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAMzG,eAAO,MAAM,iBAAiB;;;CAKpB,CAAC;AAEX,eAAO,MAAM,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"capability-plugin.d.ts","sourceRoot":"","sources":["../../src/components/capability-plugin.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAMzG,eAAO,MAAM,iBAAiB;;;CAKpB,CAAC;AAEX,eAAO,MAAM,mBAAmB,EAAE,gBAmBjC,CAAC"}
|
package/dist/crd/parser.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* main K8s swagger parser. This enables CRD-based resources to integrate
|
|
7
7
|
* with the full codegen pipeline.
|
|
8
8
|
*/
|
|
9
|
-
import type { K8sParseResult } from "../spec/parse.js";
|
|
9
|
+
import type { K8sParseResult, CrdFieldSchema } from "../spec/parse.js";
|
|
10
10
|
import type { CRDSpec } from "./types.js";
|
|
11
11
|
/**
|
|
12
12
|
* Parse a CRD YAML document string into K8sParseResult entries.
|
|
@@ -18,4 +18,31 @@ export declare function parseCRD(content: string): K8sParseResult[];
|
|
|
18
18
|
* Extracts one result per served version with storage version preferred.
|
|
19
19
|
*/
|
|
20
20
|
export declare function parseCRDSpec(spec: CRDSpec): K8sParseResult[];
|
|
21
|
+
interface OpenAPISchema {
|
|
22
|
+
type?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
properties?: Record<string, OpenAPISchema>;
|
|
25
|
+
required?: string[];
|
|
26
|
+
items?: OpenAPISchema;
|
|
27
|
+
additionalProperties?: boolean | OpenAPISchema;
|
|
28
|
+
enum?: string[];
|
|
29
|
+
format?: string;
|
|
30
|
+
minimum?: number;
|
|
31
|
+
maximum?: number;
|
|
32
|
+
minLength?: number;
|
|
33
|
+
maxLength?: number;
|
|
34
|
+
pattern?: string;
|
|
35
|
+
default?: unknown;
|
|
36
|
+
"x-kubernetes-preserve-unknown-fields"?: boolean;
|
|
37
|
+
"x-kubernetes-int-or-string"?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reduce an `openAPIV3Schema` node to the compact {@link CrdFieldSchema} the
|
|
41
|
+
* lexicon JSON ships. Walks the whole tree; drops descriptions, formats,
|
|
42
|
+
* defaults and numeric bounds. `allOf`/`oneOf`/`anyOf` are not modelled — a
|
|
43
|
+
* node that relies on them with no `type` of its own comes out untyped, which
|
|
44
|
+
* the validators treat as "anything goes".
|
|
45
|
+
*/
|
|
46
|
+
export declare function toFieldSchema(node: OpenAPISchema): CrdFieldSchema;
|
|
47
|
+
export {};
|
|
21
48
|
//# sourceMappingURL=parser.d.ts.map
|
package/dist/crd/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/crd/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/crd/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,cAAc,EAId,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKvC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAqB1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,EAAE,CAyD5D;AAID,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC,CAAC,EAAE,OAAO,CAAC;IACjD,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC;AAoLD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CA0CjE"}
|
|
@@ -22,14 +22,18 @@
|
|
|
22
22
|
* are sets addressed by a well-known identity (containers by name, ports by
|
|
23
23
|
* containerPort+protocol). None of that needs a live object in hand.
|
|
24
24
|
*
|
|
25
|
-
* What does *not* live here is the managed-fields
|
|
26
|
-
* specific field on one specific live object is
|
|
27
|
-
*
|
|
25
|
+
* What does *not* live here is the managed-fields ownership walk — which
|
|
26
|
+
* manager owns one specific field on one specific live object. That is
|
|
27
|
+
* inherently per-object (it depends on *that* object's
|
|
28
28
|
* `metadata.managedFields`, which the declared tree never carries and which
|
|
29
29
|
* differs between two Deployments of the same type), so it cannot be
|
|
30
30
|
* expressed as a fixed rule keyed only by entity type and path — the shape
|
|
31
31
|
* every other hook in this file takes. `./deep-observe.ts` computes it once
|
|
32
|
-
* per resource and
|
|
32
|
+
* per resource and attaches it to the observation as `fieldOwners`. Since
|
|
33
|
+
* chant #1191 ownership no longer prunes anything: a foreign-owned field
|
|
34
|
+
* nobody declared is reported as `undeclared` drift, and the only static
|
|
35
|
+
* subtraction for foreign writes is `K8S_SYSTEM_METADATA_PRUNE_PATTERNS`
|
|
36
|
+
* (core's `managed-fields`), applied below.
|
|
33
37
|
*
|
|
34
38
|
* The *entity-type-agnostic* half of these rules — which fields every
|
|
35
39
|
* Kubernetes API object carries regardless of kind, and the well-known
|
|
@@ -73,6 +77,57 @@ export declare const K8S_SERVICE_DEFAULTS: Record<string, Record<string, unknown
|
|
|
73
77
|
* is still compared, only the purely server-filled appearance is noise.
|
|
74
78
|
*/
|
|
75
79
|
export declare const K8S_SERVER_ASSIGNED_PATTERNS: Record<string, ReadonlySet<string>>;
|
|
80
|
+
/**
|
|
81
|
+
* The k8s lexicon's static noise rules: the generic Kubernetes object
|
|
82
|
+
* envelope (unconditional, by pattern, `@intentius/chant/managed-fields`) and
|
|
83
|
+
* Kubernetes-defaulted fields (gated on `counterpart === "absent"`), plus the
|
|
84
|
+
* array orderings.
|
|
85
|
+
*
|
|
86
|
+
* The orderings are now taken from the spec itself (chant #1441): codegen
|
|
87
|
+
* carries `x-kubernetes-list-type`/`x-kubernetes-list-map-keys` through into
|
|
88
|
+
* `./generated/list-map-keys.json`, and {@link schemaListMapOrderKey} reads
|
|
89
|
+
* it. The hand-written conventions in
|
|
90
|
+
* `@intentius/chant/managed-fields`'s `k8sListMapOrderKey` — containers by
|
|
91
|
+
* `name`, `env` by `name`, `volumes` by `name`, container/service `ports` by
|
|
92
|
+
* `containerPort`/`port` + `protocol` — remain as the fallback for lists the
|
|
93
|
+
* spec does not annotate, and for readers that have no generated table at all
|
|
94
|
+
* (GCP's Config Connector hooks).
|
|
95
|
+
*
|
|
96
|
+
* This is the object `k8sPlugin.deepNormalizationHooks` is. It is also what
|
|
97
|
+
* `./deep-observe.ts` layers its per-resource managed-fields prune on top of,
|
|
98
|
+
* so the two normalization passes (the reader's own, and core's later
|
|
99
|
+
* re-normalization of both the declared and the already-normalized live tree
|
|
100
|
+
* — see `packages/core/src/lifecycle/deep-observe.ts`) apply the identical
|
|
101
|
+
* entityType-keyed rules either way.
|
|
102
|
+
*/
|
|
103
|
+
/** Property name → candidate key-field sets, generated from the spec (chant #1441). */
|
|
104
|
+
type ListMapKeyTable = Record<string, string[][]>;
|
|
105
|
+
/**
|
|
106
|
+
* Where the generated table lives: next to this module, resolved from
|
|
107
|
+
* `import.meta.url`. This module ships as ESM (tsx strips types from src/
|
|
108
|
+
* directly), where a bare `require` is not defined — the #1441 regression
|
|
109
|
+
* crashed `lifecycle diff --live` with `require is not defined` on every
|
|
110
|
+
* estate with a Deployment, and azure's apiVersion registry hit the same
|
|
111
|
+
* class of bug in #1581. A plain fs read has no module-system dependency.
|
|
112
|
+
*/
|
|
113
|
+
export declare function listMapKeyTablePath(): string;
|
|
114
|
+
/**
|
|
115
|
+
* Load the spec-derived table once. A missing or unreadable file degrades to
|
|
116
|
+
* an EMPTY table, which routes every list through `k8sListMapOrderKey`'s
|
|
117
|
+
* hand-written conventions — the same fallback an unlisted property already
|
|
118
|
+
* takes. The empty table is cached by the caller too, so an absent artifact
|
|
119
|
+
* costs one failed read and one warning, not one per array element
|
|
120
|
+
* (chant #1476).
|
|
121
|
+
*
|
|
122
|
+
* Degrading is the right call here, unlike azure's apiVersion registry
|
|
123
|
+
* (#1581) where a silent fallback bypasses correctness-bearing pins. Without
|
|
124
|
+
* the table, drift detection narrows back to the six hardcoded properties:
|
|
125
|
+
* less coverage, never wrong answers. The warning names the regen command so
|
|
126
|
+
* the narrowing is not silent.
|
|
127
|
+
*/
|
|
128
|
+
export declare function loadListMapKeyTable(path?: string): ListMapKeyTable;
|
|
129
|
+
/** Test hook: replace (or drop) the cached table so the next lookup reloads it. */
|
|
130
|
+
export declare function resetListMapKeyTableCache(table?: ListMapKeyTable): void;
|
|
76
131
|
/**
|
|
77
132
|
* Order an associative list's element by the identity the SPEC declares for it
|
|
78
133
|
* (chant #1441), falling back to `@intentius/chant/managed-fields`'s hand-written
|
|
@@ -88,4 +143,5 @@ export declare const K8S_SERVER_ASSIGNED_PATTERNS: Record<string, ReadonlySet<st
|
|
|
88
143
|
*/
|
|
89
144
|
export declare function schemaListMapOrderKey(element: DeepArrayElement): string | undefined;
|
|
90
145
|
export declare const k8sDeepNormalizationHooks: DeepNormalizationHooks;
|
|
146
|
+
export {};
|
|
91
147
|
//# sourceMappingURL=deep-observe-hooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-observe-hooks.d.ts","sourceRoot":"","sources":["../src/deep-observe-hooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"deep-observe-hooks.d.ts","sourceRoot":"","sources":["../src/deep-observe-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAY,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAQnG;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoCxE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAE5E,CAAC;AA+BF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,uFAAuF;AACvF,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;AAIlD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,GAAE,MAA8B,GAAG,eAAe,CAWzF;AAeD,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAEvE;AAmCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAYnF;AAMD,eAAO,MAAM,yBAAyB,EAAE,sBA4BvC,CAAC"}
|
package/dist/deep-observe.d.ts
CHANGED
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
* rather than the hand-maintained `ignoreDifferences` list every Argo user
|
|
8
8
|
* keeps.
|
|
9
9
|
*
|
|
10
|
-
* ##
|
|
11
|
-
* Control"
|
|
10
|
+
* ## What managedFields decides, and what it does not
|
|
12
11
|
*
|
|
13
12
|
* AWS, Azure and Temporal's rows all prune by a **static, entityType-keyed**
|
|
14
13
|
* table: an ARN always looks like an ARN, `provisioningState` is always
|
|
@@ -17,65 +16,43 @@
|
|
|
17
16
|
* what `./deep-observe-hooks.ts`'s `k8sDeepNormalizationHooks` is, and it
|
|
18
17
|
* covers Kubernetes' *equivalent* static noise (`status`,
|
|
19
18
|
* `metadata.{uid,resourceVersion,generation,creationTimestamp}`, a handful of
|
|
20
|
-
* server-defaulted pod-spec fields
|
|
19
|
+
* server-defaulted pod-spec fields, and the annotations and labels
|
|
20
|
+
* Kubernetes' own controllers stamp on every object of a kind —
|
|
21
|
+
* `K8S_SYSTEM_METADATA_PRUNE_PATTERNS` in `@intentius/chant/managed-fields`).
|
|
21
22
|
*
|
|
22
|
-
* managedFields is
|
|
23
|
-
* *this* Deployment
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `DeepNormalizationHooks.prune` cannot see the object it is walking, only a
|
|
28
|
-
* path and a value, so this cannot be expressed as a fixed hook the way the
|
|
29
|
-
* other three rows' entire contribution is. It has to be computed once per
|
|
30
|
-
* resource, here, and layered on top of the static rules before the tree is
|
|
31
|
-
* normalized.
|
|
23
|
+
* managedFields is a different kind of fact. Which manager owns
|
|
24
|
+
* `spec.replicas` on *this* Deployment differs between two Deployments of
|
|
25
|
+
* the same type, and the declared tree never carries it at all (chant's
|
|
26
|
+
* source has no `managedFields` key to normalize). It has to be resolved once
|
|
27
|
+
* per resource, here, against the object in hand.
|
|
32
28
|
*
|
|
33
|
-
*
|
|
29
|
+
* Until chant #1191 that resolution *pruned*: a foreign-owned path nobody
|
|
30
|
+
* declared was dropped before the tree reached core, on the theory that it
|
|
31
|
+
* was controller noise. It silenced exactly the case the deep read exists
|
|
32
|
+
* for — `kubectl label deploy web team=platform` is foreign-owned
|
|
33
|
+
* (`kubectl-edit`) and undeclared, and never appeared in fieldDrift. The
|
|
34
|
+
* policy now (recorded on #1202) is:
|
|
34
35
|
*
|
|
35
|
-
*
|
|
36
|
+
* 1. **Chant-owned** (`chant`, `chant:<stack>` — chant #1075, matched on the
|
|
37
|
+
* family so a stack rename does not stop recognizing its own history) is
|
|
38
|
+
* always diffable.
|
|
39
|
+
* 2. **Declared, whoever owns it live** (a contested field) is always
|
|
40
|
+
* diffable: chant's source is a statement of intent independent of which
|
|
41
|
+
* write currently holds the field, and a foreign write that overrides a
|
|
42
|
+
* value chant's manifest asks for is the thing `lifecycle diff --live`
|
|
43
|
+
* exists to surface. It reports as `changed`.
|
|
44
|
+
* 3. **Foreign-owned and undeclared** is reported as `undeclared` drift,
|
|
45
|
+
* unless the accepted baseline already carries it at that value. The
|
|
46
|
+
* baseline (`--update-baseline`) is the noise valve: an HPA that owns
|
|
47
|
+
* `spec.replicas` on a Deployment whose source is silent about replicas
|
|
48
|
+
* reports once, gets accepted, and stays quiet until the value moves.
|
|
36
49
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* webhook defaulting a field, `kubectl-client-side-apply` from a human
|
|
44
|
-
* operator — *provided* nobody declared it (next question). Prune it.
|
|
45
|
-
* 3. **Does chant's own manifest *also* set this path?** — independent of
|
|
46
|
-
* who currently owns it live. This is the case the issue calls out by
|
|
47
|
-
* name: **a contested field chant declared is drift-relevant.** The
|
|
48
|
-
* reasoning: chant's source is a statement of intent regardless of
|
|
49
|
-
* whether a previous apply is what currently holds the field, and a
|
|
50
|
-
* foreign write that overrides a value chant's manifest asks for is
|
|
51
|
-
* exactly the thing `lifecycle diff --live` exists to surface — silencing
|
|
52
|
-
* it because *something else* currently owns the field would hide the one
|
|
53
|
-
* case where chant and the cluster disagree about a property chant is
|
|
54
|
-
* actively declaring. So: foreign-owned *and* declared is never pruned by
|
|
55
|
-
* this rule, whatever #2 would otherwise do.
|
|
56
|
-
*
|
|
57
|
-
* `counterpart: "unknown"` and why it does not help here: core's own
|
|
58
|
-
* counterpart tri-state (`side === "live" && counterpart === "absent"`, what
|
|
59
|
-
* {@link K8S_SERVICE_DEFAULTS} is gated on) answers "did the *declared tree*
|
|
60
|
-
* carry this path at all" — which is exactly question 3, but it is computed
|
|
61
|
-
* by *core*, from the raw declared and raw live trees, only on the **second**
|
|
62
|
-
* normalization pass (`packages/core/src/lifecycle/deep-observe.ts`'s
|
|
63
|
-
* `diffDeepObservation`). This reader's own call to
|
|
64
|
-
* {@link normalizeDeepProperties} runs first, with no `counterpartPaths`
|
|
65
|
-
* supplied — same as the other three rows — so `counterpart` is `"unknown"`
|
|
66
|
-
* for every node here, and a rule gated on `"absent"` would never fire during
|
|
67
|
-
* this read at all. That is fine for a table keyed only by entityType (AWS's
|
|
68
|
-
* service defaults are subtracted on core's later pass, not this one), but it
|
|
69
|
-
* is *not* fine for the managed-fields rule: if this reader left
|
|
70
|
-
* `spec.replicas` in the tree waiting for core's second pass to prune it,
|
|
71
|
-
* core would be normalizing with the *static* `k8sDeepNormalizationHooks`,
|
|
72
|
-
* which has no managedFields for this object in hand either (this reader
|
|
73
|
-
* already computed its ownership sets from data it read once and does not
|
|
74
|
-
* return). So question 3 is answered **here**, directly against the declared
|
|
75
|
-
* `props` this reader was handed — not via `counterpart` — and the result is
|
|
76
|
-
* baked into what this reader returns: a foreign-owned, undeclared field is
|
|
77
|
-
* gone from the tree before it ever reaches core, and a contested one is
|
|
78
|
-
* still there for the ordinary declared-vs-live comparison to catch.
|
|
50
|
+
* So ownership decides nothing about *whether* a path is compared. What it
|
|
51
|
+
* contributes is `fieldOwners` (#1189): every reported drift names the
|
|
52
|
+
* manager that holds the field live, which is how an operator tells
|
|
53
|
+
* `hpa-controller` doing its job from somebody running `kubectl edit`. The
|
|
54
|
+
* only fields subtracted because a foreign manager wrote them are the
|
|
55
|
+
* well-known system ones on the static allowlist.
|
|
79
56
|
*
|
|
80
57
|
* ## Resolving a managedFields entry against a live array
|
|
81
58
|
*
|
|
@@ -99,10 +76,8 @@
|
|
|
99
76
|
* container that also sets no scalar sub-fields (unusual — a real apply
|
|
100
77
|
* setting a container almost always sets `image`/`name` too) would not confer
|
|
101
78
|
* ownership onto a sibling field nobody's `fieldsV1` entry lists explicitly.
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* rather than silently pruned. Reported drift that turns out to be more
|
|
105
|
-
* noise than expected is a tuning problem; drift silently dropped is not.
|
|
79
|
+
* A path absent from every manager's fields simply has no `owner` on its
|
|
80
|
+
* drift line; it is compared like any other.
|
|
106
81
|
*
|
|
107
82
|
* ## `buildOwnershipSets` lives in core now
|
|
108
83
|
*
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4FG;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;AASjE,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,CAgHhC"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
5
|
-
"meta.json": "
|
|
4
|
+
"manifest.json": "d494ac9907d9da8ddb4456e697be2efe6e5d238df855db3c62abeb7d7036f406",
|
|
5
|
+
"meta.json": "6ec9419aa1aed8402b7957955f2a67e8c641861cfd3650886fb0898db5df14f6",
|
|
6
6
|
"types/index.d.ts": "ef2c9df6a4d1ebfbe33f96c094fbbe3fc7909522ea38e086666fbf3c8ac477fd",
|
|
7
7
|
"rules/argo-appset-single-project.ts": "afa9f310753aa2d475f35012b13135b2dfaebed2a35d44edbe185ebc07673674",
|
|
8
8
|
"rules/argo-ast.ts": "f57b7d84fef9c9cd326a7cad0dff290914e01299415d64bdab48e2f6eb4181c3",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"rules/argo002.ts": "d2f07daabfc7a4624d3d60ea151fd2380d43f1578dd6a17825f6f6e0ebc610ba",
|
|
16
16
|
"rules/argo003.ts": "a61024fbd3db772eface6b2e4fee618a5818f12a1050faea8e358e0fdc992396",
|
|
17
17
|
"rules/argo005.ts": "611ea489e005e3ead925013e636f0d7c6899fd0ce68c59a97541fc6fe4e8d25c",
|
|
18
|
+
"rules/crd-schema-helpers.ts": "62e8d3d3557f6046ead90cce7198aa1f59838acc7b4229c5dda0cf2a2893fec9",
|
|
18
19
|
"rules/flux002.ts": "4269ce13121bc5b28c02aad06765dc85085a1c9ebcc936ae958663b85de07bc6",
|
|
19
20
|
"rules/flux003.ts": "a174af9941bd2491a9bbf72039ab2fc4d4f4de388b2884ddf7123f05594d9d4e",
|
|
20
21
|
"rules/k8s-helpers.ts": "d7d5020bc9b47bfb1827e8c8cb13ad1d406890d08a964a521c9fbcb93b230827",
|
|
@@ -44,6 +45,8 @@
|
|
|
44
45
|
"rules/wk8401.ts": "860e5104d53158ebea790f5acc3d34b82d666c4808d8ee5de44b68c1c602af77",
|
|
45
46
|
"rules/wk8402.ts": "91c58dc146c6aa44b93f167fd5ed8c16cb5dc95e9d99f40685d9d0acdf7eb474",
|
|
46
47
|
"rules/wk8403.ts": "abf42e48d9539768856d71d365b5e6cbb9d4800b9f890809b70d181641a86b98",
|
|
48
|
+
"rules/wk8501.ts": "7de8c368ae0b0a2678441a97ec6bed8172f1f127bad6a8441b39ea8d1d4f1dd3",
|
|
49
|
+
"rules/wk8502.ts": "c13813543b4ec42b9b87d2ebfe20bae3e6e954a8d7c4e9387581a753484aa778",
|
|
47
50
|
"skills/chant-k8s.md": "222268f9e6b19912ece4b066d8897f009b90a3fe6f14e9c5059d0717e7ee0f82",
|
|
48
51
|
"skills/chant-k8s-patterns.md": "683148e9f0f9da6879bd65d97c82cc29dbff897e31bc11b3c1de654cd6baeea3",
|
|
49
52
|
"skills/chant-k8s-deployment-strategies.md": "c4cc93cba064230567baa755b5a3493dc69bfc6e74a62e1990d12039ffaaf5f8",
|
|
@@ -54,5 +57,5 @@
|
|
|
54
57
|
"skills/chant-k8s-argo.md": "b1a0b826559d8c5033a479c5781efaf650320f0aee4419d8841170bd3393cea5",
|
|
55
58
|
"skills/chant-k8s-flux.md": "9670efc2e9854bd14686b5adeb707396b9030a4dcaee6529b30abf56efe2c50c"
|
|
56
59
|
},
|
|
57
|
-
"composite": "
|
|
60
|
+
"composite": "1594ddb769d445bb1e070ee0e591c94da0716f03f2a4681c6284992981cf616a"
|
|
58
61
|
}
|
|
@@ -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,EAAE,MAAM,gCAAgC,CAAC;AAElH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,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,EAAE,MAAM,gCAAgC,CAAC;AAElH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAkCpD,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the custom-resource spec checks (WK8501, WK8502) — chant #1372.
|
|
3
|
+
*
|
|
4
|
+
* A CRD's constructor takes `spec: Record<string, unknown>`, so a misspelled
|
|
5
|
+
* or wrong-typed field type-checks, serializes, and is accepted by the API
|
|
6
|
+
* server (which prunes what the structural schema does not know) — the
|
|
7
|
+
* controller then runs with a default nobody chose. The generated lexicon JSON
|
|
8
|
+
* carries each CRD's `spec` field schema (`specSchema`); these helpers walk a
|
|
9
|
+
* synthesized manifest against it and report what the schema would reject.
|
|
10
|
+
*
|
|
11
|
+
* Excluded from check auto-discovery by the "helper" filename filter.
|
|
12
|
+
*/
|
|
13
|
+
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
14
|
+
import type { CrdFieldSchema } from "../../spec/parse.js";
|
|
15
|
+
import { type K8sManifest } from "./k8s-helpers.js";
|
|
16
|
+
export type { CrdFieldSchema };
|
|
17
|
+
/**
|
|
18
|
+
* Spec schemas of every CRD the lexicon ships, keyed by `apiVersion/kind`.
|
|
19
|
+
* Built-in kinds carry no `specSchema` and are never in the map.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getCrdSchemaRegistry(): Map<string, CrdFieldSchema>;
|
|
22
|
+
/** Test seam: replace the registry (pass `null` to reload from the lexicon JSON). */
|
|
23
|
+
export declare function setCrdSchemaRegistry(registry: Map<string, CrdFieldSchema> | null): void;
|
|
24
|
+
/** The schema for a manifest's `apiVersion`/`kind`, if the lexicon ships one. */
|
|
25
|
+
export declare function specSchemaFor(manifest: K8sManifest): CrdFieldSchema | undefined;
|
|
26
|
+
/** Every manifest in the build that has a shipped spec schema, with that schema. */
|
|
27
|
+
export declare function customResources(ctx: PostSynthContext): Array<{
|
|
28
|
+
manifest: K8sManifest;
|
|
29
|
+
schema: CrdFieldSchema;
|
|
30
|
+
}>;
|
|
31
|
+
export interface SpecFinding {
|
|
32
|
+
kind: "unknown-field" | "type-mismatch";
|
|
33
|
+
/** Dotted path under `spec`, e.g. `spec.source.s3bucket`. Array elements use `[i]`. */
|
|
34
|
+
path: string;
|
|
35
|
+
message: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Walk `value` against `schema` and report every field the schema does not
|
|
39
|
+
* list (unless the enclosing object is `open`) and every scalar whose type or
|
|
40
|
+
* enum membership the schema rejects. Untyped nodes pass anything.
|
|
41
|
+
*/
|
|
42
|
+
export declare function validateSpec(value: unknown, schema: CrdFieldSchema, path?: string): SpecFinding[];
|
|
43
|
+
/** Levenshtein distance between two strings. */
|
|
44
|
+
export declare function levenshtein(a: string, b: string): number;
|
|
45
|
+
/** Closest known field within Levenshtein distance 3 (case-insensitive), if any. */
|
|
46
|
+
export declare function suggestField(unknown: string, known: string[]): string | undefined;
|
|
47
|
+
/** `metadata.name` or the kind, for diagnostics. */
|
|
48
|
+
export declare function resourceLabel(manifest: K8sManifest): string;
|
|
49
|
+
//# sourceMappingURL=crd-schema-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crd-schema-helpers.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/crd-schema-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAEtF,YAAY,EAAE,cAAc,EAAE,CAAC;AAgB/B;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAkBlE;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,GAAG,IAAI,CAEvF;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,CAG/E;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,GAAG,EAAE,gBAAgB,GAAG,KAAK,CAAC;IAAE,QAAQ,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,CAS/G;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,GAAG,eAAe,CAAC;IACxC,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,SAAS,GAAG,WAAW,EAAE,CAIjG;AAgGD,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAcxD;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAWjF;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAE3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAmCvE,eAAO,MAAM,eAAe,EAAE,cAAc,EAkC3C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WK8501: Custom resource spec has a field its CRD schema does not declare
|
|
3
|
+
*
|
|
4
|
+
* A generated CRD class takes `spec: Record<string, unknown>`, so a misspelled
|
|
5
|
+
* field (`classname` for `className`) type-checks and serializes. The API
|
|
6
|
+
* server accepts the object and prunes the unknown field, the controller
|
|
7
|
+
* never sees it, and the resource runs with a default nobody chose. The
|
|
8
|
+
* lexicon ships each CRD's `spec` schema (chant #1372); this check flags any
|
|
9
|
+
* field that schema does not list, unless the enclosing object declares
|
|
10
|
+
* `x-kubernetes-preserve-unknown-fields` or `additionalProperties`.
|
|
11
|
+
*/
|
|
12
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
13
|
+
export declare const wk8501: PostSynthCheck;
|
|
14
|
+
//# sourceMappingURL=wk8501.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wk8501.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/wk8501.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,MAAM,EAAE,cAwBpB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WK8502: Custom resource spec field has the wrong type or an invalid enum value
|
|
3
|
+
*
|
|
4
|
+
* With `spec: Record<string, unknown>` on every generated CRD class, nothing
|
|
5
|
+
* at compile time stops `replicas: "2"` or `desiredState: "Runing"`. The API
|
|
6
|
+
* server rejects the first at apply and the controller ignores the second.
|
|
7
|
+
* The lexicon ships each CRD's `spec` schema (chant #1372); this check
|
|
8
|
+
* compares every scalar against its declared type and enum before apply.
|
|
9
|
+
* `x-kubernetes-int-or-string` and untyped nodes accept anything.
|
|
10
|
+
*/
|
|
11
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
12
|
+
export declare const wk8502: PostSynthCheck;
|
|
13
|
+
//# sourceMappingURL=wk8502.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wk8502.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/wk8502.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,MAAM,EAAE,cAwBpB,CAAC"}
|