@intentius/chant-lexicon-k8s 0.29.0 → 0.31.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/classify.d.ts +55 -0
- package/dist/api/classify.d.ts.map +1 -0
- package/dist/api/connect.d.ts +58 -0
- package/dist/api/connect.d.ts.map +1 -0
- package/dist/api/fake-cluster.d.ts +55 -0
- package/dist/api/fake-cluster.d.ts.map +1 -0
- package/dist/api/operation-surface.d.ts +64 -0
- package/dist/api/operation-surface.d.ts.map +1 -0
- package/dist/codegen/generate-operations.d.ts +29 -0
- package/dist/codegen/generate-operations.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/crd/parser.d.ts.map +1 -1
- package/dist/crd/types.d.ts +7 -0
- package/dist/crd/types.d.ts.map +1 -1
- package/dist/describe-resources.d.ts +41 -24
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/export-resources.d.ts +27 -1
- package/dist/export-resources.d.ts.map +1 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/dist/op/activities/index.d.ts +2 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/kubectl.d.ts +38 -2
- package/dist/op/activities/kubectl.d.ts.map +1 -1
- package/dist/op/activities/wait-for-ready.d.ts +30 -3
- package/dist/op/activities/wait-for-ready.d.ts.map +1 -1
- package/dist/spec/parse.d.ts +42 -0
- package/dist/spec/parse.d.ts.map +1 -1
- package/package.json +5 -2
- package/src/api/classify.test.ts +133 -0
- package/src/api/classify.ts +131 -0
- package/src/api/connect.ts +104 -0
- package/src/api/fake-cluster.ts +218 -0
- package/src/api/operation-surface.test.ts +116 -0
- package/src/api/operation-surface.ts +129 -0
- package/src/codegen/generate-operations.ts +56 -0
- package/src/codegen/generate.ts +9 -0
- package/src/config.ts +17 -0
- package/src/crd/parser.ts +8 -0
- package/src/crd/types.ts +7 -0
- package/src/describe-resources.test.ts +396 -191
- package/src/describe-resources.ts +134 -118
- package/src/export-resources-io.test.ts +76 -51
- package/src/export-resources.ts +63 -35
- package/src/generated/operations.json +2156 -0
- package/src/lifecycle-integration.test.ts +132 -92
- package/src/op/activities/index.ts +2 -1
- package/src/op/activities/kubectl.test.ts +148 -0
- package/src/op/activities/kubectl.ts +86 -13
- package/src/op/activities/wait-for-ready.test.ts +94 -0
- package/src/op/activities/wait-for-ready.ts +66 -15
- package/src/spec/parse.ts +93 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed API failure → the observation tri-state (chant #1089, #1074).
|
|
3
|
+
*
|
|
4
|
+
* `classifyKubectlFailure` in core does this by matching English on stderr,
|
|
5
|
+
* because that was all `kubectl` gave it. The API server has always sent a
|
|
6
|
+
* `Status` object with a numeric code and a `reason` enum; the typed client
|
|
7
|
+
* carries it through, so classification here reads fields rather than
|
|
8
|
+
* searching for substrings. The verdicts are deliberately the same ones the
|
|
9
|
+
* kubectl path produced — this replaces the evidence, not the contract.
|
|
10
|
+
*
|
|
11
|
+
* The one that reads as a surprise, and is not: **a kind the cluster does not
|
|
12
|
+
* serve is an absence, not a hole.** No instance of an unserved kind can exist
|
|
13
|
+
* there, and the usual cause is a CRD the very plan being computed has not
|
|
14
|
+
* applied yet. Calling it NOT-OBSERVED would suppress the create that is
|
|
15
|
+
* genuinely needed. That is core's existing rule (`classifyKubectlFailure`
|
|
16
|
+
* treats "the server doesn't have a resource type" as absent) and it survives
|
|
17
|
+
* the move intact.
|
|
18
|
+
*
|
|
19
|
+
* Errors are discriminated by `name`, not `instanceof`. The client is an
|
|
20
|
+
* optional dependency reached through a dynamic import, so this module must
|
|
21
|
+
* not carry a static value import of it — and `name` is set explicitly by
|
|
22
|
+
* every one of its error classes, which also makes the classification survive
|
|
23
|
+
* a duplicated copy of the package in a consumer's tree.
|
|
24
|
+
*/
|
|
25
|
+
import type { UnobservedReason } from "@intentius/chant/lexicon";
|
|
26
|
+
/** What a failed read actually proved. Mirrors core's `KubectlReadOutcome`. */
|
|
27
|
+
export type K8sReadOutcome =
|
|
28
|
+
/** The API server answered and the object is not there. Safe to plan a create. */
|
|
29
|
+
{
|
|
30
|
+
kind: "absent";
|
|
31
|
+
}
|
|
32
|
+
/** The read proved nothing about the object's existence. */
|
|
33
|
+
| {
|
|
34
|
+
kind: "unobserved";
|
|
35
|
+
reason: UnobservedReason;
|
|
36
|
+
detail: string;
|
|
37
|
+
};
|
|
38
|
+
/** Classify a failure from the typed client into the observation tri-state. */
|
|
39
|
+
export declare function classifyApiFailure(err: unknown): K8sReadOutcome;
|
|
40
|
+
/**
|
|
41
|
+
* Whether a failure kills the whole observation rather than one entity. A
|
|
42
|
+
* refused binding, a missing client package and a rejected credential plugin
|
|
43
|
+
* are all true of every entity, so they propagate and core marks the lot
|
|
44
|
+
* NOT-OBSERVED with one reason instead of repeating the same failure N times.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isWholeLexiconFailure(err: unknown): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* A dynamic import of the optional client package that failed to resolve looks
|
|
49
|
+
* like an ordinary module error. Recognizing it lets `describeResources` report
|
|
50
|
+
* a missing dependency as a missing dependency rather than as a broken cluster.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isMissingClientPackage(err: unknown): boolean;
|
|
53
|
+
/** The message a missing client package should produce. */
|
|
54
|
+
export declare const MISSING_CLIENT_DETAIL: string;
|
|
55
|
+
//# sourceMappingURL=classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/api/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,+EAA+E;AAC/E,MAAM,MAAM,cAAc;AACxB,kFAAkF;AAChF;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,4DAA4D;GAC1D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuBrE,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAwC/D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAEuE,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Getting from a chant environment to a live API client — chant #1074.
|
|
3
|
+
*
|
|
4
|
+
* The cluster binding (chant #1100, landed in #1155) is unchanged by the move
|
|
5
|
+
* off `kubectl`, and deliberately so: `resolveClusterTarget` in core stays the
|
|
6
|
+
* single resolver, shared with the GCP lexicon's Config Connector observation,
|
|
7
|
+
* and the refusal it throws on a bound-but-mismatched context still aborts
|
|
8
|
+
* before any resource is touched. What changes is only *how the ambient
|
|
9
|
+
* context is read*: the typed client parses the kubeconfig it is about to use
|
|
10
|
+
* rather than shelling `kubectl config current-context`, so a worker image with
|
|
11
|
+
* no `kubectl` in it can still check the binding. Same question, same three
|
|
12
|
+
* outcomes:
|
|
13
|
+
*
|
|
14
|
+
* - **Bound and ambient agrees** — the bound context is passed explicitly to
|
|
15
|
+
* the client, never left to the ambient default.
|
|
16
|
+
* - **Bound and ambient disagrees** — `ClusterBindingMismatchError`, thrown
|
|
17
|
+
* before the first request. Core turns the throw into NOT-OBSERVED for every
|
|
18
|
+
* declared entity (chant #1089), which is what stops a wrong-cluster read
|
|
19
|
+
* becoming a confident list of creates.
|
|
20
|
+
* - **Unbound** — the kubeconfig's own current-context, with the same visible
|
|
21
|
+
* warning naming the environment and the missing binding.
|
|
22
|
+
*/
|
|
23
|
+
import { type ResolvedClusterTarget } from "@intentius/chant/kubectl-context";
|
|
24
|
+
import type { K8sClient, K8sClientOptions } from "@intentius/chant-k8s-client";
|
|
25
|
+
/**
|
|
26
|
+
* Build a client for an environment. Injectable so tests drive the real client
|
|
27
|
+
* against a fake request layer, and so `describeResources` and the Op
|
|
28
|
+
* activities share one connection story rather than each inventing one.
|
|
29
|
+
*/
|
|
30
|
+
export type K8sConnector = (options: ConnectOptions) => Promise<ConnectedClient>;
|
|
31
|
+
export interface ConnectOptions {
|
|
32
|
+
/**
|
|
33
|
+
* chant environment being observed or applied to. Omitting it skips the
|
|
34
|
+
* config lookup and the binding check — which is what an Op activity called
|
|
35
|
+
* with no environment and no explicit context has always done: use whatever
|
|
36
|
+
* the kubeconfig selects.
|
|
37
|
+
*/
|
|
38
|
+
environment?: string;
|
|
39
|
+
/** Directory whose `chant.config.ts` carries `k8s.profiles`. Defaults to cwd. */
|
|
40
|
+
cwd?: string;
|
|
41
|
+
/**
|
|
42
|
+
* An explicit context, for the Op write path whose activity contract has
|
|
43
|
+
* always taken one. Skips the config lookup and the binding check entirely.
|
|
44
|
+
*/
|
|
45
|
+
context?: string;
|
|
46
|
+
/** Extra client options — the request-layer seam, concurrency. */
|
|
47
|
+
client?: Partial<K8sClientOptions>;
|
|
48
|
+
}
|
|
49
|
+
export interface ConnectedClient {
|
|
50
|
+
client: K8sClient;
|
|
51
|
+
target: ResolvedClusterTarget;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The production connector: read the project's config, resolve the binding,
|
|
55
|
+
* build a client honoring it.
|
|
56
|
+
*/
|
|
57
|
+
export declare const defaultK8sConnector: K8sConnector;
|
|
58
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/api/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/E;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAEjF,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAwCjC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A fake cluster to point the k8s lexicon at, for tests (chant #1074).
|
|
3
|
+
*
|
|
4
|
+
* It builds a **real** `@intentius/chant-k8s-client` over a literal kubeconfig
|
|
5
|
+
* with `@kubernetes/client-node`'s HTTP send replaced. So kubeconfig parsing,
|
|
6
|
+
* context selection, the credential policy, API discovery, path construction
|
|
7
|
+
* and the auth path all run for real; the only thing that does not happen is
|
|
8
|
+
* the socket. Nothing reads `~/.kube/config` or `$KUBECONFIG`, and nothing can
|
|
9
|
+
* reach a cluster the developer happens to have a context for.
|
|
10
|
+
*
|
|
11
|
+
* Shipped rather than kept in a test file because the lexicon's own tests, the
|
|
12
|
+
* cross-lexicon lifecycle suite and a consumer wiring chant into their harness
|
|
13
|
+
* all need the same thing.
|
|
14
|
+
*/
|
|
15
|
+
import type { K8sObject } from "@intentius/chant-k8s-client";
|
|
16
|
+
import type { FakeRequestLayer, RecordedRequest } from "@intentius/chant-k8s-client/testing";
|
|
17
|
+
import type { ConnectOptions, K8sConnector } from "./connect.js";
|
|
18
|
+
export interface FakeClusterOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Objects the cluster holds, keyed by
|
|
21
|
+
* `<apiVersion>/<Kind>/<namespace|_>/<name>`, e.g.
|
|
22
|
+
* `apps/v1/Deployment/prod/web`. Build keys with {@link objectKey}.
|
|
23
|
+
*/
|
|
24
|
+
objects?: Record<string, K8sObject>;
|
|
25
|
+
/**
|
|
26
|
+
* Entity types (or `<apiVersion> <Kind>` pairs) this cluster serves. Defaults
|
|
27
|
+
* to every type in the generated operation surface, which is what makes a
|
|
28
|
+
* CRD resolvable in a test without registering anything.
|
|
29
|
+
*/
|
|
30
|
+
serves?: readonly string[];
|
|
31
|
+
/** Full control: return a response for a request, or undefined to fall through. */
|
|
32
|
+
respond?: (request: RecordedRequest) => {
|
|
33
|
+
status?: number;
|
|
34
|
+
body?: unknown;
|
|
35
|
+
} | undefined;
|
|
36
|
+
/** Kubeconfig to hand the client. Defaults to a single-context one. */
|
|
37
|
+
kubeconfig?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface FakeCluster {
|
|
40
|
+
connector: K8sConnector;
|
|
41
|
+
layer: FakeRequestLayer;
|
|
42
|
+
/** Connect options every call received, for asserting the binding path. */
|
|
43
|
+
connects: ConnectOptions[];
|
|
44
|
+
}
|
|
45
|
+
/** Key an object the way {@link fakeCluster} indexes them. */
|
|
46
|
+
export declare function objectKey(apiVersion: string, kind: string, name: string, namespace?: string): string;
|
|
47
|
+
/** Build a live object with chant's ownership marker already on it. */
|
|
48
|
+
export declare function ownedObject(apiVersion: string, kind: string, name: string, namespace: string | undefined, extra?: Partial<K8sObject>): K8sObject;
|
|
49
|
+
/**
|
|
50
|
+
* A cluster that answers discovery for the kinds it serves and holds the
|
|
51
|
+
* objects it was given. Anything else 404s with a real `Status` body, which is
|
|
52
|
+
* how a test drives the absent branch of the observation tri-state.
|
|
53
|
+
*/
|
|
54
|
+
export declare function fakeCluster(options?: FakeClusterOptions): FakeCluster;
|
|
55
|
+
//# sourceMappingURL=fake-cluster.d.ts.map
|
|
@@ -0,0 +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;AAE7F,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,mFAAmF;IACnF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACxF,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,CA+FzE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the generated operation surface — chant #1074.
|
|
3
|
+
*
|
|
4
|
+
* The table itself is written by `chant generate` (see
|
|
5
|
+
* `../codegen/generate-operations.ts`); this is the runtime side, and it is
|
|
6
|
+
* deliberately the only place in the lexicon that knows how an entity type
|
|
7
|
+
* becomes an API address.
|
|
8
|
+
*
|
|
9
|
+
* Loading mirrors the serializer's handling of `lexicon-k8s.json`: a `require`
|
|
10
|
+
* behind a try/catch, so a checkout that has not run `chant generate` yet
|
|
11
|
+
* degrades to derivation rather than failing to import. Nothing here touches
|
|
12
|
+
* the filesystem at module load (chant #1081) — the first call does, and caches.
|
|
13
|
+
*/
|
|
14
|
+
/** One resource's addressing information, as `chant generate` emits it. */
|
|
15
|
+
export interface K8sOperationDescriptor {
|
|
16
|
+
/** chant entity type, e.g. `K8s::Apps::Deployment`. */
|
|
17
|
+
entityType: string;
|
|
18
|
+
/** `v1`, `apps/v1`, `ray.io/v1` — what goes in a manifest. */
|
|
19
|
+
apiVersion: string;
|
|
20
|
+
/** `Deployment`, `RayCluster`. */
|
|
21
|
+
kind: string;
|
|
22
|
+
/** Plural path segment the schema documents, e.g. `deployments`. */
|
|
23
|
+
plural: string;
|
|
24
|
+
scope: "Namespaced" | "Cluster";
|
|
25
|
+
/** Verbs the schema documents for the named-object path. */
|
|
26
|
+
verbs: string[];
|
|
27
|
+
}
|
|
28
|
+
/** The generated file's shape: entity type → descriptor. */
|
|
29
|
+
export type K8sOperationTable = Record<string, K8sOperationDescriptor>;
|
|
30
|
+
/**
|
|
31
|
+
* Fallback plural for a kind whose schema documented no named-object path.
|
|
32
|
+
*
|
|
33
|
+
* Kubernetes' own pluralization for resource names is the lowercased kind with
|
|
34
|
+
* English plural rules applied — the three cases `kubectl` implements. It only
|
|
35
|
+
* fires for kinds the OpenAPI paths do not cover, and the live client overrides
|
|
36
|
+
* it from the cluster's discovery regardless, so it is a placeholder rather
|
|
37
|
+
* than a second table to maintain.
|
|
38
|
+
*/
|
|
39
|
+
export declare function pluralizeKind(kind: string): string;
|
|
40
|
+
/** The generated table, loaded once. Empty when nothing has been generated. */
|
|
41
|
+
export declare function operationTable(): K8sOperationTable;
|
|
42
|
+
/** Reset the memoized table. Tests only. */
|
|
43
|
+
export declare function resetOperationTableForTests(): void;
|
|
44
|
+
/**
|
|
45
|
+
* How to address a declared entity type over the API.
|
|
46
|
+
*
|
|
47
|
+
* Returns undefined only for a type the generated surface does not carry and
|
|
48
|
+
* whose `K8s::<Group>::<Kind>` shape yields no known group — which is the one
|
|
49
|
+
* case where chant genuinely does not know what to ask for. Every generated
|
|
50
|
+
* resource type, including every CRD baked in at generation time, is in the
|
|
51
|
+
* table; that is the difference between this and the twenty-entry map it
|
|
52
|
+
* replaces.
|
|
53
|
+
*/
|
|
54
|
+
export declare function operationFor(entityType: string): K8sOperationDescriptor | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Last-resort derivation from the entity type's own shape, for a lexicon
|
|
57
|
+
* running without generated artifacts. It cannot invent an API group it has
|
|
58
|
+
* never seen, so an unknown group returns undefined rather than a guess that
|
|
59
|
+
* would address the wrong thing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function deriveOperation(entityType: string): K8sOperationDescriptor | undefined;
|
|
62
|
+
/** Every entity type the generated surface can address. */
|
|
63
|
+
export declare function addressableEntityTypes(): string[];
|
|
64
|
+
//# sourceMappingURL=operation-surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-surface.d.ts","sourceRoot":"","sources":["../../src/api/operation-surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,YAAY,GAAG,SAAS,CAAC;IAChC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;AAEvE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKlD;AAqBD,+EAA+E;AAC/E,wBAAgB,cAAc,IAAI,iBAAiB,CAQlD;AAED,4CAA4C;AAC5C,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAKnF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAatF;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generated operation surface — chant #1074.
|
|
3
|
+
*
|
|
4
|
+
* `describeResources` used to reach the cluster through a hand-written
|
|
5
|
+
* `entityType → kubectl resource` map with twenty entries in it. Every one of
|
|
6
|
+
* the other ~180 generated resource types, and every CRD, fell off the end of
|
|
7
|
+
* it. The map was hand-maintained precisely because nothing derived it, and
|
|
8
|
+
* nothing derived it because the codegen pass that produces the types never
|
|
9
|
+
* emitted the addressing half.
|
|
10
|
+
*
|
|
11
|
+
* It does now. This artifact is written by the same `generate()` run that
|
|
12
|
+
* writes `lexicon-k8s.json` and `index.d.ts`, out of the same parsed results,
|
|
13
|
+
* so a resource that has a declarable class necessarily has an operation entry
|
|
14
|
+
* with the same apiVersion and kind. `operation-surface.test.ts` asserts that
|
|
15
|
+
* correspondence rather than trusting it.
|
|
16
|
+
*
|
|
17
|
+
* What it is not: an authority on what a given cluster serves. `plural` and
|
|
18
|
+
* `scope` are what the schema says; the live client confirms both against the
|
|
19
|
+
* cluster's own discovery before addressing anything, because a cluster can
|
|
20
|
+
* serve a different version of a CRD than the one chant generated from.
|
|
21
|
+
*/
|
|
22
|
+
import type { K8sParseResult } from "../spec/parse.js";
|
|
23
|
+
import { type K8sOperationDescriptor, type K8sOperationTable } from "../api/operation-surface.js";
|
|
24
|
+
export type { K8sOperationDescriptor, K8sOperationTable };
|
|
25
|
+
/** Build the operation table from the same parsed results the types come from. */
|
|
26
|
+
export declare function buildOperationTable(results: K8sParseResult[]): K8sOperationTable;
|
|
27
|
+
/** Serialize the table, key-sorted so regeneration produces a stable diff. */
|
|
28
|
+
export declare function generateOperationsJSON(results: K8sParseResult[]): string;
|
|
29
|
+
//# sourceMappingURL=generate-operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-operations.d.ts","sourceRoot":"","sources":["../../src/codegen/generate-operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAiB,KAAK,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE9G,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,CAAC;AAE1D,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,iBAAiB,CAkBhF;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CAKxE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,cAAc,EAEpB,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,cAAc,EAEpB,MAAM,mCAAmC,CAAC;AAe3C,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0ErF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAWjF"}
|
package/dist/config.d.ts
CHANGED
|
@@ -58,5 +58,22 @@ export interface K8sClusterProfile {
|
|
|
58
58
|
export interface K8sChantConfig {
|
|
59
59
|
/** Named environment → cluster bindings, keyed by environment name. */
|
|
60
60
|
profiles?: Record<string, K8sClusterProfile>;
|
|
61
|
+
/**
|
|
62
|
+
* Exec credential-plugin commands chant may execute (chant #1074).
|
|
63
|
+
*
|
|
64
|
+
* On EKS, AKS and GKE, kubeconfig authentication is a subprocess:
|
|
65
|
+
* `aws eks get-token`, `kubelogin`, `gke-gcloud-auth-plugin`. Those three
|
|
66
|
+
* plus `kubectl` are allowed by default. Anything else the kubeconfig names
|
|
67
|
+
* is refused, because an exec plugin is an arbitrary binary named in a file
|
|
68
|
+
* chant did not write. Setting this **replaces** the default list.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* k8s: {
|
|
72
|
+
* profiles: { prod: { context: "prod-eks" } },
|
|
73
|
+
* execCredentialPlugins: ["aws", "my-org-oidc-helper"],
|
|
74
|
+
* } satisfies K8sChantConfig
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
execCredentialPlugins?: string[];
|
|
61
78
|
}
|
|
62
79
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,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;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,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;CAClC"}
|
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,EAAE,cAAc,EAAwD,MAAM,eAAe,CAAC;AAC1G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AA4CvC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAqB1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/crd/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAwD,MAAM,eAAe,CAAC;AAC1G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AA4CvC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAqB1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,EAAE,CAoD5D"}
|
package/dist/crd/types.d.ts
CHANGED
|
@@ -32,6 +32,13 @@ export interface CRDSource {
|
|
|
32
32
|
export interface CRDSpec {
|
|
33
33
|
/** API group (e.g. "cert-manager.io") */
|
|
34
34
|
group: string;
|
|
35
|
+
/**
|
|
36
|
+
* Whether instances are namespaced. Declared by the CRD itself, so it is the
|
|
37
|
+
* authoritative source for a custom resource's scope — the equivalent of what
|
|
38
|
+
* the OpenAPI `paths` say for built-in kinds (chant #1074). Defaults to
|
|
39
|
+
* `Namespaced`, matching the API server's own default.
|
|
40
|
+
*/
|
|
41
|
+
scope?: "Namespaced" | "Cluster";
|
|
35
42
|
/** Name variants for the CRD */
|
|
36
43
|
names: {
|
|
37
44
|
kind: string;
|
package/dist/crd/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/crd/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IACjC,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;IACF,sCAAsC;IACtC,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,0BAA0B,CAAC;IACjC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACnD,IAAI,EAAE,OAAO,CAAC;CACf"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/crd/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IACjC,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACjC,gCAAgC;IAChC,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;IACF,sCAAsC;IACtC,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,0BAA0B,CAAC;IACjC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACnD,IAAI,EAAE,OAAO,CAAC;CACf"}
|
|
@@ -2,35 +2,49 @@
|
|
|
2
2
|
* Live introspection of a Kubernetes cluster — implements the
|
|
3
3
|
* LexiconPlugin.describeResources() contract for the k8s lexicon.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* and maps the response to a ResourceMetadata entry keyed by the chant entity
|
|
7
|
-
* name (using the props.metadata.name + props.metadata.namespace from #39's
|
|
8
|
-
* entity-prop pass-through).
|
|
5
|
+
* ## What changed, and why it matters (chant #1074)
|
|
9
6
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* reason. Extending the KUBECTL_RESOURCE map converts unsupported-kind holes into
|
|
17
|
-
* real reads; until then they are holes chant admits to.
|
|
7
|
+
* This used to run `kubectl get <kind> <name> -o json` once per declared
|
|
8
|
+
* entity, serially, resolved through a hardcoded twenty-entry
|
|
9
|
+
* `KUBECTL_RESOURCE` map. Every CRD and every uncommon type fell off the end
|
|
10
|
+
* of that map and came back as a hole. Coverage, concurrency and error quality
|
|
11
|
+
* were all capped by it, and `lifecycle diff --live`, `lifecycle plan` and
|
|
12
|
+
* behold's overlay inherited the cap.
|
|
18
13
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
14
|
+
* Now:
|
|
15
|
+
*
|
|
16
|
+
* - **Coverage.** An entity type becomes an API address through the generated
|
|
17
|
+
* operation surface (`./api/operation-surface.ts`), which the same codegen
|
|
18
|
+
* pass that emits the declarable classes writes — 184 types rather than 20,
|
|
19
|
+
* CRDs included. The address is then confirmed against the cluster's *own*
|
|
20
|
+
* discovery, which is what knows the plural and the scope for the version
|
|
21
|
+
* that cluster actually serves.
|
|
22
|
+
* - **Concurrency.** Reads run through the client's bounded pool. A hundred
|
|
23
|
+
* entities are a hundred concurrent HTTP GETs sharing one connection and one
|
|
24
|
+
* cached credential, not a hundred serial process spawns.
|
|
25
|
+
* - **Error quality.** Failures arrive as typed errors carrying the API
|
|
26
|
+
* server's own `code` and `reason`, so the tri-state verdict is read off a
|
|
27
|
+
* field instead of matched against English on stderr.
|
|
28
|
+
*
|
|
29
|
+
* ## What did not change
|
|
30
|
+
*
|
|
31
|
+
* The observation tri-state (chant #1089) and the cluster binding (chant
|
|
32
|
+
* #1100/#1155) are the same contracts they were. A genuine `NotFound` — and a
|
|
33
|
+
* kind the cluster's discovery does not serve, where no instance can exist —
|
|
34
|
+
* is an absence, and only an absence becomes a `create`. Everything else is
|
|
35
|
+
* NOT-OBSERVED with a reason. A declared `k8s.profiles.<env>.context` that
|
|
36
|
+
* disagrees with the ambient one still refuses before a single resource is
|
|
37
|
+
* touched, via the same `resolveClusterTarget` the GCP lexicon shares.
|
|
26
38
|
*/
|
|
27
39
|
import type { ObservationResult } from "@intentius/chant/lexicon";
|
|
40
|
+
import type { K8sObject } from "@intentius/chant-k8s-client";
|
|
41
|
+
import { type K8sConnector } from "./api/connect.js";
|
|
28
42
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
43
|
+
* Collapse a live object to one status word. Unchanged from the kubectl path
|
|
44
|
+
* — the shape of the response is the same JSON either way.
|
|
31
45
|
*/
|
|
32
|
-
export declare
|
|
33
|
-
export
|
|
46
|
+
export declare function statusFromObject(obj: K8sObject): string;
|
|
47
|
+
export interface DescribeResourcesOptions {
|
|
34
48
|
environment: string;
|
|
35
49
|
buildOutput: string;
|
|
36
50
|
entityNames: string[];
|
|
@@ -39,5 +53,8 @@ export declare function describeResources(options: {
|
|
|
39
53
|
props: Record<string, unknown>;
|
|
40
54
|
}>;
|
|
41
55
|
owned?: boolean;
|
|
42
|
-
|
|
56
|
+
/** Directory whose `chant.config.ts` carries the cluster binding. Defaults to cwd. */
|
|
57
|
+
cwd?: string;
|
|
58
|
+
}
|
|
59
|
+
export declare function describeResources(options: DescribeResourcesOptions, connect?: K8sConnector): Promise<ObservationResult>;
|
|
43
60
|
//# sourceMappingURL=describe-resources.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAsC,MAAM,0BAA0B,CAAC;AAGtG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAiBvE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAUvD;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;CACd;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAmH5B"}
|
|
@@ -1,8 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live export for the Kubernetes lexicon — implements
|
|
3
|
+
* LexiconPlugin.exportResources() so `chant import --from <cluster-env>`
|
|
4
|
+
* regenerates live objects as chant TypeScript.
|
|
5
|
+
*
|
|
6
|
+
* Reads live objects through the typed API client (chant #1074, previously
|
|
7
|
+
* `kubectl get <kinds> -A -o json`), strips server-managed noise to reach the
|
|
8
|
+
* declared shape (kept under `verbatim`), and maps to the import IR via the
|
|
9
|
+
* shared K8sParser. All I/O lives here; the cleaning and IR-building logic is
|
|
10
|
+
* pure in `./import/live-export`.
|
|
11
|
+
*
|
|
12
|
+
* The list below is a *product* decision — what a bare `chant import` should
|
|
13
|
+
* sweep when the caller names no type — not an addressing limit. It used to be
|
|
14
|
+
* both, because `KUBECTL_RESOURCE` was simultaneously the sweep set and the
|
|
15
|
+
* only way the lexicon knew how to address anything (chant #1074 removed the
|
|
16
|
+
* second job). A `--selector type=<entity type>` import can now name any of the
|
|
17
|
+
* ~180 types the generated operation surface carries, CRDs included.
|
|
18
|
+
*/
|
|
1
19
|
import type { ExportedTemplate, ResourceSelector } from "@intentius/chant/lexicon";
|
|
20
|
+
import { type K8sConnector } from "./api/connect.js";
|
|
21
|
+
/**
|
|
22
|
+
* Entity types a bare `chant import --from <cluster>` sweeps: the workload,
|
|
23
|
+
* config, networking and RBAC kinds people actually author. Everything else is
|
|
24
|
+
* reachable by naming it with `--selector type=...`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const DEFAULT_IMPORT_TYPES: readonly string[];
|
|
2
27
|
export declare function exportResources(options: {
|
|
3
28
|
environment: string;
|
|
4
29
|
selector?: ResourceSelector;
|
|
5
30
|
owned?: boolean;
|
|
6
31
|
verbatim?: boolean;
|
|
7
|
-
|
|
32
|
+
cwd?: string;
|
|
33
|
+
}, connect?: K8sConnector): Promise<ExportedTemplate>;
|
|
8
34
|
//# sourceMappingURL=export-resources.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-resources.d.ts","sourceRoot":"","sources":["../src/export-resources.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"export-resources.d.ts","sourceRoot":"","sources":["../src/export-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAIvE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAoBjD,CAAC;AAEF,wBAAsB,eAAe,CACnC,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,EACD,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,gBAAgB,CAAC,CA4B3B"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "be792b33ca067c06a359ee06d250f08fc9ae3401507ee275c18568cfc5e55483",
|
|
5
5
|
"meta.json": "6d112006daa7196eb28619ac5a3893b709dc2b845edbd537db7d7b471e8dc104",
|
|
6
6
|
"types/index.d.ts": "7b873148146a5512c22baabfde6cfcc3248c24c2c7578f68a19544af5dc675f6",
|
|
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": "3620d7f17ce6375203ab8de306d37be7d96b1e5658c883acbf908307d52d2703"
|
|
54
54
|
}
|
package/dist/manifest.json
CHANGED
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
* dependency-light — it shells out to a CLI and does not import the k8s declarable
|
|
12
12
|
* surface — so a Temporal worker loads it cheaply.
|
|
13
13
|
*/
|
|
14
|
-
export { kubectlApply } from "./kubectl.js";
|
|
14
|
+
export { kubectlApply, readManifestDocuments } from "./kubectl.js";
|
|
15
15
|
export type { KubectlApplyArgs } from "./kubectl.js";
|
|
16
16
|
export { k3dUp, k3dDown, k3dUpCommand, k3dDownCommand, k3dExistsCommand } from "./k3d.js";
|
|
17
17
|
export type { K3dUpArgs, K3dDownArgs } from "./k3d.js";
|
|
18
18
|
export { waitForArgoSync, defaultArgoStatusFetcher, ArgoSyncFailedError } from "./argo.js";
|
|
19
19
|
export type { WaitForArgoSyncArgs, ArgoAppStatus, ArgoStatusFetcher } from "./argo.js";
|
|
20
|
-
export { waitForReady, defaultResourceFetcher, ReadinessFailedError, readinessFor, isReady, firstTerminal, DEFAULT_READINESS, READINESS_OVERRIDES, } from "./wait-for-ready.js";
|
|
20
|
+
export { waitForReady, defaultResourceFetcher, apiResourceFetcher, ReadinessFailedError, readinessFor, isReady, firstTerminal, DEFAULT_READINESS, READINESS_OVERRIDES, } from "./wait-for-ready.js";
|
|
21
21
|
export type { WaitForReadyArgs, ResourceFetcher, ReadinessSpec, ReadinessMatch, ConditionMatch, PathMatch, } from "./wait-for-ready.js";
|
|
22
22
|
export { resolveClusterTarget, ClusterBindingMismatchError } from "@intentius/chant/kubectl-context";
|
|
23
23
|
export type { ResolvedClusterTarget, K8sClusterProfile, K8sConfigShape } from "@intentius/chant/kubectl-context";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACvF,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxF,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEpF,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,cAAc,EACd,cAAc,EACd,SAAS,GACV,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AACrG,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kubectlApply` — apply a rendered manifest to a cluster.
|
|
3
|
+
*
|
|
4
|
+
* chant #1074 moved this off `kubectl apply -f`. The activity contract is
|
|
5
|
+
* unchanged (a manifest path, an optional context, `Promise<void>`, the
|
|
6
|
+
* `longInfra` profile's 15s heartbeat) because Temporal workers register it by
|
|
7
|
+
* that signature; what changed is underneath. The name is kept for the same
|
|
8
|
+
* reason.
|
|
9
|
+
*
|
|
10
|
+
* Consequences worth knowing:
|
|
11
|
+
*
|
|
12
|
+
* - **A worker image needs no `kubectl` binary.** That was the point.
|
|
13
|
+
* - **It is a server-side apply**, with `chant` as the field manager, rather
|
|
14
|
+
* than the client-side three-way merge `kubectl apply` performs by default.
|
|
15
|
+
* Server-side apply is the direction Kubernetes itself has taken, it removes
|
|
16
|
+
* the `last-applied-configuration` annotation from the story, and it is what
|
|
17
|
+
* chant #1075 builds the field-ownership and conflict surface on. A conflict
|
|
18
|
+
* with another field manager arrives here as a typed 409 rather than a line
|
|
19
|
+
* of stderr; #1075 is where it gets a proper presentation.
|
|
20
|
+
* - **Documents apply in file order**, as `kubectl apply -f` does, and a
|
|
21
|
+
* directory's files are read in sorted order.
|
|
22
|
+
*/
|
|
23
|
+
import { type K8sConnector } from "../../api/connect.js";
|
|
1
24
|
export interface KubectlApplyArgs {
|
|
25
|
+
/** Path to a manifest file, or a directory of them. */
|
|
2
26
|
manifest: string;
|
|
3
27
|
/**
|
|
4
28
|
* kubectl context name. Uses the ambient context if omitted. To target the
|
|
@@ -7,10 +31,22 @@ export interface KubectlApplyArgs {
|
|
|
7
31
|
* `./index.ts` and pass `.context` through.
|
|
8
32
|
*/
|
|
9
33
|
context?: string;
|
|
34
|
+
/**
|
|
35
|
+
* chant environment, used to resolve `k8s.profiles.<env>.context` when no
|
|
36
|
+
* explicit `context` is given. Optional and additive: omitting both keeps
|
|
37
|
+
* the previous behavior of using whatever the kubeconfig selects.
|
|
38
|
+
*/
|
|
39
|
+
environment?: string;
|
|
40
|
+
/** Field manager recorded on the applied objects. Default `chant`. */
|
|
41
|
+
fieldManager?: string;
|
|
42
|
+
/** Take ownership of fields another manager owns instead of failing (chant #1075). */
|
|
43
|
+
force?: boolean;
|
|
10
44
|
}
|
|
45
|
+
/** Read a manifest path — one file, or every YAML/JSON file in a directory. */
|
|
46
|
+
export declare function readManifestDocuments(path: string): Record<string, unknown>[];
|
|
11
47
|
/**
|
|
12
|
-
*
|
|
48
|
+
* Apply every document in `args.manifest`.
|
|
13
49
|
* Uses longInfra profile — 20m timeout, heartbeat every 15s.
|
|
14
50
|
*/
|
|
15
|
-
export declare function kubectlApply(args: KubectlApplyArgs, signal?: AbortSignal): Promise<void>;
|
|
51
|
+
export declare function kubectlApply(args: KubectlApplyArgs, signal?: AbortSignal, connect?: K8sConnector): Promise<void>;
|
|
16
52
|
//# sourceMappingURL=kubectl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kubectl.d.ts","sourceRoot":"","sources":["../../../src/op/activities/kubectl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kubectl.d.ts","sourceRoot":"","sources":["../../../src/op/activities/kubectl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E,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,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAiB7E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,gBAAgB,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,YAAkC,GAC1C,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
|