@highstate/k8s 0.9.16 → 0.9.19

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 (95) 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/cluster-dns/index.js.map +1 -1
  37. package/dist/units/cluster-patch/index.js.map +1 -1
  38. package/dist/units/dns01-issuer/index.js +27 -23
  39. package/dist/units/dns01-issuer/index.js.map +1 -1
  40. package/dist/units/existing-cluster/index.js +11 -8
  41. package/dist/units/existing-cluster/index.js.map +1 -1
  42. package/dist/units/gateway-api/index.js +2 -2
  43. package/dist/units/gateway-api/index.js.map +1 -1
  44. package/package.json +40 -14
  45. package/src/cluster.ts +30 -22
  46. package/src/config-map.ts +195 -57
  47. package/src/container.ts +5 -5
  48. package/src/cron-job.ts +403 -31
  49. package/src/deployment.ts +260 -120
  50. package/src/dns01-solver.ts +10 -0
  51. package/src/gateway/backend.ts +2 -2
  52. package/src/gateway/gateway.ts +383 -0
  53. package/src/gateway/http-route.ts +17 -24
  54. package/src/gateway/index.ts +1 -0
  55. package/src/helm.ts +83 -53
  56. package/src/impl/gateway-route.ts +155 -0
  57. package/src/impl/tls-certificate.ts +33 -0
  58. package/src/index.ts +22 -67
  59. package/src/job.ts +393 -28
  60. package/src/namespace.ts +236 -99
  61. package/src/network-policy.ts +216 -165
  62. package/src/network.ts +2 -2
  63. package/src/pvc.ts +266 -65
  64. package/src/rbac.ts +218 -0
  65. package/src/scripting/bundle.ts +9 -20
  66. package/src/scripting/container.ts +1 -1
  67. package/src/scripting/environment.ts +5 -5
  68. package/src/secret.ts +200 -62
  69. package/src/service.ts +288 -158
  70. package/src/shared.ts +94 -67
  71. package/src/stateful-set.ts +270 -117
  72. package/src/tls.ts +344 -0
  73. package/src/units/cert-manager/index.ts +2 -3
  74. package/src/units/dns01-issuer/index.ts +30 -14
  75. package/src/units/existing-cluster/index.ts +10 -7
  76. package/src/units/gateway-api/index.ts +2 -2
  77. package/src/worker.ts +26 -0
  78. package/src/workload.ts +275 -171
  79. package/dist/chunk-5C2BJGES.js.map +0 -1
  80. package/dist/chunk-5TLC5BXR.js +0 -256
  81. package/dist/chunk-5TLC5BXR.js.map +0 -1
  82. package/dist/chunk-BBIY3KUN.js +0 -1557
  83. package/dist/chunk-BBIY3KUN.js.map +0 -1
  84. package/dist/chunk-OFFSHGC6.js.map +0 -1
  85. package/dist/chunk-TZHOUJRC.js +0 -202
  86. package/dist/chunk-TZHOUJRC.js.map +0 -1
  87. package/dist/chunk-YWRJ4EZM.js +0 -192
  88. package/dist/chunk-YWRJ4EZM.js.map +0 -1
  89. package/dist/deployment-XK3CDJOE.js +0 -6
  90. package/dist/stateful-set-7CAQWTV2.js +0 -6
  91. package/dist/units/access-point/index.js +0 -21
  92. package/dist/units/access-point/index.js.map +0 -1
  93. package/src/access-point.ts +0 -191
  94. package/src/units/access-point/index.ts +0 -19
  95. package/src/units/dns01-issuer/solver.ts +0 -23
package/dist/index.js CHANGED
@@ -1,132 +1,738 @@
1
- export { Chart, RenderedChart, getChartService, getChartServiceOutput, resolveHelmChart } from './chunk-OFFSHGC6.js';
2
- export { StatefulSet } from './chunk-TZHOUJRC.js';
3
- export { Deployment } from './chunk-YWRJ4EZM.js';
4
- import { NetworkPolicy, isFromCluster, ConfigMap, getWorkloadComponents } from './chunk-BBIY3KUN.js';
5
- export { ConfigMap, ExposableWorkload, HttpRoute, NetworkPolicy, PersistentVolumeClaim, Secret, Service, Workload, getBestEndpoint, getServiceMetadata, hasServiceMetadata, isFromCluster, mapContainerPortToServicePort, mapServiceToLabelSelector, requireBestEndpoint, withServiceMetadata } from './chunk-BBIY3KUN.js';
6
- export { createK8sTerminal, detectExternalIps } from './chunk-5C2BJGES.js';
7
- import { commonExtraArgs, getProvider, mapNamespaceLikeToNamespaceName, mapMetadata } from './chunk-5TLC5BXR.js';
8
- export { Namespace, getProvider, mapMetadata, mapNamespaceLikeToNamespaceName, mapNamespaceNameToSelector, mapSelectorLikeToSelector } from './chunk-5TLC5BXR.js';
1
+ export { Chart, RenderedChart, getChartService, getChartServiceOutput, resolveHelmChart } from './chunk-4JGXGN2L.js';
2
+ export { Deployment } from './chunk-JYNXQ3I3.js';
3
+ export { StatefulSet } from './chunk-A3XGSDIW.js';
4
+ import { Workload, getWorkloadComponents, ConfigMap } from './chunk-SBC3TUIN.js';
5
+ export { ConfigMap, ExposableWorkload, NativeNetworkPolicy, NetworkPolicy, PersistentVolumeClaim, Workload, exposableWorkloadExtraArgs, getAutoVolumeName, getBestEndpoint, getExposableWorkloadComponents, getWorkloadComponents, getWorkloadVolumeResourceUuid, mapContainerEnvironment, mapContainerToRaw, mapEnvironmentSource, mapVolumeMount, mapWorkloadVolume, networkPolicyMediator, podSpecDefaults, requireBestEndpoint, workloadExtraArgs } from './chunk-SBC3TUIN.js';
6
+ export { dns01SolverMediator } from './chunk-2EEHJZPD.js';
7
+ export { createK8sTerminal, detectExternalIps } from './chunk-KDD6XUWM.js';
8
+ export { Gateway, HttpRoute, mapHttpRouteRuleMatch, resolveBackendRef } from './chunk-NXSYCA3V.js';
9
+ export { Service, getServiceType, isEndpointFromCluster, l4EndpointToServicePort, mapContainerPortToServicePort, mapServiceToLabelSelector } from './chunk-SI7X6N46.js';
10
+ import { Secret } from './chunk-IMTXUK2U.js';
11
+ export { Secret } from './chunk-IMTXUK2U.js';
12
+ import { commonExtraArgs, Namespace, mapMetadata, getProvider, getNamespaceName, images_exports } from './chunk-WGMJCZSK.js';
13
+ export { Namespace, ScopedResource, commonExtraArgs, getNamespaceName, getProvider, getProviderAsync, images_exports as images, mapMetadata, mapNamespaceNameToSelector, mapSelectorLikeToSelector, validateCluster } from './chunk-WGMJCZSK.js';
9
14
  import './chunk-PZ5AY32C.js';
10
- import { DnsRecordSet, filterEndpoints, l3EndpointToString, parseL34Endpoint } from '@highstate/common';
11
- import { gateway } from '@highstate/gateway-api';
12
- import { output, normalize, toPromise, apply, ComponentResource as ComponentResource$1 } from '@highstate/pulumi';
13
- import { ComponentResource, output as output$1 } from '@pulumi/pulumi';
14
- import { pipe, omitBy, mapValues, merge, mergeDeep, omit } from 'remeda';
15
+ import { getOrCreate, text, trimIndentation } from '@highstate/contract';
16
+ import { output, interpolate, toPromise, ComponentResource, normalizeInputs, normalize } from '@highstate/pulumi';
17
+ import { batch, core, rbac } from '@pulumi/kubernetes';
15
18
  import { deepmerge } from 'deepmerge-ts';
19
+ import { omit, map, unique, omitBy, mapValues, merge } from 'remeda';
20
+ import { KubeConfig } from '@kubernetes/client-node';
21
+ import { ComponentResource as ComponentResource$1, output as output$1 } from '@pulumi/pulumi';
16
22
  import { readPackageJSON } from 'pkg-types';
17
- import { text, trimIndentation } from '@highstate/contract';
23
+ import { parseL34Endpoint } from '@highstate/common';
18
24
  import { serializeFunction } from '@pulumi/pulumi/runtime/index.js';
19
- import { batch } from '@pulumi/kubernetes';
20
25
 
21
- function useAccessPoint(args) {
22
- const result = output({ args, namespaceName: output(args.namespace).metadata.name }).apply(
23
- ({ args: args2, namespaceName }) => {
24
- if (args2.accessPoint.clusterId !== args2.cluster.id) {
25
- throw new Error(
26
- "The provided Kubernetes cluster is different from the one where the access point is deployed."
27
- );
26
+ var CronJob = class _CronJob extends Workload {
27
+ constructor(type, name, args, opts, apiVersion, kind, terminalArgs, containers, namespace, metadata, networkPolicy, spec, status) {
28
+ super(
29
+ type,
30
+ name,
31
+ args,
32
+ opts,
33
+ apiVersion,
34
+ kind,
35
+ terminalArgs,
36
+ containers,
37
+ namespace,
38
+ metadata,
39
+ networkPolicy
40
+ );
41
+ this.spec = spec;
42
+ this.status = status;
43
+ }
44
+ /**
45
+ * The Highstate cron job entity.
46
+ */
47
+ get entity() {
48
+ return output({
49
+ type: "cron-job",
50
+ clusterId: this.cluster.id,
51
+ clusterName: this.cluster.name,
52
+ metadata: this.metadata
53
+ });
54
+ }
55
+ getTerminalMeta() {
56
+ return output({
57
+ title: "CronJob",
58
+ globalTitle: interpolate`CronJob | ${this.metadata.name}`,
59
+ description: "The shell inside the cron job.",
60
+ icon: "devicon:kubernetes"
61
+ });
62
+ }
63
+ get resourceType() {
64
+ return "cronjob";
65
+ }
66
+ /**
67
+ * Creates a new cron job.
68
+ */
69
+ static create(name, args, opts) {
70
+ return new CreatedCronJob(name, args, opts);
71
+ }
72
+ /**
73
+ * Creates a new cron job or patches an existing one.
74
+ *
75
+ * @param name The name of the resource. May not be the same as the cron job name.
76
+ * @param args The arguments to create or patch the cron job with.
77
+ * @param opts Optional resource options.
78
+ */
79
+ static createOrPatch(name, args, opts) {
80
+ if (args.existing) {
81
+ return new CronJobPatch(name, {
82
+ ...args,
83
+ name: output(args.existing).metadata.name,
84
+ namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster)
85
+ });
86
+ }
87
+ return new CreatedCronJob(name, args, opts);
88
+ }
89
+ /**
90
+ * Creates a new cron job or gets an existing one.
91
+ *
92
+ * @param name The name of the resource. May not be the same as the cron job name. Will not be used when existing cron job is retrieved.
93
+ * @param args The arguments to create or get the cron job with.
94
+ * @param opts Optional resource options.
95
+ */
96
+ static async createOrGet(name, args, opts) {
97
+ if (args.existing) {
98
+ return await _CronJob.forAsync(args.existing, output(args.namespace).cluster);
99
+ }
100
+ return new CreatedCronJob(name, args, opts);
101
+ }
102
+ /**
103
+ * Patches an existing cron job.
104
+ *
105
+ * Will throw an error if the cron job does not exist.
106
+ *
107
+ * @param name The name of the resource. May not be the same as the cron job name.
108
+ * @param args The arguments to patch the cron job with.
109
+ * @param opts Optional resource options.
110
+ */
111
+ static patch(name, args, opts) {
112
+ return new CronJobPatch(name, args, opts);
113
+ }
114
+ /**
115
+ * Wraps an existing Kubernetes cron job.
116
+ */
117
+ static wrap(name, args, opts) {
118
+ return new WrappedCronJob(name, args, opts);
119
+ }
120
+ /**
121
+ * Gets an existing cron job.
122
+ *
123
+ * Will throw an error if the cron job does not exist.
124
+ */
125
+ static get(name, args, opts) {
126
+ return new ExternalCronJob(name, args, opts);
127
+ }
128
+ static cronJobCache = /* @__PURE__ */ new Map();
129
+ /**
130
+ * Gets an existing cron job for a given entity.
131
+ * Prefer this method over `get` when possible.
132
+ *
133
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
134
+ *
135
+ * This method is idempotent and will return the same instance for the same entity.
136
+ *
137
+ * @param entity The entity to get the cron job for.
138
+ * @param cluster The cluster where the cron job is located.
139
+ */
140
+ static for(entity, cluster) {
141
+ return getOrCreate(
142
+ _CronJob.cronJobCache,
143
+ `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
144
+ (name) => {
145
+ return _CronJob.get(name, {
146
+ name: entity.metadata.name,
147
+ namespace: Namespace.forResource(entity, cluster)
148
+ });
28
149
  }
29
- const gateway2 = createGateway({
30
- ...args2,
31
- annotations: {
32
- "cert-manager.io/cluster-issuer": args2.accessPoint.tlsIssuer.clusterIssuerName
150
+ );
151
+ }
152
+ /**
153
+ * Gets an existing cron job for a given entity.
154
+ * Prefer this method over `get` when possible.
155
+ *
156
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
157
+ *
158
+ * This method is idempotent and will return the same instance for the same entity.
159
+ *
160
+ * @param entity The entity to get the cron job for.
161
+ * @param cluster The cluster where the cron job is located.
162
+ */
163
+ static async forAsync(entity, cluster) {
164
+ const resolvedEntity = await toPromise(entity);
165
+ return _CronJob.for(resolvedEntity, cluster);
166
+ }
167
+ };
168
+ var cronJobExtraArgs = [...commonExtraArgs, "container", "containers"];
169
+ var CreatedCronJob = class extends CronJob {
170
+ constructor(name, args, opts) {
171
+ const { podTemplate, containers, networkPolicy } = getWorkloadComponents(
172
+ name,
173
+ args,
174
+ () => this,
175
+ opts
176
+ );
177
+ const cronJob = output(args.namespace).cluster.apply((cluster) => {
178
+ return new batch.v1.CronJob(
179
+ name,
180
+ {
181
+ metadata: mapMetadata(args, name),
182
+ spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
183
+ return deepmerge(
184
+ {
185
+ jobTemplate: {
186
+ spec: {
187
+ template: deepmerge(
188
+ {
189
+ spec: {
190
+ restartPolicy: "Never"
191
+ }
192
+ },
193
+ podTemplate2
194
+ )
195
+ }
196
+ },
197
+ schedule: args2.schedule
198
+ },
199
+ omit(args2, cronJobExtraArgs)
200
+ );
201
+ })
202
+ },
203
+ {
204
+ ...opts,
205
+ parent: this,
206
+ provider: getProvider(cluster)
207
+ }
208
+ );
209
+ });
210
+ super(
211
+ "highstate:k8s:CronJob",
212
+ name,
213
+ args,
214
+ opts,
215
+ cronJob.apiVersion,
216
+ cronJob.kind,
217
+ output(args.terminal ?? {}),
218
+ containers,
219
+ output(args.namespace),
220
+ cronJob.metadata,
221
+ networkPolicy,
222
+ cronJob.spec,
223
+ cronJob.status
224
+ );
225
+ }
226
+ };
227
+ var CronJobPatch = class extends CronJob {
228
+ constructor(name, args, opts) {
229
+ const { podTemplate, containers, networkPolicy } = getWorkloadComponents(
230
+ name,
231
+ args,
232
+ () => this,
233
+ opts
234
+ );
235
+ const cronJob = output(args.namespace).cluster.apply((cluster) => {
236
+ return new batch.v1.CronJobPatch(
237
+ name,
238
+ {
239
+ metadata: mapMetadata(args, name),
240
+ spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
241
+ return deepmerge(
242
+ {
243
+ jobTemplate: {
244
+ spec: {
245
+ template: podTemplate2
246
+ }
247
+ },
248
+ schedule: args2.schedule
249
+ },
250
+ omit(args2, cronJobExtraArgs)
251
+ );
252
+ })
33
253
  },
34
- gateway: args2.accessPoint.gateway
254
+ {
255
+ ...opts,
256
+ parent: this,
257
+ provider: getProvider(cluster)
258
+ }
259
+ );
260
+ });
261
+ super(
262
+ "highstate:k8s:CronJobPatch",
263
+ name,
264
+ args,
265
+ opts,
266
+ cronJob.apiVersion,
267
+ cronJob.kind,
268
+ output(args.terminal ?? {}),
269
+ containers,
270
+ output(args.namespace),
271
+ cronJob.metadata,
272
+ networkPolicy,
273
+ cronJob.spec,
274
+ cronJob.status
275
+ );
276
+ }
277
+ };
278
+ var WrappedCronJob = class extends CronJob {
279
+ constructor(name, args, opts) {
280
+ super(
281
+ "highstate:k8s:WrappedCronJob",
282
+ name,
283
+ args,
284
+ opts,
285
+ output(args.cronJob).apiVersion,
286
+ output(args.cronJob).kind,
287
+ output(args.terminal ?? {}),
288
+ output([]),
289
+ output(args.namespace),
290
+ output(args.cronJob).metadata,
291
+ output(void 0),
292
+ output(args.cronJob).spec,
293
+ output(args.cronJob).status
294
+ );
295
+ }
296
+ };
297
+ var ExternalCronJob = class extends CronJob {
298
+ constructor(name, args, opts) {
299
+ const cronJob = output(args.namespace).cluster.apply((cluster) => {
300
+ return batch.v1.CronJob.get(
301
+ name,
302
+ interpolate`${output(args.namespace).metadata.name}/${args.name}`,
303
+ { ...opts, parent: this, provider: getProvider(cluster) }
304
+ );
305
+ });
306
+ super(
307
+ "highstate:k8s:ExternalCronJob",
308
+ name,
309
+ args,
310
+ opts,
311
+ cronJob.apiVersion,
312
+ cronJob.kind,
313
+ output({}),
314
+ output([]),
315
+ output(args.namespace),
316
+ cronJob.metadata,
317
+ output(void 0),
318
+ cronJob.spec,
319
+ cronJob.status
320
+ );
321
+ }
322
+ };
323
+ var Job = class _Job extends Workload {
324
+ constructor(type, name, args, opts, apiVersion, kind, terminalArgs, containers, namespace, metadata, networkPolicy, spec, status) {
325
+ super(
326
+ type,
327
+ name,
328
+ args,
329
+ opts,
330
+ apiVersion,
331
+ kind,
332
+ terminalArgs,
333
+ containers,
334
+ namespace,
335
+ metadata,
336
+ networkPolicy
337
+ );
338
+ this.spec = spec;
339
+ this.status = status;
340
+ }
341
+ /**
342
+ * The Highstate job entity.
343
+ */
344
+ get entity() {
345
+ return output({
346
+ type: "job",
347
+ clusterId: this.cluster.id,
348
+ clusterName: this.cluster.name,
349
+ metadata: this.metadata
350
+ });
351
+ }
352
+ getTerminalMeta() {
353
+ return output({
354
+ title: "Job",
355
+ globalTitle: interpolate`Job | ${this.metadata.name}`,
356
+ description: "The shell inside the job.",
357
+ icon: "devicon:kubernetes"
358
+ });
359
+ }
360
+ get resourceType() {
361
+ return "job";
362
+ }
363
+ /**
364
+ * Creates a new job.
365
+ */
366
+ static create(name, args, opts) {
367
+ return new CreatedJob(name, args, opts);
368
+ }
369
+ /**
370
+ * Creates a new job or patches an existing one.
371
+ *
372
+ * @param name The name of the resource. May not be the same as the job name.
373
+ * @param args The arguments to create or patch the job with.
374
+ * @param opts Optional resource options.
375
+ */
376
+ static createOrPatch(name, args, opts) {
377
+ if (args.existing) {
378
+ return new JobPatch(name, {
379
+ ...args,
380
+ name: output(args.existing).metadata.name,
381
+ namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster)
35
382
  });
36
- const dnsRecordSets = normalize(args2.fqdn, args2.fqdns).flatMap((fqdn) => {
37
- return DnsRecordSet.create(fqdn, {
38
- providers: args2.accessPoint.dnsProviders,
39
- values: filterEndpoints(
40
- args2.accessPoint.gateway.endpoints.filter((endpoint) => endpoint.type !== "hostname")
41
- )
383
+ }
384
+ return new CreatedJob(name, args, opts);
385
+ }
386
+ /**
387
+ * Creates a new job or gets an existing one.
388
+ *
389
+ * @param name The name of the resource. May not be the same as the job name. Will not be used when existing job is retrieved.
390
+ * @param args The arguments to create or get the job with.
391
+ * @param opts Optional resource options.
392
+ */
393
+ static async createOrGet(name, args, opts) {
394
+ if (args.existing) {
395
+ return await _Job.forAsync(args.existing, output(args.namespace).cluster);
396
+ }
397
+ return new CreatedJob(name, args, opts);
398
+ }
399
+ /**
400
+ * Patches an existing job.
401
+ *
402
+ * Will throw an error if the job does not exist.
403
+ *
404
+ * @param name The name of the resource. May not be the same as the job name.
405
+ * @param args The arguments to patch the job with.
406
+ * @param opts Optional resource options.
407
+ */
408
+ static patch(name, args, opts) {
409
+ return new JobPatch(name, args, opts);
410
+ }
411
+ /**
412
+ * Wraps an existing Kubernetes job.
413
+ */
414
+ static wrap(name, args, opts) {
415
+ return new WrappedJob(name, args, opts);
416
+ }
417
+ /**
418
+ * Gets an existing job.
419
+ *
420
+ * Will throw an error if the job does not exist.
421
+ */
422
+ static get(name, args, opts) {
423
+ return new ExternalJob(name, args, opts);
424
+ }
425
+ static jobCache = /* @__PURE__ */ new Map();
426
+ /**
427
+ * Gets an existing job for a given entity.
428
+ * Prefer this method over `get` when possible.
429
+ *
430
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
431
+ *
432
+ * This method is idempotent and will return the same instance for the same entity.
433
+ *
434
+ * @param entity The entity to get the job for.
435
+ * @param cluster The cluster where the job is located.
436
+ */
437
+ static for(entity, cluster) {
438
+ return getOrCreate(
439
+ _Job.jobCache,
440
+ `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
441
+ (name) => {
442
+ return _Job.get(name, {
443
+ name: entity.metadata.name,
444
+ namespace: Namespace.forResource(entity, cluster)
42
445
  });
43
- });
44
- const networkPolicies = [
45
- NetworkPolicy.create(
46
- `allow-ingress-from-${l3EndpointToString(args2.accessPoint.gateway.endpoints[0])}`,
47
- {
48
- namespace: args2.namespace,
49
- cluster: args2.cluster,
50
- description: `Allow ingress traffic from the gateway at "${l3EndpointToString(args2.accessPoint.gateway.endpoints[0])}".`,
51
- ingressRule: {
52
- fromEndpoints: args2.accessPoint.gateway.endpoints
446
+ }
447
+ );
448
+ }
449
+ /**
450
+ * Gets an existing job for a given entity.
451
+ * Prefer this method over `get` when possible.
452
+ *
453
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
454
+ *
455
+ * This method is idempotent and will return the same instance for the same entity.
456
+ *
457
+ * @param entity The entity to get the job for.
458
+ * @param cluster The cluster where the job is located.
459
+ */
460
+ static async forAsync(entity, cluster) {
461
+ const resolvedEntity = await toPromise(entity);
462
+ return _Job.for(resolvedEntity, cluster);
463
+ }
464
+ };
465
+ var jobExtraArgs = [...commonExtraArgs, "container", "containers"];
466
+ var CreatedJob = class extends Job {
467
+ constructor(name, args, opts) {
468
+ const { podTemplate, containers, networkPolicy } = getWorkloadComponents(
469
+ name,
470
+ args,
471
+ () => this,
472
+ opts
473
+ );
474
+ const job = output(args.namespace).cluster.apply((cluster) => {
475
+ return new batch.v1.Job(
476
+ name,
477
+ {
478
+ metadata: mapMetadata(args, name),
479
+ spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
480
+ return deepmerge(
481
+ {
482
+ template: deepmerge(
483
+ {
484
+ spec: {
485
+ restartPolicy: "Never"
486
+ }
487
+ },
488
+ podTemplate2
489
+ )
490
+ },
491
+ omit(args2, jobExtraArgs)
492
+ );
493
+ })
494
+ },
495
+ { ...opts, parent: this, provider: getProvider(cluster) }
496
+ );
497
+ });
498
+ super(
499
+ "highstate:k8s:Job",
500
+ name,
501
+ args,
502
+ opts,
503
+ job.apiVersion,
504
+ job.kind,
505
+ output(args.terminal ?? {}),
506
+ containers,
507
+ output(args.namespace),
508
+ job.metadata,
509
+ networkPolicy,
510
+ job.spec,
511
+ job.status
512
+ );
513
+ }
514
+ };
515
+ var JobPatch = class extends Job {
516
+ constructor(name, args, opts) {
517
+ const { podTemplate, containers, networkPolicy } = getWorkloadComponents(
518
+ name,
519
+ args,
520
+ () => this,
521
+ opts
522
+ );
523
+ const job = output(args.namespace).cluster.apply((cluster) => {
524
+ return new batch.v1.JobPatch(
525
+ name,
526
+ {
527
+ metadata: mapMetadata(args, name),
528
+ spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
529
+ return deepmerge(
530
+ { template: podTemplate2 },
531
+ omit(args2, jobExtraArgs)
532
+ );
533
+ })
534
+ },
535
+ { ...opts, parent: this, provider: getProvider(cluster) }
536
+ );
537
+ });
538
+ super(
539
+ "highstate:k8s:JobPatch",
540
+ name,
541
+ args,
542
+ opts,
543
+ job.apiVersion,
544
+ job.kind,
545
+ output(args.terminal ?? {}),
546
+ containers,
547
+ output(args.namespace),
548
+ job.metadata,
549
+ networkPolicy,
550
+ job.spec,
551
+ job.status
552
+ );
553
+ this.registerOutputs({
554
+ metadata: this.metadata,
555
+ spec: this.spec,
556
+ status: this.status
557
+ });
558
+ }
559
+ };
560
+ var WrappedJob = class extends Job {
561
+ constructor(name, args, opts) {
562
+ super(
563
+ "highstate:k8s:WrappedJob",
564
+ name,
565
+ args,
566
+ opts,
567
+ output(args.job).apiVersion,
568
+ output(args.job).kind,
569
+ output(args.terminal ?? {}),
570
+ output([]),
571
+ output(args.namespace),
572
+ output(args.job).metadata,
573
+ output(void 0),
574
+ output(args.job).spec,
575
+ output(args.job).status
576
+ );
577
+ }
578
+ };
579
+ var ExternalJob = class extends Job {
580
+ constructor(name, args, opts) {
581
+ const job = output(args.namespace).cluster.apply((cluster) => {
582
+ return batch.v1.Job.get(
583
+ name,
584
+ interpolate`${output(args.namespace).metadata.name}/${args.name}`,
585
+ { ...opts, parent: this, provider: getProvider(cluster) }
586
+ );
587
+ });
588
+ super(
589
+ "highstate:k8s:ExternalJob",
590
+ name,
591
+ args,
592
+ opts,
593
+ job.apiVersion,
594
+ job.kind,
595
+ output({}),
596
+ output([]),
597
+ output(args.namespace),
598
+ job.metadata,
599
+ output(void 0),
600
+ job.spec,
601
+ job.status
602
+ );
603
+ }
604
+ };
605
+ var ClusterAccessScope = class _ClusterAccessScope extends ComponentResource {
606
+ /**
607
+ * The cluster entity with the reduced access.
608
+ */
609
+ cluster;
610
+ constructor(name, args, opts) {
611
+ super("highstate:k8s:ClusterAccessScope", name, args, opts);
612
+ const { serviceAccount, kubeconfig } = output(args.namespace).cluster.apply((cluster) => {
613
+ const provider = getProvider(cluster);
614
+ const namespaceName = output(args.namespace).metadata.name;
615
+ const serviceAccount2 = new core.v1.ServiceAccount(
616
+ name,
617
+ {
618
+ metadata: {
619
+ name,
620
+ namespace: namespaceName
621
+ }
622
+ },
623
+ { provider }
624
+ );
625
+ const clusterRole = new rbac.v1.ClusterRole(
626
+ name,
627
+ {
628
+ metadata: {
629
+ name: interpolate`highstate.${namespaceName}.${name}`,
630
+ annotations: {
631
+ "kubernetes.io/description": interpolate`Created by Highstate for the ServiceAccount "${name}" in the namespace "${namespaceName}".`
53
632
  }
54
633
  },
55
- { provider: args2.provider }
56
- )
57
- ];
58
- if (isFromCluster(args2.accessPoint.gateway.endpoints[0], args2.cluster)) {
59
- networkPolicies.push(
60
- NetworkPolicy.create(
61
- `allow-egress-to-${namespaceName}`,
62
- {
63
- namespace: args2.accessPoint.gateway.endpoints[0].metadata.k8sService.namespace,
64
- cluster: args2.cluster,
65
- selector: args2.accessPoint.gateway.endpoints[0].metadata.k8sService.selector,
66
- description: `Allow egress traffic to the namespace "${namespaceName}".`,
67
- egressRule: {
68
- toNamespace: args2.namespace
69
- }
634
+ rules: normalizeInputs(args.rule, args.rules)
635
+ },
636
+ { provider }
637
+ );
638
+ const createRoleBinding = (namespace) => {
639
+ return new rbac.v1.RoleBinding(
640
+ name,
641
+ {
642
+ metadata: { name, namespace },
643
+ roleRef: {
644
+ kind: "ClusterRole",
645
+ name: clusterRole.metadata.name,
646
+ apiGroup: "rbac.authorization.k8s.io"
70
647
  },
71
- { provider: args2.provider }
72
- )
648
+ subjects: [
649
+ {
650
+ kind: "ServiceAccount",
651
+ name: serviceAccount2.metadata.name,
652
+ namespace: namespaceName
653
+ }
654
+ ]
655
+ },
656
+ { provider }
73
657
  );
658
+ };
659
+ if (args.allowOriginNamespace ?? true) {
660
+ createRoleBinding(namespaceName);
661
+ }
662
+ output(args.extraNamespaces ?? []).apply(map(getNamespaceName)).apply(map(createRoleBinding));
663
+ return { serviceAccount: serviceAccount2, kubeconfig: cluster.kubeconfig };
664
+ });
665
+ const accessTokenSecret = Secret.create(`${name}-token`, {
666
+ namespace: args.namespace,
667
+ type: "kubernetes.io/service-account-token",
668
+ metadata: {
669
+ annotations: {
670
+ "kubernetes.io/service-account.name": serviceAccount.metadata.name
671
+ }
74
672
  }
75
- return output({
76
- gateway: gateway2,
77
- dnsRecordSets,
78
- networkPolicies
673
+ });
674
+ this.cluster = output({
675
+ cluster: output(args.namespace).cluster,
676
+ kubeconfig,
677
+ newToken: accessTokenSecret.getValue("token"),
678
+ serviceAccount: serviceAccount.metadata.name
679
+ }).apply(({ cluster, kubeconfig: kubeconfig2, newToken, serviceAccount: serviceAccount2 }) => {
680
+ const config = new KubeConfig();
681
+ config.loadFromString(kubeconfig2);
682
+ config.users = [];
683
+ config.contexts = [];
684
+ config.addUser({ name: serviceAccount2, token: newToken });
685
+ config.addContext({
686
+ name: config.clusters[0].name,
687
+ cluster: config.clusters[0].name,
688
+ user: serviceAccount2
79
689
  });
690
+ config.setCurrentContext(config.clusters[0].name);
691
+ return {
692
+ ...cluster,
693
+ kubeconfig: config.exportConfig()
694
+ };
695
+ });
696
+ }
697
+ /**
698
+ * Creates `ClusterAccessScope` for the given resources with the specified verbs.
699
+ *
700
+ * All resources must belong to the same namespace in the same cluster.
701
+ *
702
+ * @param name The name of the resource and the ServiceAccount.
703
+ * @param resources The resources to create access scope for.
704
+ * @param verbs The verbs to allow on the resources.
705
+ */
706
+ static async forResources(name, resources, verbs) {
707
+ const resolved = await toPromise(
708
+ output(resources).apply(
709
+ (resources2) => resources2.map((r) => ({
710
+ namespaceId: r.namespace.metadata.uid,
711
+ namespace: r.namespace,
712
+ metadata: r.metadata,
713
+ apiVersion: r.apiVersion,
714
+ kind: r.kind
715
+ }))
716
+ )
717
+ );
718
+ if (resolved.length === 0) {
719
+ throw new Error("No resources provided to forResources.");
80
720
  }
81
- );
82
- return toPromise(result);
83
- }
84
- async function useStandardAcessPoint(namespace, args, inputs) {
85
- return await useAccessPoint({
86
- name: args.appName,
87
- namespace,
88
- fqdn: args.fqdn,
89
- accessPoint: inputs.accessPoint,
90
- cluster: inputs.k8sCluster,
91
- provider: await getProvider(inputs.k8sCluster)
92
- });
93
- }
94
- function createGateway(args) {
95
- return output(args).apply((args2) => {
96
- if (args2.cluster.id !== args2.gateway.clusterId) {
97
- throw new Error(
98
- "The provided Kubernetes cluster is different from the one where the gateway controller is deployed."
99
- );
721
+ if (unique(resolved.map((r) => r.namespaceId)).length !== 1) {
722
+ throw new Error("All resources must belong to the same namespace.");
100
723
  }
101
- return new gateway.v1.Gateway(
102
- args2.name,
103
- {
104
- metadata: {
105
- name: args2.name,
106
- namespace: mapNamespaceLikeToNamespaceName(args2.namespace),
107
- annotations: args2.annotations
108
- },
109
- spec: {
110
- gatewayClassName: output(args2.gateway).gatewayClassName,
111
- listeners: normalize(args2.fqdn, args2.fqdns).map((fqdn) => {
112
- const normalizedName = fqdn.replace(/\*/g, "wildcard");
113
- return {
114
- name: `https-${normalizedName}`,
115
- port: output(args2.gateway).httpsListenerPort,
116
- protocol: "HTTPS",
117
- hostname: fqdn,
118
- tls: {
119
- mode: "Terminate",
120
- certificateRefs: [{ name: normalizedName }]
121
- }
122
- };
123
- })
124
- }
125
- },
126
- { provider: args2.provider, deletedWith: args2.namespace }
127
- );
128
- });
129
- }
724
+ return new _ClusterAccessScope(name, {
725
+ namespace: resolved[0].namespace,
726
+ rules: resolved.map((r) => ({
727
+ apiGroups: r.apiVersion === "v1" ? [""] : [r.apiVersion.split("/")[0]],
728
+ resources: [r.kind.toLowerCase() + (r.metadata?.name ? "s" : "")],
729
+ // TODO: critical
730
+ // resourceNames: r.metadata?.name ? [r.metadata.name] : undefined,
731
+ verbs
732
+ }))
733
+ });
734
+ }
735
+ };
130
736
 
131
737
  // src/scripting/environment.ts
132
738
  var emptyDistributionEnvironment = {
@@ -169,7 +775,7 @@ var functionScriptImages = {
169
775
  };
170
776
 
171
777
  // src/scripting/bundle.ts
172
- var ScriptBundle = class extends ComponentResource {
778
+ var ScriptBundle = class extends ComponentResource$1 {
173
779
  /**
174
780
  * The config map containing the scripts.
175
781
  */
@@ -200,11 +806,7 @@ var ScriptBundle = class extends ComponentResource {
200
806
  allowedEndpoints;
201
807
  constructor(name, args, opts) {
202
808
  super("highstate:k8s:ScriptBundle", name, args, opts);
203
- const scriptEnvironment = pipe(
204
- output$1(args),
205
- apply((args2) => normalize(args2.environment, args2.environments)),
206
- apply((args2) => deepmerge(emptyScriptEnvironment, ...args2))
207
- );
809
+ const scriptEnvironment = output$1(args).apply((args2) => normalize(args2.environment, args2.environments)).apply((args2) => deepmerge(emptyScriptEnvironment, ...args2));
208
810
  const hasFunctionScripts = scriptEnvironment.apply((scriptEnvironment2) => {
209
811
  return Object.values(scriptEnvironment2.files).some((file) => typeof file === "function");
210
812
  });
@@ -231,7 +833,6 @@ var ScriptBundle = class extends ComponentResource {
231
833
  return ConfigMap.create(
232
834
  name,
233
835
  {
234
- cluster: args2.cluster,
235
836
  namespace: args2.namespace,
236
837
  data: createScriptData(this.distribution, scriptEnvironment2)
237
838
  },
@@ -267,15 +868,6 @@ var ScriptBundle = class extends ComponentResource {
267
868
  ...hasFunctionScripts2 ? [{ name: "node-modules", mountPath: "/scripts/node_modules" }] : []
268
869
  ];
269
870
  });
270
- this.registerOutputs({
271
- configMap: this.configMap,
272
- volumes: this.volumes,
273
- volumeMounts: this.volumeMounts,
274
- environment: this.environment,
275
- distribution: this.distribution,
276
- allowedEndpoints: this.allowedEndpoints,
277
- image: this.image
278
- });
279
871
  }
280
872
  };
281
873
  function stripWorkspacePrefix(value) {
@@ -441,86 +1033,22 @@ function createScriptContainer(options) {
441
1033
  };
442
1034
  });
443
1035
  }
444
- var jobExtraArgs = [...commonExtraArgs, "container", "containers"];
445
- var Job = class extends ComponentResource$1 {
446
- /**
447
- * The underlying Kubernetes job.
448
- */
449
- job;
450
- constructor(name, args, opts) {
451
- super("highstate:k8s:Job", name, args, opts);
452
- const { podTemplate } = getWorkloadComponents(name, args, () => this, opts);
453
- this.job = output({ args, podTemplate }).apply(async ({ args: args2, podTemplate: podTemplate2 }) => {
454
- return new batch.v1.Job(
455
- name,
456
- {
457
- metadata: mapMetadata(args2, name),
458
- spec: mergeDeep(
459
- {
460
- template: mergeDeep(
461
- {
462
- spec: {
463
- restartPolicy: "Never"
464
- }
465
- },
466
- podTemplate2
467
- )
468
- },
469
- omit(args2, jobExtraArgs)
470
- )
471
- },
472
- {
473
- ...opts,
474
- parent: this,
475
- provider: await getProvider(args2.cluster)
476
- }
477
- );
478
- });
479
- }
480
- };
481
- var cronJobExtraArgs = [...commonExtraArgs, "container", "containers"];
482
- var CronJob = class extends ComponentResource$1 {
483
- /**
484
- * The underlying Kubernetes job.
485
- */
486
- cronJob;
487
- constructor(name, args, opts) {
488
- super("highstate:k8s:CronJob", name, args, opts);
489
- const { podTemplate } = getWorkloadComponents(name, args, () => this, opts);
490
- this.cronJob = output({ args, podTemplate }).apply(async ({ args: args2, podTemplate: podTemplate2 }) => {
491
- return new batch.v1.CronJob(
492
- name,
493
- {
494
- metadata: mapMetadata(args2, name),
495
- spec: mergeDeep(
496
- {
497
- jobTemplate: {
498
- spec: {
499
- template: mergeDeep(
500
- {
501
- spec: {
502
- restartPolicy: "Never"
503
- }
504
- },
505
- podTemplate2
506
- )
507
- }
508
- },
509
- schedule: args2.schedule
510
- },
511
- omit(args2, cronJobExtraArgs)
512
- )
513
- },
514
- {
515
- ...opts,
516
- parent: this,
517
- provider: await getProvider(args2.cluster)
518
- }
519
- );
520
- });
521
- }
522
- };
1036
+ async function createMonitorWorker(resources) {
1037
+ const scope = await ClusterAccessScope.forResources("monitor", resources, [
1038
+ "get",
1039
+ "list",
1040
+ "watch"
1041
+ ]);
1042
+ return output$1({
1043
+ name: "monitor",
1044
+ image: images_exports["worker-k8s-monitor"].image,
1045
+ params: {
1046
+ kubeconfig: scope.cluster.kubeconfig,
1047
+ resources: output$1(resources).apply((resources2) => resources2.map((r) => r.entity))
1048
+ }
1049
+ });
1050
+ }
523
1051
 
524
- export { CronJob, Job, ScriptBundle, createScriptContainer, useAccessPoint, useStandardAcessPoint };
1052
+ export { ClusterAccessScope, CronJob, Job, ScriptBundle, createMonitorWorker, createScriptContainer, emptyScriptEnvironment, functionScriptImages };
525
1053
  //# sourceMappingURL=index.js.map
526
1054
  //# sourceMappingURL=index.js.map