@microagi/alchemy-gcp 0.6.0 → 0.7.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/CHANGELOG.md CHANGED
@@ -4,6 +4,53 @@ All notable changes to `@microagi/alchemy-gcp`. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this package
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 0.7.0 — 2026-06-16
8
+
9
+ ### Added
10
+
11
+ - **`GCP.KubernetesManifest`** — generic Alchemy resource for *any*
12
+ Kubernetes Kind/CRD, server-side-applied via
13
+ `Content-Type: application/apply-patch+yaml` with `fieldManager=alchemy`
14
+ and `force=true`. Kind → REST resource (plural + scope) resolved through
15
+ the apiserver's discovery endpoint, so built-ins and CRDs work without a
16
+ hard-coded kind→plural table. Adoption gated on the standard
17
+ `alchemy_app`/`alchemy_stage`/`alchemy_id` label triple.
18
+
19
+ - **`clusterLayer` (`src/Kubernetes/connection.ts`)** — wires a GKE
20
+ cluster into the typed `@distilled.cloud/kubernetes` SDK: ADC bearer
21
+ token (`Credentials`) + an `HttpClient` whose `FetchHttpClient.Fetch` is
22
+ overridden with a `node:https` fetch that trusts the per-cluster CA.
23
+ The stock fetch can't verify the GKE cert (it's signed by the
24
+ cluster's own CA, not a public root), so the override is required.
25
+
26
+ ### Changed
27
+
28
+ - **`GCP.KubernetesSecret` convergence** — moved off the hand-rolled
29
+ client onto typed `@distilled.cloud/kubernetes` core/v1 ops. Reconcile
30
+ is now **create + replace (PUT)** with the observed `resourceVersion`
31
+ for optimistic concurrency, bounded `Conflict` retry (recursive on the
32
+ whole observe→write flow, up to 3 re-attempts), and read-modify-write
33
+ metadata that preserves foreign annotations/owner references/finalizers
34
+ (a PUT replaces the whole object, so spreading `...observed.metadata`
35
+ first and overlaying only what we manage is essential — without it
36
+ every reconcile would strip an `ownerReference` and break garbage
37
+ collection). Validation scripts in `scripts/validate-k8s-{connection,
38
+ secret,manifest}.ts` cover live cluster runs against `research-cluster-a`.
39
+
40
+ ## 0.6.0 — 2026-06-14
41
+
42
+ ### Added
43
+
44
+ - **`GCP.KubernetesSecret`** — first Kubernetes resource in the
45
+ provider. Opaque Secret in a GKE cluster, driven via a hand-rolled
46
+ REST client with ADC bearer auth + per-cluster CA trust. Adoptable via
47
+ the standard alchemy-internal label triple.
48
+
49
+ ### Changed
50
+
51
+ - **`Auth/Credentials.fromAuthProvider`** — same fix as `0.5.1`,
52
+ re-asserted against the freshly bumped workspace pins.
53
+
7
54
  ## 0.5.1 — 2026-06-08
8
55
 
9
56
  ### Fixed
@@ -0,0 +1,100 @@
1
+ import { Credentials } from "@distilled.cloud/gcp";
2
+ import { Resource } from "alchemy";
3
+ import * as Provider from "alchemy/Provider";
4
+ import type * as GCP from "../Providers.ts";
5
+ /**
6
+ * Apply an **arbitrary** Kubernetes object to a GKE cluster via server-side
7
+ * apply — the generic escape hatch for any Kind (built-ins and CRDs alike),
8
+ * complementing the typed {@link "./Secret.ts"} resource.
9
+ *
10
+ * Convergence is a single `application/apply-patch+yaml` PATCH with
11
+ * `fieldManager: alchemy`, `force: true`. SSA merges by field ownership: only
12
+ * the fields you declare are managed, fields owned by other managers/controllers
13
+ * are left intact, and dropping a previously-declared field prunes it. The REST
14
+ * path is resolved from the apiserver's discovery endpoint, so no per-Kind code
15
+ * is required. See {@link "./client.ts"} for the full create/replace-vs-SSA
16
+ * rationale and when to prefer each.
17
+ *
18
+ * Ownership for adoption is gated on alchemy-internal `metadata.labels` (same
19
+ * triple as labelled GCP resources), so an object created out of band reads
20
+ * back as {@link Unowned} until adopted.
21
+ *
22
+ * @section Applying a manifest
23
+ * @example A ConfigMap
24
+ * ```typescript
25
+ * yield* GCP.KubernetesManifest("AppConfig", {
26
+ * endpoint: cluster.endpoint,
27
+ * caCertificate: cluster.clusterCaCertificate,
28
+ * apiVersion: "v1",
29
+ * kind: "ConfigMap",
30
+ * name: "app-config",
31
+ * namespace: "admin",
32
+ * body: { data: { LOG_LEVEL: "info" } },
33
+ * });
34
+ * ```
35
+ * @example A namespaced CRD instance
36
+ * ```typescript
37
+ * yield* GCP.KubernetesManifest("Tunnel", {
38
+ * endpoint: cluster.endpoint,
39
+ * caCertificate: cluster.clusterCaCertificate,
40
+ * apiVersion: "networking.cfargotunnel.com/v1alpha1",
41
+ * kind: "TunnelBinding",
42
+ * name: "research-ui",
43
+ * namespace: "admin",
44
+ * body: { spec: { ... } },
45
+ * });
46
+ * ```
47
+ */
48
+ export type KubernetesManifestProps = {
49
+ /**
50
+ * GKE control-plane endpoint (IP or hostname, no scheme) — typically
51
+ * `cluster.endpoint`. A change points at a different cluster → replace.
52
+ */
53
+ endpoint: string;
54
+ /**
55
+ * Base64-encoded cluster CA certificate (PEM) — typically
56
+ * `cluster.clusterCaCertificate`. Mutable (can rotate on the same cluster).
57
+ */
58
+ caCertificate: string;
59
+ /** Object `apiVersion`, e.g. `"v1"`, `"apps/v1"`. Immutable — replace. */
60
+ apiVersion: string;
61
+ /** Object `kind`, e.g. `"ConfigMap"`, `"Deployment"`. Immutable — replace. */
62
+ kind: string;
63
+ /** `metadata.name`. Immutable — replace. */
64
+ name: string;
65
+ /**
66
+ * `metadata.namespace`. Required for namespaced Kinds, omit for cluster-scoped
67
+ * ones. Immutable — replace.
68
+ */
69
+ namespace?: string;
70
+ /** Extra `metadata.labels` (alchemy ownership labels merge on top). Mutable. */
71
+ labels?: Record<string, string>;
72
+ /**
73
+ * The rest of the object — everything except `apiVersion`/`kind`/`metadata`
74
+ * (e.g. `spec`, `data`, `rules`). Mutable; may carry resolved Inputs from
75
+ * other resources. SSA prunes any key dropped from a later apply.
76
+ */
77
+ body?: Record<string, unknown>;
78
+ };
79
+ export type KubernetesManifestAttributes = {
80
+ /** Object apiVersion. */
81
+ apiVersion: string;
82
+ /** Object kind. */
83
+ kind: string;
84
+ /** metadata.name. */
85
+ name: string;
86
+ /** metadata.namespace (undefined for cluster-scoped objects). */
87
+ namespace: string | undefined;
88
+ /** Server-assigned uid. */
89
+ uid: string | undefined;
90
+ /** Server-assigned resourceVersion at last apply. */
91
+ resourceVersion: string | undefined;
92
+ /** Control-plane endpoint, threaded through for delete/read. */
93
+ endpoint: string;
94
+ /** Cluster CA certificate, threaded through for delete/read. */
95
+ caCertificate: string;
96
+ };
97
+ export type KubernetesManifest = Resource<"GCP.KubernetesManifest", KubernetesManifestProps, KubernetesManifestAttributes, never, GCP.Providers>;
98
+ export declare const KubernetesManifest: import("alchemy").ResourceClass<KubernetesManifest>;
99
+ export declare const KubernetesManifestProvider: () => import("effect/Layer").Layer<Provider.Provider<KubernetesManifest>, never, import("alchemy").Stack | import("alchemy").Stage | Credentials>;
100
+ //# sourceMappingURL=KubernetesManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KubernetesManifest.d.ts","sourceRoot":"","sources":["../../src/Kubernetes/KubernetesManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAW5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,2BAA2B;IAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,qDAAqD;IACrD,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CACvC,wBAAwB,EACxB,uBAAuB,EACvB,4BAA4B,EAC5B,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AACF,eAAO,MAAM,kBAAkB,qDAE9B,CAAC;AAoDF,eAAO,MAAM,0BAA0B,mJA+HpC,CAAC"}
@@ -0,0 +1,131 @@
1
+ import { Credentials } from "@distilled.cloud/gcp";
2
+ import { Resource } from "alchemy";
3
+ import { Unowned } from "alchemy/AdoptPolicy";
4
+ import { isResolved, somePropsAreDifferent } from "alchemy/Diff";
5
+ import * as Provider from "alchemy/Provider";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Redacted from "effect/Redacted";
8
+ import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.js";
9
+ import { applyObject, deleteObject, getObject, KubernetesApiError, } from "./client.js";
10
+ export const KubernetesManifest = Resource("GCP.KubernetesManifest");
11
+ const toAttributes = (o, parent) => ({
12
+ apiVersion: o?.apiVersion ?? parent.apiVersion,
13
+ kind: o?.kind ?? parent.kind,
14
+ name: o?.metadata?.name ?? parent.name,
15
+ namespace: o?.metadata?.namespace ?? parent.namespace,
16
+ uid: o?.metadata?.uid,
17
+ resourceVersion: o?.metadata?.resourceVersion,
18
+ endpoint: parent.endpoint,
19
+ caCertificate: parent.caCertificate,
20
+ });
21
+ /** Mint a fresh GKE connection (plain bearer token) from props + ADC creds. */
22
+ const connect = Effect.fn("k8sManifest.connect")(function* (props) {
23
+ const { accessToken } = yield* yield* Credentials;
24
+ return {
25
+ endpoint: props.endpoint,
26
+ caCertificate: props.caCertificate,
27
+ token: Redacted.value(accessToken),
28
+ };
29
+ });
30
+ /** GET the object, mapping a 404 to `undefined`. */
31
+ const observe = (connection, apiVersion, kind, namespace, name) => getObject(connection, apiVersion, kind, namespace, name).pipe(Effect.catchIf((e) => e instanceof KubernetesApiError && e.statusCode === 404, () => Effect.succeed(undefined)));
32
+ export const KubernetesManifestProvider = () => Provider.effect(KubernetesManifest, Effect.gen(function* () {
33
+ return {
34
+ // Identity (apiVersion/kind/name/namespace) and the server-assigned uid
35
+ // are unchanged by an in-place apply. endpoint is a replace trigger so
36
+ // it never changes on update; caCertificate is excluded (can rotate).
37
+ stables: [
38
+ "apiVersion",
39
+ "kind",
40
+ "name",
41
+ "namespace",
42
+ "uid",
43
+ "endpoint",
44
+ ],
45
+ diff: Effect.fn(function* ({ news, olds = {} }) {
46
+ if (!isResolved(news))
47
+ return undefined;
48
+ const o = olds;
49
+ // apiVersion/kind/name/namespace are the object's identity, and
50
+ // endpoint points at a specific cluster — any change orphans the old
51
+ // object, so create new + delete old.
52
+ if (somePropsAreDifferent(o, news, [
53
+ "apiVersion",
54
+ "kind",
55
+ "name",
56
+ "namespace",
57
+ "endpoint",
58
+ ])) {
59
+ return { action: "replace" };
60
+ }
61
+ return undefined;
62
+ }),
63
+ reconcile: Effect.fn(function* ({ id, news }) {
64
+ const labels = {
65
+ ...(news.labels ?? {}),
66
+ ...(yield* gcpInternalLabels(id)),
67
+ };
68
+ const connection = yield* connect(news);
69
+ // Build the full object: identity + merged labels + the user body.
70
+ // SSA is declarative — we send exactly what we manage (no
71
+ // resourceVersion), and force ownership of any field we name.
72
+ const object = {
73
+ ...news.body,
74
+ apiVersion: news.apiVersion,
75
+ kind: news.kind,
76
+ metadata: {
77
+ name: news.name,
78
+ ...(news.namespace ? { namespace: news.namespace } : {}),
79
+ labels,
80
+ },
81
+ };
82
+ const applied = yield* applyObject(connection, object);
83
+ // A 2xx apply normally echoes the object, but an empty-body success is
84
+ // possible — re-read so we always return real attributes (uid/
85
+ // resourceVersion). Use getObject (not observe): a missing object
86
+ // after a successful apply is a real failure, not "absent".
87
+ const final = applied?.metadata != null
88
+ ? applied
89
+ : yield* getObject(connection, news.apiVersion, news.kind, news.namespace, news.name);
90
+ return toAttributes(final, {
91
+ apiVersion: news.apiVersion,
92
+ kind: news.kind,
93
+ name: news.name,
94
+ namespace: news.namespace,
95
+ endpoint: news.endpoint,
96
+ caCertificate: news.caCertificate,
97
+ });
98
+ }),
99
+ delete: Effect.fn(function* ({ output }) {
100
+ const connection = yield* connect(output);
101
+ yield* deleteObject(connection, output.apiVersion, output.kind, output.namespace, output.name);
102
+ }),
103
+ read: Effect.fn(function* ({ id, output, olds }) {
104
+ const endpoint = output?.endpoint ?? olds?.endpoint;
105
+ const caCertificate = output?.caCertificate ?? olds?.caCertificate;
106
+ const apiVersion = output?.apiVersion ?? olds?.apiVersion;
107
+ const kind = output?.kind ?? olds?.kind;
108
+ const name = output?.name ?? olds?.name;
109
+ const namespace = output?.namespace ?? olds?.namespace;
110
+ if (!endpoint || !caCertificate || !apiVersion || !kind || !name) {
111
+ return undefined;
112
+ }
113
+ const connection = yield* connect({ endpoint, caCertificate });
114
+ const observed = yield* observe(connection, apiVersion, kind, namespace, name);
115
+ if (!observed)
116
+ return undefined;
117
+ const attrs = toAttributes(observed, {
118
+ apiVersion,
119
+ kind,
120
+ name,
121
+ namespace,
122
+ endpoint,
123
+ caCertificate,
124
+ });
125
+ return (yield* hasAlchemyLabels(id, observed.metadata?.labels))
126
+ ? attrs
127
+ : Unowned(attrs);
128
+ }),
129
+ };
130
+ }));
131
+ //# sourceMappingURL=KubernetesManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KubernetesManifest.js","sourceRoot":"","sources":["../../src/Kubernetes/KubernetesManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EACL,WAAW,EACX,YAAY,EACZ,SAAS,EACT,kBAAkB,GAGnB,MAAM,aAAa,CAAC;AAuGrB,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CACxC,wBAAwB,CACzB,CAAC;AAEF,MAAM,YAAY,GAAG,CACnB,CAAyB,EACzB,MAOC,EAC6B,EAAE,CAAC,CAAC;IAClC,UAAU,EAAE,CAAC,EAAE,UAAU,IAAI,MAAM,CAAC,UAAU;IAC9C,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI;IAC5B,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI;IACtC,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,IAAI,MAAM,CAAC,SAAS;IACrD,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG;IACrB,eAAe,EAAE,CAAC,EAAE,QAAQ,EAAE,eAAe;IAC7C,QAAQ,EAAE,MAAM,CAAC,QAAQ;IACzB,aAAa,EAAE,MAAM,CAAC,aAAa;CACpC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,EAAE,KAG3D;IACC,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;IAClD,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;KACX,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,oDAAoD;AACpD,MAAM,OAAO,GAAG,CACd,UAAyB,EACzB,UAAkB,EAClB,IAAY,EACZ,SAA6B,EAC7B,IAAY,EACZ,EAAE,CACF,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,IAAI,CAC3D,MAAM,CAAC,OAAO,CACZ,CAAC,CAAC,EAA2B,EAAE,CAC7B,CAAC,YAAY,kBAAkB,IAAI,CAAC,CAAC,UAAU,KAAK,GAAG,EACzD,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAmC,CAAC,CAC1D,CACF,CAAC;AAEJ,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,EAAE,CAC7C,QAAQ,CAAC,MAAM,CACb,kBAAkB,EAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,OAAO;QACL,wEAAwE;QACxE,uEAAuE;QACvE,sEAAsE;QACtE,OAAO,EAAE;YACP,YAAY;YACZ,MAAM;YACN,MAAM;YACN,WAAW;YACX,KAAK;YACL,UAAU;SACX;QACD,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE;YAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;YACxC,MAAM,CAAC,GAAG,IAA+B,CAAC;YAC1C,gEAAgE;YAChE,qEAAqE;YACrE,sCAAsC;YACtC,IACE,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE;gBAC7B,YAAY;gBACZ,MAAM;gBACN,MAAM;gBACN,WAAW;gBACX,UAAU;aACX,CAAC,EACF,CAAC;gBACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAW,CAAC;YACxC,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QACF,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE;YAC1C,MAAM,MAAM,GAAG;gBACb,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;gBACtB,GAAG,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;aAClC,CAAC;YACF,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAExC,mEAAmE;YACnE,0DAA0D;YAC1D,8DAA8D;YAC9D,MAAM,MAAM,GAAe;gBACzB,GAAG,IAAI,CAAC,IAAI;gBACZ,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE;oBACR,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxD,MAAM;iBACP;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAEvD,uEAAuE;YACvE,+DAA+D;YAC/D,kEAAkE;YAClE,4DAA4D;YAC5D,MAAM,KAAK,GACT,OAAO,EAAE,QAAQ,IAAI,IAAI;gBACvB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CACd,UAAU,EACV,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,IAAI,CACV,CAAC;YAER,OAAO,YAAY,CAAC,KAAK,EAAE;gBACzB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC,CAAC;QACL,CAAC,CAAC;QACF,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE;YACrC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC1C,KAAK,CAAC,CAAC,YAAY,CACjB,UAAU,EACV,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,IAAI,CACZ,CAAC;QACJ,CAAC,CAAC;QACF,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;YAC7C,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,IAAI,EAAE,QAAQ,CAAC;YACpD,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,IAAI,EAAE,aAAa,CAAC;YACnE,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,IAAI,EAAE,UAAU,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC;YACxC,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC;YACxC,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,IAAI,EAAE,SAAS,CAAC;YACvD,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACjE,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;YAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,OAAO,CAC7B,UAAU,EACV,UAAU,EACV,IAAI,EACJ,SAAS,EACT,IAAI,CACL,CAAC;YACF,IAAI,CAAC,QAAQ;gBAAE,OAAO,SAAS,CAAC;YAEhC,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE;gBACnC,UAAU;gBACV,IAAI;gBACJ,IAAI;gBACJ,SAAS;gBACT,QAAQ;gBACR,aAAa;aACd,CAAC,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAC7D,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CACH,CAAC"}
@@ -6,23 +6,31 @@ import type * as GCP from "../Providers.ts";
6
6
  /**
7
7
  * An Opaque Kubernetes Secret in a GKE cluster.
8
8
  *
9
- * Unlike the rest of the GCP provider (which calls typed
10
- * `@distilled.cloud/gcp` operations), this resource talks directly to a
11
- * GKE cluster's Kubernetes API server alchemy's upstream Kubernetes
12
- * provider is EKS-only. The control-plane connection (`endpoint` +
13
- * `caCertificate`) comes from a {@link GCP.Cluster}'s attributes; the
14
- * bearer token is minted from the provider's ADC {@link Credentials}.
9
+ * Driven through the typed `@distilled.cloud/kubernetes` SDK (core/v1) rather
10
+ * than alchemy's upstream Kubernetes provider, which is EKS-only. The
11
+ * control-plane connection (`endpoint` + `caCertificate`) comes from a
12
+ * {@link GCP.Cluster}'s attributes; the bearer token is minted from the
13
+ * provider's ADC {@link Credentials} and threaded into the cluster via
14
+ * {@link clusterLayer} (which also trusts the per-cluster CA).
15
15
  *
16
- * Ownership for adoption is gated on alchemy-internal `metadata.labels`
17
- * (same triple as labelled GCP resources), so a Secret created out of
18
- * band reads back as {@link Unowned} until adopted.
16
+ * Convergence is a typed **create-or-replace upsert** (not server-side apply):
17
+ * `reconcile` reads the Secret, then `createCoreV1NamespacedSecret` if absent
18
+ * or `replaceCoreV1NamespacedSecret` (a full PUT, carrying the observed
19
+ * `resourceVersion` for optimistic concurrency) if present. A `PUT` is a full
20
+ * object replacement, so dropping a key from `data` removes it from the stored
21
+ * Secret — the same pruning SSA gave us, without needing the
22
+ * `application/apply-patch+yaml` content type the typed PATCH op can't express.
23
+ *
24
+ * Ownership for adoption is gated on alchemy-internal `metadata.labels` (same
25
+ * triple as labelled GCP resources), so a Secret created out of band reads back
26
+ * as {@link Unowned} until adopted.
19
27
  *
20
28
  * @section Creating a Secret
21
29
  * @example Wire a Cloudflare tunnel token into the cluster
22
30
  * ```typescript
23
31
  * // `tunnel.token` is a `Redacted<string>`; pass it straight through —
24
- * // the value is unwrapped only at the moment it's written to the API,
25
- * // and stays redacted in logs/plan output.
32
+ * // the value is unwrapped only at the moment it's written to the API, and
33
+ * // stays redacted in logs/plan output.
26
34
  * yield* GCP.KubernetesSecret("CloudflaredTunnelSecret", {
27
35
  * endpoint: cluster.endpoint,
28
36
  * caCertificate: cluster.clusterCaCertificate,
@@ -53,15 +61,14 @@ export type KubernetesSecretProps = {
53
61
  /** Secret `type`. Default `"Opaque"`. Mutable. */
54
62
  type?: string;
55
63
  /**
56
- * String data (written under `stringData`; UTF-8 values). Mutable.
64
+ * String data (UTF-8 values, base64-encoded on the way to the API). Mutable.
57
65
  *
58
- * Values may be `Redacted<string>` (e.g. a resource's secret output
59
- * like `tunnel.token`) — they are unwrapped only when written to the
60
- * Kubernetes API and stay opaque in logs/plan output. Plain strings
61
- * are accepted too.
66
+ * Values may be `Redacted<string>` (e.g. a resource's secret output like
67
+ * `tunnel.token`) — they are unwrapped only when written to the Kubernetes
68
+ * API and stay opaque in logs/plan output. Plain strings are accepted too.
62
69
  *
63
- * NOTE: the underlying values are persisted in alchemy stack state
64
- * (the engine diffs on the real value) — protect the state backend.
70
+ * NOTE: the underlying values are persisted in alchemy stack state (the
71
+ * engine diffs on the real value) — protect the state backend.
65
72
  */
66
73
  stringData: Record<string, Redacted.Redacted<string> | string>;
67
74
  /** Extra metadata labels (alchemy ownership labels merge on top). Mutable. */
@@ -1 +1 @@
1
- {"version":3,"file":"Secret.d.ts","sourceRoot":"","sources":["../../src/Kubernetes/Secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAW5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;OAUG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/D,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,qDAAqD;IACrD,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CACrC,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AACF,eAAO,MAAM,gBAAgB,mDAE5B,CAAC;AA2CF,eAAO,MAAM,wBAAwB,iJAwHlC,CAAC"}
1
+ {"version":3,"file":"Secret.d.ts","sourceRoot":"","sources":["../../src/Kubernetes/Secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOnD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAI5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;OASG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/D,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,qDAAqD;IACrD,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CACrC,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AACF,eAAO,MAAM,gBAAgB,mDAE5B,CAAC;AAuEF,eAAO,MAAM,wBAAwB,iJAgKlC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { Credentials } from "@distilled.cloud/gcp";
2
+ import { createCoreV1NamespacedSecret, deleteCoreV1NamespacedSecret, readCoreV1NamespacedSecret, replaceCoreV1NamespacedSecret, } from "@distilled.cloud/kubernetes/core";
2
3
  import { Resource } from "alchemy";
3
4
  import { Unowned } from "alchemy/AdoptPolicy";
4
5
  import { isResolved, somePropsAreDifferent } from "alchemy/Diff";
@@ -7,7 +8,7 @@ import * as Provider from "alchemy/Provider";
7
8
  import * as Effect from "effect/Effect";
8
9
  import * as Redacted from "effect/Redacted";
9
10
  import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.js";
10
- import { applySecret, deleteSecret, getSecret, KubernetesApiError, } from "./client.js";
11
+ import { clusterLayer } from "./connection.js";
11
12
  export const KubernetesSecret = Resource("GCP.KubernetesSecret");
12
13
  const toAttributes = (s, parent) => ({
13
14
  name: s?.metadata?.name ?? parent.name,
@@ -24,37 +25,46 @@ const connect = Effect.fn("k8sSecret.connect")(function* (props) {
24
25
  return {
25
26
  endpoint: props.endpoint,
26
27
  caCertificate: props.caCertificate,
27
- token: Redacted.value(accessToken),
28
+ token: accessToken,
28
29
  };
29
30
  });
30
- const observe = (connection, namespace, name) => getSecret(connection, namespace, name).pipe(Effect.catchIf((e) => e instanceof KubernetesApiError && e.statusCode === 404, () => Effect.succeed(undefined)));
31
+ /** GET a Secret, mapping a 404 (`NotFound`) to `undefined`. */
32
+ const observe = (connection, namespace, name) => readCoreV1NamespacedSecret({ namespace, name }).pipe(Effect.provide(clusterLayer(connection)), Effect.catchTag("NotFound", () => Effect.succeed(undefined)));
33
+ /** Base64-encode the (possibly redacted) string values for the `data` field. */
34
+ const encodeData = (stringData) => {
35
+ const data = {};
36
+ for (const [k, v] of Object.entries(stringData)) {
37
+ const raw = Redacted.isRedacted(v) ? Redacted.value(v) : v;
38
+ data[k] = Buffer.from(raw, "utf8").toString("base64");
39
+ }
40
+ return data;
41
+ };
31
42
  export const KubernetesSecretProvider = () => Provider.effect(KubernetesSecret, Effect.gen(function* () {
32
43
  return {
33
- // Attributes unchanged by an in-place update (so dependents can
34
- // resolve them at plan time): identity (name/namespace), the
35
- // server-assigned uid, and endpoint — which is a replace trigger,
36
- // so it never changes on update. caCertificate is intentionally
37
- // excluded: it can rotate on the same cluster.
44
+ // Attributes unchanged by an in-place update (so dependents can resolve
45
+ // them at plan time): identity (name/namespace), the server-assigned
46
+ // uid, and endpoint — which is a replace trigger, so it never changes
47
+ // on update. caCertificate is intentionally excluded: it can rotate on
48
+ // the same cluster.
38
49
  stables: ["name", "namespace", "endpoint", "uid"],
39
50
  diff: Effect.fn(function* ({ id, news, olds = {} }) {
40
51
  if (!isResolved(news))
41
52
  return undefined;
42
53
  const o = olds;
43
- // Compare the RESOLVED name and type (with their defaults
44
- // applied), not the raw props — otherwise omitting `name` on one
45
- // side and setting it to the generated physical name on the
46
- // other (or the same for `type`/"Opaque") triggers a spurious
47
- // replace.
54
+ // Compare the RESOLVED name and type (with their defaults applied),
55
+ // not the raw props — otherwise omitting `name` on one side and
56
+ // setting it to the generated physical name on the other (or the
57
+ // same for `type`/"Opaque") triggers a spurious replace.
48
58
  const defaultName = (yield* createPhysicalName({ id, maxLength: 63 })).toLowerCase();
49
59
  const sameName = (o.name ?? defaultName) === (news.name ?? defaultName);
50
60
  const sameType = (o.type ?? "Opaque") === (news.type ?? "Opaque");
51
- // Replace (create new + delete old) rather than in-place SSA on:
52
- // - `endpoint`: points at a different cluster (would orphan the
53
- // old Secret). caCertificate is excluded — it can rotate on
54
- // the same cluster and should just re-apply.
61
+ // Replace (create new + delete old) rather than in-place upsert on:
62
+ // - `endpoint`: points at a different cluster (would orphan the old
63
+ // Secret). caCertificate is excluded — it can rotate on the same
64
+ // cluster and should just re-apply.
55
65
  // - `namespace`/`name`: the object's identity.
56
- // - `type`: immutable on a Kubernetes Secret; an in-place apply
57
- // with a new type is rejected by the API.
66
+ // - `type`: immutable on a Kubernetes Secret; a PUT with a new type
67
+ // is rejected by the API.
58
68
  if (!sameName ||
59
69
  !sameType ||
60
70
  somePropsAreDifferent(o, news, ["namespace", "endpoint"])) {
@@ -71,33 +81,52 @@ export const KubernetesSecretProvider = () => Provider.effect(KubernetesSecret,
71
81
  ...(yield* gcpInternalLabels(id)),
72
82
  };
73
83
  const connection = yield* connect(news);
74
- // Unwrap any Redacted values at the last moment — Redacted is
75
- // kept opaque through Output resolution, so it arrives here as
76
- // a Redacted object that would JSON-serialize to "<redacted>"
77
- // if passed through verbatim then base64-encode for `data`.
78
- const data = {};
79
- for (const [k, v] of Object.entries(news.stringData)) {
80
- const raw = Redacted.isRedacted(v) ? Redacted.value(v) : v;
81
- data[k] = Buffer.from(raw, "utf8").toString("base64");
82
- }
83
- // Server-side apply is an idempotent upsert it both creates
84
- // the Secret if missing and converges its data/labels if it
85
- // exists, taking field-manager ownership (force=true).
86
- const applied = yield* applySecret(connection, {
87
- metadata: { name: desiredName, namespace: news.namespace, labels },
84
+ const layer = clusterLayer(connection);
85
+ const data = encodeData(news.stringData);
86
+ // Full-object PUT for an existing Secret carries the observed
87
+ // resourceVersion (the API requires it for updates and uses it for
88
+ // optimistic concurrency).
89
+ const replaceFrom = (observed) => replaceCoreV1NamespacedSecret({
90
+ namespace: news.namespace,
91
+ name: desiredName,
92
+ fieldManager: "alchemy",
93
+ // Read-modify-write: a PUT replaces the WHOLE object, so preserve
94
+ // the observed metadata (annotations, ownerReferences, finalizers,
95
+ // …) and overlay only what we manage — otherwise every reconcile
96
+ // strips fields other managers set (e.g. an ownerReference, which
97
+ // would break garbage collection). `observed.metadata` carries the
98
+ // full server object at runtime (the local type is a subset).
99
+ // Labels merge (ours win) so foreign labels survive too. (The SSA
100
+ // path — GCP.KubernetesManifest — does field-level pruning instead;
101
+ // the typed PUT path deliberately preserves rather than prunes.)
102
+ metadata: {
103
+ ...observed.metadata,
104
+ name: desiredName,
105
+ labels: { ...observed.metadata?.labels, ...labels },
106
+ resourceVersion: observed.metadata?.resourceVersion,
107
+ },
88
108
  type: desiredType,
89
109
  data,
90
- });
91
- // A 2xx apply normally echoes the object, but a successful
92
- // empty-body response is possible re-read so we always return
93
- // real attributes (uid/resourceVersion) rather than crash. Use
94
- // getSecret (NOT observe): if the Secret is somehow absent after
95
- // a successful apply, propagate the 404 and fail the reconcile
96
- // instead of recording an empty success.
97
- const final = applied?.metadata
98
- ? applied
99
- : yield* getSecret(connection, news.namespace, desiredName);
100
- return toAttributes(final, {
110
+ }).pipe(Effect.provide(layer));
111
+ // Observe ensure: create if absent, else read-modify-write replace.
112
+ // Adoption (output defined, olds undefined) traverses the same flow.
113
+ const writeOnce = observe(connection, news.namespace, desiredName).pipe(Effect.flatMap((observed) => observed
114
+ ? replaceFrom(observed)
115
+ : createCoreV1NamespacedSecret({
116
+ namespace: news.namespace,
117
+ fieldManager: "alchemy",
118
+ metadata: { name: desiredName, labels },
119
+ type: desiredType,
120
+ data,
121
+ }).pipe(Effect.provide(layer))));
122
+ // Retry the WHOLE observe→write flow on Conflict — a stale
123
+ // resourceVersion (replace) or a create/delete race re-observes fresh
124
+ // state and writes again, so a second conflict is handled too. Bounded
125
+ // so a persistently-contended object fails (and the engine
126
+ // re-reconciles) rather than spinning forever.
127
+ const upsert = (attempt) => writeOnce.pipe(Effect.catchTag("Conflict", (e) => attempt < 3 ? upsert(attempt + 1) : Effect.fail(e)));
128
+ const result = yield* upsert(0);
129
+ return toAttributes(result, {
101
130
  name: desiredName,
102
131
  namespace: news.namespace,
103
132
  endpoint: news.endpoint,
@@ -107,7 +136,12 @@ export const KubernetesSecretProvider = () => Provider.effect(KubernetesSecret,
107
136
  }),
108
137
  delete: Effect.fn(function* ({ output }) {
109
138
  const connection = yield* connect(output);
110
- yield* deleteSecret(connection, output.namespace, output.name);
139
+ yield* deleteCoreV1NamespacedSecret({
140
+ namespace: output.namespace,
141
+ name: output.name,
142
+ }).pipe(Effect.provide(clusterLayer(connection)),
143
+ // 404 is success (idempotent teardown).
144
+ Effect.catchTag("NotFound", () => Effect.void));
111
145
  }),
112
146
  read: Effect.fn(function* ({ id, output, olds }) {
113
147
  const endpoint = output?.endpoint ?? olds?.endpoint;
@@ -1 +1 @@
1
- {"version":3,"file":"Secret.js","sourceRoot":"","sources":["../../src/Kubernetes/Secret.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Secret.js","sourceRoot":"","sources":["../../src/Kubernetes/Secret.ts"],"names":[],"mappings":"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"}