@alchemy.run/kubernetes 0.0.0 → 2.0.0-beta.85

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 (94) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +41 -4
  3. package/lib/BuiltinAdapters.d.ts +43 -0
  4. package/lib/BuiltinAdapters.d.ts.map +1 -0
  5. package/lib/BuiltinAdapters.js +129 -0
  6. package/lib/BuiltinAdapters.js.map +1 -0
  7. package/lib/Client.d.ts +97 -0
  8. package/lib/Client.d.ts.map +1 -0
  9. package/lib/Client.js +312 -0
  10. package/lib/Client.js.map +1 -0
  11. package/lib/ClusterAdapter.d.ts +324 -0
  12. package/lib/ClusterAdapter.d.ts.map +1 -0
  13. package/lib/ClusterAdapter.js +65 -0
  14. package/lib/ClusterAdapter.js.map +1 -0
  15. package/lib/Connection.d.ts +210 -0
  16. package/lib/Connection.d.ts.map +1 -0
  17. package/lib/Connection.js +58 -0
  18. package/lib/Connection.js.map +1 -0
  19. package/lib/Deployment.d.ts +401 -0
  20. package/lib/Deployment.d.ts.map +1 -0
  21. package/lib/Deployment.js +550 -0
  22. package/lib/Deployment.js.map +1 -0
  23. package/lib/HelmChart.d.ts +147 -0
  24. package/lib/HelmChart.d.ts.map +1 -0
  25. package/lib/HelmChart.js +248 -0
  26. package/lib/HelmChart.js.map +1 -0
  27. package/lib/Job.d.ts +333 -0
  28. package/lib/Job.d.ts.map +1 -0
  29. package/lib/Job.js +443 -0
  30. package/lib/Job.js.map +1 -0
  31. package/lib/LocalCluster.d.ts +243 -0
  32. package/lib/LocalCluster.d.ts.map +1 -0
  33. package/lib/LocalCluster.js +359 -0
  34. package/lib/LocalCluster.js.map +1 -0
  35. package/lib/Manifest.d.ts +157 -0
  36. package/lib/Manifest.d.ts.map +1 -0
  37. package/lib/Manifest.js +205 -0
  38. package/lib/Manifest.js.map +1 -0
  39. package/lib/Objects.d.ts +60 -0
  40. package/lib/Objects.d.ts.map +1 -0
  41. package/lib/Objects.js +132 -0
  42. package/lib/Objects.js.map +1 -0
  43. package/lib/Providers.d.ts +24 -0
  44. package/lib/Providers.d.ts.map +1 -0
  45. package/lib/Providers.js +36 -0
  46. package/lib/Providers.js.map +1 -0
  47. package/lib/index.d.ts +10 -0
  48. package/lib/index.d.ts.map +1 -0
  49. package/lib/index.js +10 -0
  50. package/lib/index.js.map +1 -0
  51. package/lib/internal/declared.d.ts +19 -0
  52. package/lib/internal/declared.d.ts.map +1 -0
  53. package/lib/internal/declared.js +435 -0
  54. package/lib/internal/declared.js.map +1 -0
  55. package/lib/internal/helm.d.ts +65 -0
  56. package/lib/internal/helm.d.ts.map +1 -0
  57. package/lib/internal/helm.js +173 -0
  58. package/lib/internal/helm.js.map +1 -0
  59. package/lib/internal/kind.d.ts +17 -0
  60. package/lib/internal/kind.d.ts.map +1 -0
  61. package/lib/internal/kind.js +31 -0
  62. package/lib/internal/kind.js.map +1 -0
  63. package/lib/internal/kubeconfig.d.ts +79 -0
  64. package/lib/internal/kubeconfig.d.ts.map +1 -0
  65. package/lib/internal/kubeconfig.js +222 -0
  66. package/lib/internal/kubeconfig.js.map +1 -0
  67. package/lib/internal/registry.d.ts +44 -0
  68. package/lib/internal/registry.d.ts.map +1 -0
  69. package/lib/internal/registry.js +72 -0
  70. package/lib/internal/registry.js.map +1 -0
  71. package/lib/internal/workload.d.ts +127 -0
  72. package/lib/internal/workload.d.ts.map +1 -0
  73. package/lib/internal/workload.js +411 -0
  74. package/lib/internal/workload.js.map +1 -0
  75. package/package.json +55 -3
  76. package/src/BuiltinAdapters.ts +202 -0
  77. package/src/Client.ts +496 -0
  78. package/src/ClusterAdapter.ts +373 -0
  79. package/src/Connection.ts +234 -0
  80. package/src/Deployment.ts +872 -0
  81. package/src/HelmChart.ts +388 -0
  82. package/src/Job.ts +709 -0
  83. package/src/LocalCluster.ts +631 -0
  84. package/src/Manifest.ts +301 -0
  85. package/src/Objects.ts +213 -0
  86. package/src/Providers.ts +52 -0
  87. package/src/globals.d.ts +2 -0
  88. package/src/index.ts +9 -0
  89. package/src/internal/declared.ts +471 -0
  90. package/src/internal/helm.ts +245 -0
  91. package/src/internal/kind.ts +43 -0
  92. package/src/internal/kubeconfig.ts +364 -0
  93. package/src/internal/registry.ts +108 -0
  94. package/src/internal/workload.ts +504 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy.run/kubernetes",
3
- "version": "0.0.0",
3
+ "version": "2.0.0-beta.85",
4
4
  "description": "Kubernetes deployments, jobs, Helm charts, manifests and local clusters for Alchemy.",
5
5
  "keywords": [
6
6
  "alchemy",
@@ -9,12 +9,64 @@
9
9
  "infrastructure-as-code",
10
10
  "kubernetes"
11
11
  ],
12
+ "homepage": "https://alchemy.run",
13
+ "bugs": {
14
+ "url": "https://github.com/alchemy-run/alchemy/issues"
15
+ },
12
16
  "license": "Apache-2.0",
13
17
  "author": "Sam Goodwin <sam@alchemy.run>",
14
- "homepage": "https://alchemy.run",
15
18
  "repository": {
16
19
  "type": "git",
17
20
  "url": "git+https://github.com/alchemy-run/alchemy.git",
18
21
  "directory": "packages/kubernetes"
22
+ },
23
+ "files": [
24
+ "lib",
25
+ "src"
26
+ ],
27
+ "type": "module",
28
+ "sideEffects": false,
29
+ "exports": {
30
+ ".": {
31
+ "types": "./lib/index.d.ts",
32
+ "bun": "./src/index.ts",
33
+ "default": "./lib/index.js"
34
+ },
35
+ "./internal/*": null,
36
+ "./*": {
37
+ "types": "./lib/*.d.ts",
38
+ "bun": "./src/*.ts",
39
+ "default": "./lib/*.js"
40
+ },
41
+ "./package.json": "./package.json"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "dependencies": {
47
+ "@alchemy.run/docker": "2.0.0-beta.85",
48
+ "yaml": "^2.9.1"
49
+ },
50
+ "devDependencies": {
51
+ "@effect/platform-bun": "^4.1.0",
52
+ "@types/bun": "1.4.3",
53
+ "@types/node": "26.6.5",
54
+ "alchemy": "2.0.0-beta.85",
55
+ "effect": "^4.1.0",
56
+ "typescript": "^7.0.2"
57
+ },
58
+ "peerDependencies": {
59
+ "@effect/platform-bun": "^4.1.0",
60
+ "alchemy": "2.0.0-beta.85",
61
+ "effect": "^4.1.0"
62
+ },
63
+ "peerDependenciesMeta": {
64
+ "@effect/platform-bun": {
65
+ "optional": true
66
+ }
67
+ },
68
+ "scripts": {
69
+ "build": "pnpm -r --filter \"{.}...\" run build:package",
70
+ "build:package": "node scripts/build.ts"
19
71
  }
20
- }
72
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * The built-in {@link ClusterAdapter} implementations shipped by
3
+ * `Kubernetes.providers()`: `kubeconfig`, `token`, `client-cert`, and
4
+ * `exec`. They cover any cluster `kubectl` can reach; managed-cloud
5
+ * adapters (EKS's `aws-eks`) are contributed by their provider layers.
6
+ *
7
+ * These adapters are auth-only — no workload identity and no managed image
8
+ * registry. Workloads on such clusters bind through environment variables
9
+ * and run pre-built `image` references (or images pushed by the user's own
10
+ * pipeline).
11
+ */
12
+
13
+ import * as Data from "effect/Data";
14
+ import * as Effect from "effect/Effect";
15
+ import * as FileSystem from "effect/FileSystem";
16
+ import * as Layer from "effect/Layer";
17
+ import * as Path from "effect/Path";
18
+ import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
19
+ import {
20
+ ClusterAdapter,
21
+ type ClusterAdapterService,
22
+ type ClusterTransport,
23
+ } from "./ClusterAdapter.ts";
24
+ import type { Connection } from "./Connection.ts";
25
+ import {
26
+ mintUserCredentials,
27
+ resolveKubeContext,
28
+ runExecCredential,
29
+ type MintedCredentials,
30
+ } from "./internal/kubeconfig.ts";
31
+
32
+ export class BuiltinAdaptersInvalidProps extends Data.TaggedError("BuiltinAdaptersInvalidProps")<{
33
+ readonly message: string;
34
+ readonly cause?: unknown;
35
+ }> {}
36
+
37
+ const toAuthHeaders = (credentials: MintedCredentials): Record<string, string> =>
38
+ credentials.token ? { Authorization: `Bearer ${credentials.token}` } : {};
39
+
40
+ const requireEndpoint = (connection: Connection) =>
41
+ connection.endpoint !== undefined
42
+ ? Effect.succeed(connection.endpoint)
43
+ : Effect.fail(
44
+ new BuiltinAdaptersInvalidProps({
45
+ message:
46
+ `A '${connection.auth.kind}' Kubernetes connection requires an ` +
47
+ "explicit `endpoint` (only kubeconfig-backed and managed-cloud " +
48
+ "connections can discover it)",
49
+ }),
50
+ );
51
+
52
+ /**
53
+ * `kubeconfig` — resolve the cluster and credentials from a kubeconfig
54
+ * file, honoring static tokens, client certificates, and `exec` credential
55
+ * plugins.
56
+ */
57
+ export const KubeConfigAdapter: Layer.Layer<
58
+ ClusterAdapterService,
59
+ never,
60
+ FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner
61
+ > = Layer.effect(
62
+ ClusterAdapter("kubeconfig"),
63
+ Effect.gen(function* () {
64
+ // Capture the platform services at layer build so per-request minting
65
+ // (exec plugins can re-run on token expiry) needs no ambient context.
66
+ const context = yield* Effect.context<
67
+ FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner
68
+ >();
69
+
70
+ return {
71
+ kind: "Kubernetes.ClusterAdapter" as const,
72
+ connect: Effect.fn(function* (connection: Connection) {
73
+ if (connection.auth.kind !== "kubeconfig") {
74
+ return yield* Effect.die(
75
+ new Error(`kubeconfig adapter received auth kind '${connection.auth.kind}'`),
76
+ );
77
+ }
78
+ const resolved = yield* resolveKubeContext({
79
+ path: connection.auth.path,
80
+ context: connection.auth.context,
81
+ }).pipe(Effect.provideContext(context));
82
+
83
+ // Mint once at connect: static tokens and client certificates are
84
+ // stable; exec plugins re-mint per request below (their tokens
85
+ // expire) but any plugin-issued client certificate is captured
86
+ // here.
87
+ const initial = yield* mintUserCredentials(resolved.user).pipe(
88
+ Effect.provideContext(context),
89
+ );
90
+
91
+ const isExec = resolved.user.exec?.command !== undefined;
92
+ const headers: ClusterTransport["headers"] = isExec
93
+ ? mintUserCredentials(resolved.user).pipe(
94
+ Effect.map(toAuthHeaders),
95
+ Effect.provideContext(context),
96
+ )
97
+ : Effect.succeed(toAuthHeaders(initial));
98
+
99
+ return {
100
+ endpoint: connection.endpoint ?? resolved.endpoint,
101
+ certificateAuthorityData:
102
+ connection.certificateAuthorityData ?? resolved.certificateAuthorityData,
103
+ insecureSkipTlsVerify: connection.insecureSkipTlsVerify ?? resolved.insecureSkipTlsVerify,
104
+ headers,
105
+ clientCert: initial.clientCert,
106
+ } satisfies ClusterTransport;
107
+ }),
108
+ };
109
+ }),
110
+ );
111
+
112
+ /** `token` — a static bearer token against an explicit endpoint. */
113
+ export const TokenAdapter: Layer.Layer<ClusterAdapterService> = Layer.succeed(
114
+ ClusterAdapter("token"),
115
+ {
116
+ kind: "Kubernetes.ClusterAdapter" as const,
117
+ connect: Effect.fn(function* (connection: Connection) {
118
+ if (connection.auth.kind !== "token") {
119
+ return yield* Effect.die(
120
+ new Error(`token adapter received auth kind '${connection.auth.kind}'`),
121
+ );
122
+ }
123
+ const token = connection.auth.token;
124
+ return {
125
+ endpoint: yield* requireEndpoint(connection),
126
+ certificateAuthorityData: connection.certificateAuthorityData,
127
+ insecureSkipTlsVerify: connection.insecureSkipTlsVerify,
128
+ headers: Effect.succeed({ Authorization: `Bearer ${token}` }),
129
+ } satisfies ClusterTransport;
130
+ }),
131
+ },
132
+ );
133
+
134
+ /** `client-cert` — mutual TLS against an explicit endpoint. */
135
+ export const ClientCertAdapter: Layer.Layer<ClusterAdapterService> = Layer.succeed(
136
+ ClusterAdapter("client-cert"),
137
+ {
138
+ kind: "Kubernetes.ClusterAdapter" as const,
139
+ connect: Effect.fn(function* (connection: Connection) {
140
+ if (connection.auth.kind !== "client-cert") {
141
+ return yield* Effect.die(
142
+ new Error(`client-cert adapter received auth kind '${connection.auth.kind}'`),
143
+ );
144
+ }
145
+ return {
146
+ endpoint: yield* requireEndpoint(connection),
147
+ certificateAuthorityData: connection.certificateAuthorityData,
148
+ insecureSkipTlsVerify: connection.insecureSkipTlsVerify,
149
+ headers: Effect.succeed({}),
150
+ clientCert: {
151
+ certificate: connection.auth.certificate,
152
+ key: connection.auth.key,
153
+ },
154
+ } satisfies ClusterTransport;
155
+ }),
156
+ },
157
+ );
158
+
159
+ /**
160
+ * `exec` — mint credentials with a kubeconfig-style exec credential plugin
161
+ * against an explicit endpoint.
162
+ */
163
+ export const ExecAdapter: Layer.Layer<
164
+ ClusterAdapterService,
165
+ never,
166
+ ChildProcessSpawner.ChildProcessSpawner
167
+ > = Layer.effect(
168
+ ClusterAdapter("exec"),
169
+ Effect.gen(function* () {
170
+ const context = yield* Effect.context<ChildProcessSpawner.ChildProcessSpawner>();
171
+
172
+ return {
173
+ kind: "Kubernetes.ClusterAdapter" as const,
174
+ connect: Effect.fn(function* (connection: Connection) {
175
+ if (connection.auth.kind !== "exec") {
176
+ return yield* Effect.die(
177
+ new Error(`exec adapter received auth kind '${connection.auth.kind}'`),
178
+ );
179
+ }
180
+ const exec = connection.auth;
181
+ const initial = yield* runExecCredential(exec).pipe(Effect.provideContext(context));
182
+ return {
183
+ endpoint: yield* requireEndpoint(connection),
184
+ certificateAuthorityData: connection.certificateAuthorityData,
185
+ insecureSkipTlsVerify: connection.insecureSkipTlsVerify,
186
+ headers: runExecCredential(exec).pipe(
187
+ Effect.map(toAuthHeaders),
188
+ Effect.provideContext(context),
189
+ ),
190
+ clientCert: initial.clientCert,
191
+ } satisfies ClusterTransport;
192
+ }),
193
+ };
194
+ }),
195
+ );
196
+
197
+ /** All built-in adapters, merged for `Kubernetes.providers()`. */
198
+ export const builtinAdapters = (): Layer.Layer<
199
+ ClusterAdapterService,
200
+ never,
201
+ FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner
202
+ > => Layer.mergeAll(KubeConfigAdapter, TokenAdapter, ClientCertAdapter, ExecAdapter);