typekro 0.26.0 → 0.27.1

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.
Files changed (73) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/alchemy/kro-delete.d.ts +8 -0
  3. package/dist/alchemy/kro-delete.d.ts.map +1 -1
  4. package/dist/alchemy/kro-delete.js +34 -35
  5. package/dist/alchemy/kro-delete.js.map +1 -1
  6. package/dist/alchemy/resource-registration.d.ts +60 -0
  7. package/dist/alchemy/resource-registration.d.ts.map +1 -1
  8. package/dist/alchemy/resource-registration.js +290 -11
  9. package/dist/alchemy/resource-registration.js.map +1 -1
  10. package/dist/alchemy/types.d.ts +44 -0
  11. package/dist/alchemy/types.d.ts.map +1 -1
  12. package/dist/core/deployment/k8s-helpers.d.ts +12 -0
  13. package/dist/core/deployment/k8s-helpers.d.ts.map +1 -1
  14. package/dist/core/deployment/k8s-helpers.js +26 -1
  15. package/dist/core/deployment/k8s-helpers.js.map +1 -1
  16. package/dist/core/deployment/kro-factory.d.ts +248 -1
  17. package/dist/core/deployment/kro-factory.d.ts.map +1 -1
  18. package/dist/core/deployment/kro-factory.js +1060 -180
  19. package/dist/core/deployment/kro-factory.js.map +1 -1
  20. package/dist/core/deployment/kro-instance-safety.d.ts +209 -0
  21. package/dist/core/deployment/kro-instance-safety.d.ts.map +1 -1
  22. package/dist/core/deployment/kro-instance-safety.js +506 -24
  23. package/dist/core/deployment/kro-instance-safety.js.map +1 -1
  24. package/dist/core/deployment/kro-namespace-teardown.d.ts +248 -0
  25. package/dist/core/deployment/kro-namespace-teardown.d.ts.map +1 -0
  26. package/dist/core/deployment/kro-namespace-teardown.js +459 -0
  27. package/dist/core/deployment/kro-namespace-teardown.js.map +1 -0
  28. package/dist/core/deployment/rollback-manager.d.ts +32 -0
  29. package/dist/core/deployment/rollback-manager.d.ts.map +1 -1
  30. package/dist/core/deployment/rollback-manager.js +69 -21
  31. package/dist/core/deployment/rollback-manager.js.map +1 -1
  32. package/dist/core/serialization/core.d.ts.map +1 -1
  33. package/dist/core/serialization/core.js +82 -8
  34. package/dist/core/serialization/core.js.map +1 -1
  35. package/dist/core/types/deployment.d.ts +20 -0
  36. package/dist/core/types/deployment.d.ts.map +1 -1
  37. package/dist/factories/apisix/types.js +11 -11
  38. package/dist/factories/apisix/types.js.map +1 -1
  39. package/dist/factories/caddy/types.js +2 -2
  40. package/dist/factories/caddy/types.js.map +1 -1
  41. package/dist/factories/cert-manager/types.js +6 -6
  42. package/dist/factories/cert-manager/types.js.map +1 -1
  43. package/dist/factories/cilium/compositions/cilium-bootstrap.js +6 -6
  44. package/dist/factories/cilium/compositions/cilium-bootstrap.js.map +1 -1
  45. package/dist/factories/clickhouse/compositions/clickhouse-cluster.js +1 -1
  46. package/dist/factories/clickhouse/compositions/clickhouse-cluster.js.map +1 -1
  47. package/dist/factories/clickhouse/types.js +8 -8
  48. package/dist/factories/clickhouse/types.js.map +1 -1
  49. package/dist/factories/clickstack/types.js +5 -5
  50. package/dist/factories/clickstack/types.js.map +1 -1
  51. package/dist/factories/cnpg/types.js +6 -6
  52. package/dist/factories/cnpg/types.js.map +1 -1
  53. package/dist/factories/dagster/types.js +14 -14
  54. package/dist/factories/dagster/types.js.map +1 -1
  55. package/dist/factories/external-dns/types.js +3 -3
  56. package/dist/factories/external-dns/types.js.map +1 -1
  57. package/dist/factories/inngest/types.js +8 -8
  58. package/dist/factories/inngest/types.js.map +1 -1
  59. package/dist/factories/ory/types.js +40 -40
  60. package/dist/factories/ory/types.js.map +1 -1
  61. package/dist/factories/rook/types.js +7 -7
  62. package/dist/factories/rook/types.js.map +1 -1
  63. package/dist/factories/searxng/types.js +2 -2
  64. package/dist/factories/searxng/types.js.map +1 -1
  65. package/dist/factories/valkey/types.js +4 -4
  66. package/dist/factories/valkey/types.js.map +1 -1
  67. package/dist/factories/webapp/types.js +8 -8
  68. package/dist/factories/webapp/types.js.map +1 -1
  69. package/dist/utils/string.d.ts +14 -0
  70. package/dist/utils/string.d.ts.map +1 -1
  71. package/dist/utils/string.js +22 -0
  72. package/dist/utils/string.js.map +1 -1
  73. package/package.json +1 -1
@@ -0,0 +1,248 @@
1
+ import type * as k8s from '@kubernetes/client-node';
2
+ import type { TypeKroLogger } from '../logging/types.js';
3
+ /**
4
+ * Annotation stamped on a hoisted workload Namespace at CREATE time, recording
5
+ * the RGD that created it — the durable ownership RECORD used by teardown. A
6
+ * Namespace is a deletion candidate ONLY if it carries this annotation set to
7
+ * THIS composition's RGD name (i.e. typekro created it for this composition);
8
+ * an adopted/pre-existing Namespace never carries it and is never deleted.
9
+ */
10
+ export declare const NAMESPACE_OWNER_ANNOTATION = "typekro.io/created-by-rgd";
11
+ /**
12
+ * Annotation stamped on the instance CR at DEPLOY time recording the CONCRETE names
13
+ * of every Namespace this instance hoisted out of the RGD graph (finding #4). Value is
14
+ * a JSON array of names (e.g. `["team-a","team-a-monitoring"]`). Teardown + the pre-hoist
15
+ * guard read it back EXACTLY so a hoisted name derived from an ARBITRARY spec field (e.g.
16
+ * `spec.targetNamespace`) round-trips without re-deriving it from `metadata.namespace` /
17
+ * `spec.namespace` (which can be wrong for non-1:1 hoists).
18
+ */
19
+ export declare const HOISTED_NAMESPACES_ANNOTATION = "typekro.io/hoisted-namespaces";
20
+ /**
21
+ * Parse the {@link HOISTED_NAMESPACES_ANNOTATION} value back into a list of namespace
22
+ * names. Tolerant: a missing/blank value yields `[]`; a malformed value yields `[]`
23
+ * (callers decide the fallback). Only string entries are returned.
24
+ */
25
+ export declare function parseHoistedNamespacesAnnotation(value: string | undefined): string[];
26
+ /**
27
+ * A richer read of {@link HOISTED_NAMESPACES_ANNOTATION} that DISTINGUISHES three cases the
28
+ * pre-hoist guard must treat differently:
29
+ * - `present` — a valid JSON array, INCLUDING an explicit empty `[]` (the instance hoists zero
30
+ * namespaces). This is per-instance PROOF and is SAFE — the guard must NOT fail closed on it.
31
+ * - `missing` — no annotation at all: a genuinely-legacy CR predating the record → FAIL CLOSED.
32
+ * - `malformed` — present but not a JSON array → FAIL CLOSED.
33
+ * (Teardown uses {@link parseHoistedNamespacesAnnotation}, where any non-list just means "nothing
34
+ * to clean" — the missing-vs-empty distinction only matters for the fail-closed guard.)
35
+ */
36
+ export type HoistedNamespacesRecord = {
37
+ readonly status: 'present';
38
+ readonly names: string[];
39
+ } | {
40
+ readonly status: 'missing';
41
+ } | {
42
+ readonly status: 'malformed';
43
+ };
44
+ export declare function readHoistedNamespacesRecord(value: string | undefined): HoistedNamespacesRecord;
45
+ /**
46
+ * The minimal LIST surface used by {@link listNamespacesOwnedByRgd}. {@link
47
+ * k8s.KubernetesObjectApi} satisfies it; tests inject a mock.
48
+ */
49
+ export interface NamespaceListApi {
50
+ list(apiVersion: string, kind: string, namespace?: string, pretty?: string, exact?: boolean, exportt?: boolean, fieldSelector?: string, labelSelector?: string, limit?: number, continueToken?: string): Promise<unknown>;
51
+ }
52
+ /**
53
+ * List the NAMES of every Namespace carrying {@link NAMESPACE_OWNER_ANNOTATION} == `rgdName`
54
+ * — the DURABLE, cluster-side record of every workload Namespace typekro created for this RGD.
55
+ *
56
+ * Unlike the CR's {@link HOISTED_NAMESPACES_ANNOTATION} (which dies WITH the instance CR), this
57
+ * record survives the CR, so:
58
+ * - a teardown RETRY after the CR is already gone can still FIND + clean the owned
59
+ * namespace(s) (and gate the RGD/CRD delete on their cleanup), and
60
+ * - the pre-hoist guard can resolve an existing instance's namespaces EXACTLY without
61
+ * approximating from `metadata.namespace` / `spec.namespace`.
62
+ *
63
+ * Lists cluster-wide (small N in practice) and filters client-side by the ownership
64
+ * annotation, FOLLOWING the list continuation token so an owned namespace beyond the first
65
+ * page is never hidden by a silent cap. A list error PROPAGATES (callers fail closed /
66
+ * preserve): an unreadable list is not proof that no owned namespace exists.
67
+ */
68
+ export declare function listNamespacesOwnedByRgd(kubeConfig: k8s.KubeConfig, rgdName: string, options?: {
69
+ k8sApi?: NamespaceListApi;
70
+ logger?: TypeKroLogger;
71
+ }): Promise<string[]>;
72
+ /**
73
+ * A namespaced RESOURCE TYPE discovered from the cluster's API surface. `apiVersion`
74
+ * is the group/version (`v1`, `apps/v1`, `kro.run/v1alpha1`); `kind` is the object
75
+ * kind used to LIST instances of the type in a namespace.
76
+ */
77
+ export interface NamespacedResourceType {
78
+ readonly apiVersion: string;
79
+ readonly kind: string;
80
+ }
81
+ /**
82
+ * Discovery + listing surface for the emptiness check, injected so the
83
+ * classification LOGIC is unit-testable OFFLINE (the maintainer validates real
84
+ * cluster discovery on OrbStack). The default cluster implementation is
85
+ * {@link createClusterNamespaceInventory}.
86
+ */
87
+ export interface NamespaceInventory {
88
+ /** All NAMESPACED, LISTABLE resource types the cluster currently serves. */
89
+ discoverNamespacedTypes(): Promise<NamespacedResourceType[]>;
90
+ /** The names of every object of `type` present in `namespace`. */
91
+ listObjectNames(type: NamespacedResourceType, namespace: string): Promise<string[]>;
92
+ }
93
+ /**
94
+ * The verdict of the emptiness gate. `empty: false` ALWAYS carries a human `reason`
95
+ * — either a real occupant, or an uncertainty (discovery/list error) that fails the
96
+ * gate toward RETAIN.
97
+ */
98
+ export type NamespaceEmptinessVerdict = {
99
+ readonly empty: true;
100
+ } | {
101
+ readonly empty: false;
102
+ readonly reason: string;
103
+ };
104
+ /**
105
+ * Whether an object found in a namespace is a k8s AUTO-PROVISIONED default that does
106
+ * NOT count as "occupied" — every namespace has these regardless of what a
107
+ * user/stack put in it:
108
+ * - the `default` ServiceAccount,
109
+ * - the `kube-root-ca.crt` ConfigMap (the injected cluster CA bundle),
110
+ * - `default-token-*` Secrets (older k8s auto-mounted the SA token this way).
111
+ *
112
+ * `Event` objects are handled at DISCOVERY time ({@link isEventType}) — they are
113
+ * transient, controller-generated bookkeeping (a just-drained namespace still holds
114
+ * deletion Events for up to the event TTL), never a resource a user/stack owns, so
115
+ * they must not pin an otherwise-empty namespace open. Treating them as occupants
116
+ * would make the gate almost never fire. This is a deliberate, documented extension
117
+ * of the brief's three-item default list.
118
+ *
119
+ * Keyed by GROUP + kind + name (finding #5): the built-in defaults all live in the
120
+ * CORE group (`""`). Keying by kind/name alone would wrongly exempt an unrelated CRD
121
+ * whose kind happened to be `ServiceAccount` / `ConfigMap` / `Secret` in some OTHER
122
+ * group — a real occupant — from the emptiness gate.
123
+ */
124
+ export declare function isAutoProvisionedDefault(group: string, kind: string, name: string): boolean;
125
+ /**
126
+ * Event types — transient, never counted as occupants. Keyed by GROUP + kind (finding
127
+ * #5): only the CORE-group (`""`) `Event` and the `events.k8s.io` `Event` are exempted,
128
+ * so an unrelated CRD named `Event` in some OTHER group is still treated as an occupant.
129
+ */
130
+ export declare function isEventType(group: string, kind: string): boolean;
131
+ /**
132
+ * Classify whether `namespace` is EMPTY (safe to delete) by enumerating every
133
+ * namespaced resource type via discovery and listing each in the namespace. Returns
134
+ * `empty: true` ONLY when nothing but k8s auto-provisioned defaults is present.
135
+ *
136
+ * FAIL SAFE (finding #3 + #4): on ANY uncertainty — discovery error, a per-type list
137
+ * error, or an unexpected occupant — the verdict is `empty: false` (RETAIN). Deleting
138
+ * an occupied namespace is high harm; retaining an empty one is low harm, so every
139
+ * ambiguity resolves toward RETAIN.
140
+ */
141
+ export declare function classifyNamespaceEmptiness(inventory: NamespaceInventory, namespace: string, logger?: TypeKroLogger): Promise<NamespaceEmptinessVerdict>;
142
+ /**
143
+ * The OWNERSHIP-gated + EMPTY-gated delete (findings #3 + #4), shared by BOTH the
144
+ * imperative `deleteInstance` path and the Alchemy teardown handler.
145
+ *
146
+ * ORDER: this runs AFTER the instance CR is gone (KRO has graph-deleted every child)
147
+ * but BEFORE the RGD/CRD teardown — the current teardown order is CR → namespace →
148
+ * RGD → CRD (the generated CRD is torn down LAST). Deleting the namespace while the
149
+ * RGD + CRD are still HEALTHY/Active is deliberate: the namespace controller confirms
150
+ * emptiness instantly and can never terminate against a *Terminating* CRD (upstream
151
+ * kro #1171). Never scans-and-deletes arbitrary namespaces: the caller passes exactly
152
+ * the namespace THIS instance declared/hoisted.
153
+ *
154
+ * TWO GATES, ownership PRIMARY: with `ownedByRgd` set (both callers pass it), the
155
+ * namespace is deleted ONLY if it carries {@link NAMESPACE_OWNER_ANNOTATION} equal to
156
+ * this RGD (typekro CREATED it) AND is empty. An ADOPTED/undeclared namespace (no
157
+ * matching stamp) is RETAINED — never deleted — as is one another stack/user still
158
+ * OCCUPIES (non-empty) or one that cannot be read (fail-safe retain).
159
+ *
160
+ * GATED (not best-effort): a pre-delete 404 is benign (already gone), but the delete
161
+ * itself polls to a real 404 and THROWS {@link DeploymentTimeoutError} on timeout — a
162
+ * stuck namespace finalizer surfaces as an error, never a silently-abandoned
163
+ * Terminating namespace. (The generated-CRD delete, a LATER step in `deleteInstance`,
164
+ * is the only best-effort deletion — see {@link KroResourceFactoryImpl.deleteInstance}.)
165
+ */
166
+ export declare function deleteNamespaceIfEmpty(kubeConfig: k8s.KubeConfig, namespace: string, options?: {
167
+ logger?: TypeKroLogger;
168
+ inventory?: NamespaceInventory;
169
+ k8sApi?: Pick<k8s.KubernetesObjectApi, 'read' | 'delete'>;
170
+ context?: Record<string, unknown>;
171
+ /**
172
+ * When set, delete ONLY if the live Namespace carries
173
+ * {@link NAMESPACE_OWNER_ANNOTATION} equal to this value (typekro created it
174
+ * for this composition's RGD). An adopted/undeclared Namespace — no matching
175
+ * ownership annotation — is RETAINED. This is the PRIMARY ownership guard;
176
+ * emptiness below is the secondary safety net.
177
+ */
178
+ ownedByRgd?: string;
179
+ /** Bound for the gated delete (poll to a real 404, throw on timeout). */
180
+ timeoutMs?: number;
181
+ }): Promise<void>;
182
+ /**
183
+ * The create-first API surface: an atomic CREATE (POST) plus a READ used only to
184
+ * classify a pre-existing namespace on conflict. {@link k8s.KubernetesObjectApi}
185
+ * satisfies this; tests inject a mock.
186
+ */
187
+ export interface NamespaceCreateFirstApi {
188
+ create(resource: k8s.KubernetesObject, pretty?: string, dryRun?: string, fieldManager?: string): Promise<unknown>;
189
+ read(resource: {
190
+ apiVersion: string;
191
+ kind: string;
192
+ metadata: {
193
+ name: string;
194
+ };
195
+ }): Promise<unknown>;
196
+ }
197
+ /** Verdict of {@link decideNamespaceOwnershipCreateFirst}. */
198
+ export interface NamespaceOwnershipDecision {
199
+ /** True IFF our CREATE returned 201 — i.e. WE created the namespace this call. */
200
+ readonly created: boolean;
201
+ /**
202
+ * True IFF typekro (this RGD) owns the namespace: it either created it now (`created`)
203
+ * or a PRIOR create by this RGD stamped it (matching {@link NAMESPACE_OWNER_ANNOTATION}).
204
+ * A namespace merely ADOPTED (created by someone else) is `owned: false`.
205
+ */
206
+ readonly owned: boolean;
207
+ }
208
+ /**
209
+ * ATOMIC ownership decision via CREATE-FIRST (finding #3), shared by the imperative and
210
+ * alchemy deploy paths. The old GET→(if 404)→SSA-patch-with-owner-stamp was raceable:
211
+ * another actor creating the namespace between the GET and the patch let typekro ADOPT
212
+ * it yet stamp it owned — and later DELETE it. Instead:
213
+ *
214
+ * 1. Attempt to CREATE the namespace (POST) WITH the ownership stamp. A 201 is proof
215
+ * WE created it → we own it (ownership is atomic: owned IFF we created it).
216
+ * 2. On 409 (already exists) it is NOT ours to claim by this call. READ it and treat
217
+ * it as owned ONLY if it already carries THIS RGD's stamp (a prior create by us);
218
+ * otherwise it is ADOPTED (`owned: false`). This 409-read is race-free for the
219
+ * ownership decision because ownership was fixed at the original 201-create.
220
+ * 3. Any OTHER create error is rethrown for the caller to handle (fail loud).
221
+ *
222
+ * `manifestWithStamp` MUST already carry {@link NAMESPACE_OWNER_ANNOTATION} = `ownerRgd`
223
+ * plus the complete declared namespace config, so a 201 lands the full config atomically.
224
+ */
225
+ export declare function decideNamespaceOwnershipCreateFirst(api: NamespaceCreateFirstApi, manifestWithStamp: k8s.KubernetesObject, ownerRgd: string, fieldManager?: string): Promise<NamespaceOwnershipDecision>;
226
+ /**
227
+ * Default {@link NamespaceInventory} backed by the live cluster. Discovery enumerates
228
+ * EVERY served API group DYNAMICALLY — the core group via `CoreV1Api.getAPIResources()`
229
+ * and every other served group via `CustomObjectsApi.getAPIResources(group, version)`
230
+ * (the generic per-group discovery endpoint, `GET /apis/{group}/{version}`) — all
231
+ * through the Bun-compatible client wrappers (no raw HTTP; identical under Bun and Node).
232
+ * This covers built-in AND custom (CRD) namespaced kinds uniformly, since a CRD's group
233
+ * appears in the served-group list. Listing uses `KubernetesObjectApi.list(apiVersion,
234
+ * kind, namespace)` and FOLLOWS the list continuation token so a namespace with more
235
+ * objects than one page never hides an occupant behind a silent cap (finding #5b).
236
+ *
237
+ * COVERAGE / UNCERTAINTY (finding #5a): the emptiness gate is a SECONDARY backstop
238
+ * (ownership is the PRIMARY teardown guard), so it must never misclassify occupied as
239
+ * empty. If the cluster serves a namespaced group this inventory CANNOT enumerate — for
240
+ * ANY reason: a native group whose discovery call fails, or an aggregated APIService
241
+ * whose external backend is unreachable — discovery THROWS an uncertainty error, which
242
+ * {@link classifyNamespaceEmptiness} turns into a fail-safe RETAIN. The ONLY groups
243
+ * deliberately skipped are the ephemeral metrics aggregation groups (their samples are
244
+ * never persistent occupants). There is no native-vs-aggregated distinction: anything we
245
+ * can't enumerate is uncertainty.
246
+ */
247
+ export declare function createClusterNamespaceInventory(kubeConfig: k8s.KubeConfig): NamespaceInventory;
248
+ //# sourceMappingURL=kro-namespace-teardown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kro-namespace-teardown.d.ts","sourceRoot":"","sources":["../../../src/core/deployment/kro-namespace-teardown.ts"],"names":[],"mappings":"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"}