@highstate/k8s 0.9.18 → 0.9.20

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 (93) hide show
  1. package/dist/chunk-2EEHJZPD.js +13 -0
  2. package/dist/chunk-2EEHJZPD.js.map +1 -0
  3. package/dist/{chunk-OFFSHGC6.js → chunk-4JGXGN2L.js} +66 -48
  4. package/dist/chunk-4JGXGN2L.js.map +1 -0
  5. package/dist/chunk-A3XGSDIW.js +306 -0
  6. package/dist/chunk-A3XGSDIW.js.map +1 -0
  7. package/dist/chunk-IMTXUK2U.js +244 -0
  8. package/dist/chunk-IMTXUK2U.js.map +1 -0
  9. package/dist/chunk-JYNXQ3I3.js +287 -0
  10. package/dist/chunk-JYNXQ3I3.js.map +1 -0
  11. package/dist/{chunk-5C2BJGES.js → chunk-KDD6XUWM.js} +30 -23
  12. package/dist/chunk-KDD6XUWM.js.map +1 -0
  13. package/dist/chunk-NOFJC3EM.js +236 -0
  14. package/dist/chunk-NOFJC3EM.js.map +1 -0
  15. package/dist/chunk-NXSYCA3V.js +337 -0
  16. package/dist/chunk-NXSYCA3V.js.map +1 -0
  17. package/dist/chunk-SBC3TUIN.js +1513 -0
  18. package/dist/chunk-SBC3TUIN.js.map +1 -0
  19. package/dist/chunk-SI7X6N46.js +338 -0
  20. package/dist/chunk-SI7X6N46.js.map +1 -0
  21. package/dist/chunk-WGMJCZSK.js +360 -0
  22. package/dist/chunk-WGMJCZSK.js.map +1 -0
  23. package/dist/deployment-752P6JIT.js +8 -0
  24. package/dist/{deployment-XK3CDJOE.js.map → deployment-752P6JIT.js.map} +1 -1
  25. package/dist/highstate.manifest.json +8 -7
  26. package/dist/impl/gateway-route.js +123 -0
  27. package/dist/impl/gateway-route.js.map +1 -0
  28. package/dist/impl/tls-certificate.js +32 -0
  29. package/dist/impl/tls-certificate.js.map +1 -0
  30. package/dist/index.js +736 -208
  31. package/dist/index.js.map +1 -1
  32. package/dist/stateful-set-N64YVKR7.js +8 -0
  33. package/dist/{stateful-set-7CAQWTV2.js.map → stateful-set-N64YVKR7.js.map} +1 -1
  34. package/dist/units/cert-manager/index.js +11 -10
  35. package/dist/units/cert-manager/index.js.map +1 -1
  36. package/dist/units/dns01-issuer/index.js +27 -23
  37. package/dist/units/dns01-issuer/index.js.map +1 -1
  38. package/dist/units/existing-cluster/index.js +11 -8
  39. package/dist/units/existing-cluster/index.js.map +1 -1
  40. package/dist/units/gateway-api/index.js +2 -2
  41. package/dist/units/gateway-api/index.js.map +1 -1
  42. package/package.json +39 -13
  43. package/src/cluster.ts +30 -22
  44. package/src/config-map.ts +195 -57
  45. package/src/container.ts +5 -5
  46. package/src/cron-job.ts +403 -31
  47. package/src/deployment.ts +260 -120
  48. package/src/dns01-solver.ts +10 -0
  49. package/src/gateway/backend.ts +2 -2
  50. package/src/gateway/gateway.ts +383 -0
  51. package/src/gateway/http-route.ts +17 -24
  52. package/src/gateway/index.ts +1 -0
  53. package/src/helm.ts +83 -53
  54. package/src/impl/gateway-route.ts +155 -0
  55. package/src/impl/tls-certificate.ts +33 -0
  56. package/src/index.ts +22 -67
  57. package/src/job.ts +393 -28
  58. package/src/namespace.ts +236 -99
  59. package/src/network-policy.ts +216 -165
  60. package/src/network.ts +2 -2
  61. package/src/pvc.ts +266 -65
  62. package/src/rbac.ts +218 -0
  63. package/src/scripting/bundle.ts +9 -20
  64. package/src/scripting/container.ts +1 -1
  65. package/src/scripting/environment.ts +5 -5
  66. package/src/secret.ts +200 -62
  67. package/src/service.ts +288 -158
  68. package/src/shared.ts +94 -67
  69. package/src/stateful-set.ts +270 -117
  70. package/src/tls.ts +344 -0
  71. package/src/units/cert-manager/index.ts +2 -3
  72. package/src/units/dns01-issuer/index.ts +30 -14
  73. package/src/units/existing-cluster/index.ts +10 -7
  74. package/src/units/gateway-api/index.ts +2 -2
  75. package/src/worker.ts +26 -0
  76. package/src/workload.ts +275 -171
  77. package/dist/chunk-5C2BJGES.js.map +0 -1
  78. package/dist/chunk-5TLC5BXR.js +0 -256
  79. package/dist/chunk-5TLC5BXR.js.map +0 -1
  80. package/dist/chunk-BBIY3KUN.js +0 -1557
  81. package/dist/chunk-BBIY3KUN.js.map +0 -1
  82. package/dist/chunk-OFFSHGC6.js.map +0 -1
  83. package/dist/chunk-TZHOUJRC.js +0 -202
  84. package/dist/chunk-TZHOUJRC.js.map +0 -1
  85. package/dist/chunk-YWRJ4EZM.js +0 -192
  86. package/dist/chunk-YWRJ4EZM.js.map +0 -1
  87. package/dist/deployment-XK3CDJOE.js +0 -6
  88. package/dist/stateful-set-7CAQWTV2.js +0 -6
  89. package/dist/units/access-point/index.js +0 -21
  90. package/dist/units/access-point/index.js.map +0 -1
  91. package/src/access-point.ts +0 -191
  92. package/src/units/access-point/index.ts +0 -19
  93. package/src/units/dns01-issuer/solver.ts +0 -23
package/src/namespace.ts CHANGED
@@ -1,34 +1,46 @@
1
1
  import type { k8s } from "@highstate/library"
2
+ import { getOrCreate } from "@highstate/contract"
3
+ import { toPromise } from "@highstate/pulumi"
2
4
  import { core, type types } from "@pulumi/kubernetes"
3
5
  import {
4
6
  ComponentResource,
5
- output,
6
- Output,
7
7
  type ComponentResourceOptions,
8
8
  type Input,
9
9
  type Inputs,
10
+ type Output,
11
+ output,
10
12
  type Unwrap,
11
13
  } from "@pulumi/pulumi"
12
- import { getProvider, mapMetadata, type CommonArgs } from "./shared"
14
+ import { getProvider, mapMetadata, type ScopedResourceArgs, validateCluster } from "./shared"
15
+
16
+ export type NamespaceArgs = Omit<ScopedResourceArgs, "namespace"> & {
17
+ /**
18
+ * The cluster where the namespace is located.
19
+ */
20
+ cluster: Input<k8s.Cluster>
13
21
 
14
- export type NamespaceArgs = Omit<CommonArgs, "namespace"> & {
15
22
  /**
16
23
  * Whether to apply "pod-security.kubernetes.io/enforce=privileged" label to the namespace.
17
24
  */
18
25
  privileged?: boolean
19
26
  }
20
27
 
21
- export type CreateOrPatchNamespaceArgs = NamespaceArgs & {
28
+ export type CreateOrGetNamespaceArgs = NamespaceArgs & {
22
29
  /**
23
30
  * The resource to use to determine the name of the namespace.
24
31
  *
25
32
  * If not provided, the namespace will be created, otherwise it will be retrieved/patched.
26
33
  */
27
- resource: Input<k8s.Resource> | undefined
34
+ resource?: Input<k8s.ScopedResource>
35
+
36
+ /**
37
+ * The namespace entity to patch/retrieve.
38
+ */
39
+ existing?: Input<k8s.Namespace> | undefined
28
40
  }
29
41
 
30
42
  export abstract class Namespace extends ComponentResource {
31
- protected constructor(
43
+ constructor(
32
44
  type: string,
33
45
  name: string,
34
46
  args: Inputs,
@@ -57,6 +69,18 @@ export abstract class Namespace extends ComponentResource {
57
69
  super(type, name, args, opts)
58
70
  }
59
71
 
72
+ /**
73
+ * The Highstate namespace entity.
74
+ */
75
+ get entity(): Output<k8s.Namespace> {
76
+ return output({
77
+ type: "namespace",
78
+ clusterId: this.cluster.id,
79
+ clusterName: this.cluster.name,
80
+ metadata: this.metadata,
81
+ })
82
+ }
83
+
60
84
  /**
61
85
  * Creates a new namespace.
62
86
  */
@@ -65,71 +89,78 @@ export abstract class Namespace extends ComponentResource {
65
89
  }
66
90
 
67
91
  /**
68
- * Creates a new namespace or patches an existing one.
69
- *
70
- * Will throw an error if the namespace does not exist when `args.resource` is provided.
92
+ * Wraps an existing Kubernetes namespace.
71
93
  */
72
- static createOrPatch(
94
+ static wrap(
73
95
  name: string,
74
- args: CreateOrPatchNamespaceArgs,
96
+ args: WrappedNamespaceArgs,
75
97
  opts?: ComponentResourceOptions,
76
98
  ): Namespace {
77
- if (!args.resource) {
78
- return new CreatedNamespace(name, args, opts)
99
+ return new WrappedNamespace(name, args, opts)
100
+ }
101
+
102
+ /**
103
+ * Creates a new namespace or gets an existing one.
104
+ *
105
+ * @param name The name of the resource. May not be the same as the namespace name. Will not be used when existing namespace is retrieved.
106
+ * @param args The arguments to create or get the namespace with.
107
+ * @param opts Optional resource options.
108
+ */
109
+ static async createOrGet(
110
+ name: string,
111
+ args: CreateOrGetNamespaceArgs,
112
+ opts?: ComponentResourceOptions,
113
+ ): Promise<Namespace> {
114
+ if (args.resource) {
115
+ return await Namespace.forResourceAsync(args.resource, args.cluster)
79
116
  }
80
117
 
81
- return new NamespacePatch(
82
- name,
83
- {
84
- ...args,
85
- name: output(args).apply(args => {
86
- if (args.resource!.clusterId !== args.cluster.id) {
87
- throw new Error(
88
- `Cluster mismatch when patching namespace "${name}": "${args.resource!.clusterId}" != "${args.cluster.id}"`,
89
- )
90
- }
91
-
92
- return args.resource!.metadata.namespace
93
- }),
94
- },
95
- opts,
96
- )
118
+ if (args.existing) {
119
+ return await Namespace.forAsync(args.existing, args.cluster)
120
+ }
121
+
122
+ return new CreatedNamespace(name, args, opts)
97
123
  }
98
124
 
99
125
  /**
100
- * Creates a new namespace or gets an existing one.
126
+ * Creates a new namespace or patches an existing one.
101
127
  *
102
- * Will throw an error if the namespace does not exist when `args.resource` is provided.
128
+ * @param name The name of the resource. May not be the same as the namespace name.
129
+ * @param args The arguments to create or patch the namespace with.
130
+ * @param opts Optional resource options.
103
131
  */
104
- static createOrGet(
132
+ static createOrPatch(
105
133
  name: string,
106
- args: CreateOrPatchNamespaceArgs,
134
+ args: CreateOrGetNamespaceArgs,
107
135
  opts?: ComponentResourceOptions,
108
136
  ): Namespace {
109
- if (!args.resource) {
110
- return new CreatedNamespace(name, args, opts)
137
+ if (args.resource) {
138
+ return new NamespacePatch(name, {
139
+ ...args,
140
+ name: output(args.resource).metadata.namespace,
141
+ cluster: validateCluster(args.resource, args.cluster),
142
+ })
111
143
  }
112
144
 
113
- return new ExternalNamespace(
114
- name,
115
- output(args).apply(args => {
116
- if (args.resource!.clusterId !== args.cluster.id) {
117
- throw new Error(
118
- `Cluster mismatch when receiving namespace "${name}": "${args.resource!.clusterId}" != "${args.cluster.id}"`,
119
- )
120
- }
121
-
122
- return args.resource!.metadata.namespace
123
- }),
124
- args.cluster,
125
- opts,
126
- )
145
+ if (args.existing) {
146
+ return new NamespacePatch(name, {
147
+ ...args,
148
+ name: output(args.existing).metadata.name,
149
+ cluster: validateCluster(args.existing, args.cluster),
150
+ })
151
+ }
152
+
153
+ return new CreatedNamespace(name, args, opts)
127
154
  }
128
155
 
129
156
  /**
130
157
  * Patches an existing namespace.
131
158
  *
132
159
  * Will throw an error if the namespace does not exist.
160
+ *
161
+ * @param name The name of the resource. May not be the same as the namespace name.
162
+ * @param args The arguments to patch the namespace with.
163
+ * @param opts Optional resource options.
133
164
  */
134
165
  static patch(name: string, args: NamespaceArgs, opts?: ComponentResourceOptions): Namespace {
135
166
  return new NamespacePatch(name, args, opts)
@@ -139,43 +170,125 @@ export abstract class Namespace extends ComponentResource {
139
170
  * Gets an existing namespace.
140
171
  *
141
172
  * Will throw an error if the namespace does not exist.
173
+ *
174
+ * @param name The name of the resource. May not be the same as the namespace name.
175
+ * @param args The arguments to get the namespace with.
176
+ * @param opts Optional resource options.
142
177
  */
143
178
  static get(
144
179
  name: string,
145
- id: Input<string>,
146
- cluster: Input<k8s.Cluster>,
180
+ args: ExternalNamespaceArgs,
147
181
  opts?: ComponentResourceOptions,
148
182
  ): Namespace {
149
- return new ExternalNamespace(name, id, cluster, opts)
183
+ return new ExternalNamespace(name, args, opts)
150
184
  }
151
- }
152
185
 
153
- function mapNamespaceMetadata(
154
- args: Unwrap<NamespaceArgs>,
155
- name: string,
156
- ): types.input.meta.v1.ObjectMeta {
157
- const labels: Record<string, string> = args.metadata?.labels ?? {}
186
+ private static readonly namespaceCache = new Map<string, Namespace>()
187
+
188
+ /**
189
+ * Gets an existing namespace for a given entity.
190
+ * Prefer this method over `get` when possible.
191
+ *
192
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{clusterId}`.
193
+ *
194
+ * This method it idempotent and will return the same instance for the same entity.
195
+ *
196
+ * @param entity The entity to get the namespace for.
197
+ * @param cluster The cluster where the namespace is located.
198
+ */
199
+ static for(entity: k8s.Namespace, cluster: Input<k8s.Cluster>): Namespace {
200
+ return getOrCreate(
201
+ Namespace.namespaceCache,
202
+ `${entity.clusterName}.${entity.metadata.name}.${entity.clusterId}`,
203
+ name => {
204
+ return Namespace.get(name, {
205
+ name: entity.metadata.name,
206
+ cluster: validateCluster(entity, cluster),
207
+ })
208
+ },
209
+ )
210
+ }
158
211
 
159
- if (args.privileged) {
160
- labels["pod-security.kubernetes.io/enforce"] = "privileged"
212
+ /**
213
+ * Gets an existing namespace for a given entity.
214
+ * Prefer this method over `get` when possible.
215
+ *
216
+ * @param entity The entity to get the namespace for.
217
+ * @param cluster The cluster where the namespace is located.
218
+ */
219
+ static async forAsync(
220
+ entity: Input<k8s.Namespace>,
221
+ cluster: Input<k8s.Cluster>,
222
+ ): Promise<Namespace> {
223
+ const resolvedEntity = await toPromise(entity)
224
+
225
+ return Namespace.for(resolvedEntity, cluster)
161
226
  }
162
227
 
163
- return { ...mapMetadata(args, name), labels }
228
+ /**
229
+ * Gets an existing namespace where the provided resource is located.
230
+ * Prefer this method over `get` when possible.
231
+ *
232
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{clusterId}`.
233
+ *
234
+ * This method it idempotent and will return the same instance for the same resource.
235
+ *
236
+ * @param resource The resource to get the namespace for.
237
+ * @param cluster The cluster where the namespace is located.
238
+ */
239
+ static forResource(resource: k8s.ScopedResource, cluster: Input<k8s.Cluster>): Namespace {
240
+ return getOrCreate(
241
+ Namespace.namespaceCache,
242
+ `${resource.clusterName}.${resource.metadata.namespace}.${resource.clusterId}`,
243
+ name => {
244
+ return Namespace.get(name, {
245
+ name: resource.metadata.namespace,
246
+ cluster: validateCluster(resource, cluster),
247
+ })
248
+ },
249
+ )
250
+ }
251
+
252
+ /**
253
+ * Gets an existing namespace for a given entity.
254
+ * Prefer this method over `get` when possible.
255
+ *
256
+ * @param resource The resource to get the namespace for.
257
+ * @param cluster The cluster where the namespace is located.
258
+ */
259
+ static async forResourceAsync(
260
+ resource: Input<k8s.ScopedResource>,
261
+ cluster: Input<k8s.Cluster>,
262
+ ): Promise<Namespace> {
263
+ const resolvedResource = await toPromise(resource)
264
+
265
+ return Namespace.forResource(resolvedResource, cluster)
266
+ }
267
+ }
268
+
269
+ function mapNamespaceMetadata(
270
+ args: NamespaceArgs,
271
+ fallbackName: string,
272
+ ): Output<Unwrap<types.input.meta.v1.ObjectMeta>> {
273
+ return mapMetadata(args, fallbackName).apply(metadata => {
274
+ if (args.privileged) {
275
+ metadata.labels = {
276
+ ...metadata.labels,
277
+ "pod-security.kubernetes.io/enforce": "privileged",
278
+ }
279
+ }
280
+
281
+ return metadata
282
+ })
164
283
  }
165
284
 
166
285
  class CreatedNamespace extends Namespace {
167
286
  constructor(name: string, args: NamespaceArgs, opts?: ComponentResourceOptions) {
168
- const namespace = output(args).apply(async args => {
287
+ const namespace = output(args.cluster).apply(cluster => {
169
288
  return new core.v1.Namespace(
170
289
  name,
171
- {
172
- metadata: mapNamespaceMetadata(args, name),
173
- },
174
- {
175
- ...opts,
176
- parent: this,
177
- provider: await getProvider(args.cluster),
178
- },
290
+ { metadata: mapNamespaceMetadata(args, name) },
291
+ { ...opts, parent: this, provider: getProvider(cluster) },
179
292
  )
180
293
  })
181
294
 
@@ -194,17 +307,11 @@ class CreatedNamespace extends Namespace {
194
307
 
195
308
  class NamespacePatch extends Namespace {
196
309
  constructor(name: string, args: NamespaceArgs, opts?: ComponentResourceOptions) {
197
- const namespace = output(args).apply(async args => {
310
+ const namespace = output(args.cluster).apply(cluster => {
198
311
  return new core.v1.NamespacePatch(
199
312
  name,
200
- {
201
- metadata: mapNamespaceMetadata(args, name),
202
- },
203
- {
204
- ...opts,
205
- parent: this,
206
- provider: await getProvider(args.cluster),
207
- },
313
+ { metadata: mapNamespaceMetadata(args, name) },
314
+ { ...opts, parent: this, provider: getProvider(cluster) },
208
315
  )
209
316
  })
210
317
 
@@ -221,35 +328,65 @@ class NamespacePatch extends Namespace {
221
328
  }
222
329
  }
223
330
 
331
+ export type WrappedNamespaceArgs = {
332
+ /**
333
+ * The underlying Kubernetes namespace to wrap.
334
+ */
335
+ namespace: Input<core.v1.Namespace>
336
+
337
+ /**
338
+ * The cluster where the namespace is located.
339
+ */
340
+ cluster: Input<k8s.Cluster>
341
+ }
342
+
343
+ export type ExternalNamespaceArgs = {
344
+ /**
345
+ * The real name of the namespace in the cluster.
346
+ */
347
+ name: Input<string>
348
+
349
+ /**
350
+ * The cluster where the namespace is located.
351
+ */
352
+ cluster: Input<k8s.Cluster>
353
+ }
354
+
224
355
  class ExternalNamespace extends Namespace {
225
- constructor(
226
- name: string,
227
- id: Input<string>,
228
- cluster: Input<k8s.Cluster>,
229
- opts?: ComponentResourceOptions,
230
- ) {
231
- const namespace = output(id).apply(async realName => {
232
- return core.v1.Namespace.get(
233
- //
234
- name,
235
- realName,
236
- {
237
- ...opts,
238
- parent: this,
239
- provider: await getProvider(cluster),
240
- },
241
- )
356
+ constructor(name: string, args: ExternalNamespaceArgs, opts?: ComponentResourceOptions) {
357
+ const namespace = output(args.cluster).apply(cluster => {
358
+ return core.v1.Namespace.get(name, args.name, {
359
+ ...opts,
360
+ parent: this,
361
+ provider: getProvider(cluster),
362
+ })
242
363
  })
243
364
 
244
365
  super(
245
366
  "highstate:k8s:ExternalNamespace",
246
367
  name,
247
- { id, cluster },
368
+ args,
248
369
  opts,
249
- output(cluster),
370
+ output(args.cluster),
250
371
  namespace.metadata,
251
372
  namespace.spec,
252
373
  namespace.status,
253
374
  )
254
375
  }
255
376
  }
377
+
378
+ class WrappedNamespace extends Namespace {
379
+ constructor(name: string, args: WrappedNamespaceArgs, opts?: ComponentResourceOptions) {
380
+ super(
381
+ "highstate:k8s:WrappedNamespace",
382
+ name,
383
+ args,
384
+ opts,
385
+
386
+ output(args.cluster),
387
+ output(args.namespace).metadata,
388
+ output(args.namespace).spec,
389
+ output(args.namespace).status,
390
+ )
391
+ }
392
+ }