@highstate/k8s 0.18.0 → 0.20.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.
Files changed (105) hide show
  1. package/dist/{chunk-FE4SHRAJ.js → chunk-23X5SXQG.js} +22 -7
  2. package/dist/chunk-23X5SXQG.js.map +1 -0
  3. package/dist/{chunk-LGHFSXNT.js → chunk-ADHZK6V2.js} +14 -10
  4. package/dist/chunk-ADHZK6V2.js.map +1 -0
  5. package/dist/{chunk-VCXWCZ43.js → chunk-BTAEFJ5N.js} +27 -15
  6. package/dist/chunk-BTAEFJ5N.js.map +1 -0
  7. package/dist/{chunk-BR2CLUUD.js → chunk-IXE3OKB4.js} +27 -8
  8. package/dist/chunk-IXE3OKB4.js.map +1 -0
  9. package/dist/{chunk-TWBMG6TD.js → chunk-OG2OPX7B.js} +30 -12
  10. package/dist/chunk-OG2OPX7B.js.map +1 -0
  11. package/dist/{chunk-DCUMJSO6.js → chunk-P26SQ2ZB.js} +17 -51
  12. package/dist/chunk-P26SQ2ZB.js.map +1 -0
  13. package/dist/{chunk-MIC2BHGS.js → chunk-PG27ZY2H.js} +25 -7
  14. package/dist/chunk-PG27ZY2H.js.map +1 -0
  15. package/dist/chunk-PZYGZSN5.js +54 -0
  16. package/dist/{chunk-PZ5AY32C.js.map → chunk-PZYGZSN5.js.map} +1 -1
  17. package/dist/{chunk-YIJUVPU2.js → chunk-S77TE7UC.js} +27 -15
  18. package/dist/chunk-S77TE7UC.js.map +1 -0
  19. package/dist/{chunk-P2VOUU7E.js → chunk-SZKOAHNX.js} +383 -205
  20. package/dist/chunk-SZKOAHNX.js.map +1 -0
  21. package/dist/chunk-TOLFVF4S.js +889 -0
  22. package/dist/chunk-TOLFVF4S.js.map +1 -0
  23. package/dist/{chunk-RVB4WWZZ.js → chunk-TVKT3ZYX.js} +174 -18
  24. package/dist/chunk-TVKT3ZYX.js.map +1 -0
  25. package/dist/cron-job-RKB2HYTO.js +7 -0
  26. package/dist/{cron-job-NX4HD4FI.js.map → cron-job-RKB2HYTO.js.map} +1 -1
  27. package/dist/deployment-T35TUOL2.js +7 -0
  28. package/dist/{deployment-O2LJ5WR5.js.map → deployment-T35TUOL2.js.map} +1 -1
  29. package/dist/highstate.manifest.json +3 -2
  30. package/dist/impl/dynamic-endpoint-resolver.js +90 -0
  31. package/dist/impl/dynamic-endpoint-resolver.js.map +1 -0
  32. package/dist/impl/gateway-route.js +159 -62
  33. package/dist/impl/gateway-route.js.map +1 -1
  34. package/dist/impl/tls-certificate.js +6 -5
  35. package/dist/impl/tls-certificate.js.map +1 -1
  36. package/dist/index.js +106 -23
  37. package/dist/index.js.map +1 -1
  38. package/dist/job-PE4AKOHB.js +7 -0
  39. package/dist/job-PE4AKOHB.js.map +1 -0
  40. package/dist/stateful-set-LUIRHQJY.js +7 -0
  41. package/dist/{stateful-set-VJYKTQ72.js.map → stateful-set-LUIRHQJY.js.map} +1 -1
  42. package/dist/units/cert-manager/index.js +7 -8
  43. package/dist/units/cert-manager/index.js.map +1 -1
  44. package/dist/units/cluster-patch/index.js +6 -6
  45. package/dist/units/cluster-patch/index.js.map +1 -1
  46. package/dist/units/dns01-issuer/index.js +52 -15
  47. package/dist/units/dns01-issuer/index.js.map +1 -1
  48. package/dist/units/existing-cluster/index.js +39 -18
  49. package/dist/units/existing-cluster/index.js.map +1 -1
  50. package/dist/units/gateway-api/index.js +2 -2
  51. package/dist/units/reduced-access-cluster/index.js +8 -8
  52. package/dist/units/reduced-access-cluster/index.js.map +1 -1
  53. package/package.json +9 -7
  54. package/src/cluster.ts +12 -8
  55. package/src/config-map.ts +15 -5
  56. package/src/container.ts +4 -2
  57. package/src/cron-job.ts +25 -4
  58. package/src/deployment.ts +32 -17
  59. package/src/gateway/backend.ts +3 -3
  60. package/src/gateway/gateway.ts +12 -56
  61. package/src/helm.ts +354 -22
  62. package/src/impl/dynamic-endpoint-resolver.ts +109 -0
  63. package/src/impl/gateway-route.ts +231 -57
  64. package/src/impl/tls-certificate.ts +8 -3
  65. package/src/index.ts +1 -0
  66. package/src/job.ts +23 -5
  67. package/src/kubectl.ts +166 -0
  68. package/src/namespace.ts +47 -3
  69. package/src/network-policy.ts +1 -1
  70. package/src/pvc.ts +12 -2
  71. package/src/rbac.ts +28 -5
  72. package/src/scripting/environment.ts +3 -2
  73. package/src/secret.ts +15 -5
  74. package/src/service.ts +28 -6
  75. package/src/shared.ts +30 -2
  76. package/src/stateful-set.ts +32 -17
  77. package/src/tls.ts +31 -5
  78. package/src/units/cluster-patch/index.ts +5 -5
  79. package/src/units/dns01-issuer/index.ts +56 -12
  80. package/src/units/existing-cluster/index.ts +36 -15
  81. package/src/units/reduced-access-cluster/index.ts +6 -3
  82. package/src/worker.ts +4 -2
  83. package/src/workload.ts +453 -213
  84. package/dist/chunk-4G6LLC2X.js +0 -240
  85. package/dist/chunk-4G6LLC2X.js.map +0 -1
  86. package/dist/chunk-BR2CLUUD.js.map +0 -1
  87. package/dist/chunk-DCUMJSO6.js.map +0 -1
  88. package/dist/chunk-FE4SHRAJ.js.map +0 -1
  89. package/dist/chunk-KMLRI5UZ.js +0 -155
  90. package/dist/chunk-KMLRI5UZ.js.map +0 -1
  91. package/dist/chunk-LGHFSXNT.js.map +0 -1
  92. package/dist/chunk-MIC2BHGS.js.map +0 -1
  93. package/dist/chunk-OBDQONMV.js +0 -401
  94. package/dist/chunk-OBDQONMV.js.map +0 -1
  95. package/dist/chunk-P2VOUU7E.js.map +0 -1
  96. package/dist/chunk-PZ5AY32C.js +0 -9
  97. package/dist/chunk-RVB4WWZZ.js.map +0 -1
  98. package/dist/chunk-TWBMG6TD.js.map +0 -1
  99. package/dist/chunk-VCXWCZ43.js.map +0 -1
  100. package/dist/chunk-YIJUVPU2.js.map +0 -1
  101. package/dist/cron-job-NX4HD4FI.js +0 -8
  102. package/dist/deployment-O2LJ5WR5.js +0 -8
  103. package/dist/job-SYME6Y43.js +0 -8
  104. package/dist/job-SYME6Y43.js.map +0 -1
  105. package/dist/stateful-set-VJYKTQ72.js +0 -8
@@ -0,0 +1,889 @@
1
+ import { __export } from './chunk-PZYGZSN5.js';
2
+ import { getOrCreate } from '@highstate/contract';
3
+ import { common, k8s } from '@highstate/library';
4
+ import { secret, toPromise, output, ComponentResource, normalizeInputs, interpolate, makeEntity, makeEntityOutput } from '@highstate/pulumi';
5
+ import { Provider, core, rbac } from '@pulumi/kubernetes';
6
+ import { output as output$1 } from '@pulumi/pulumi';
7
+ import { KubeConfig } from '@kubernetes/client-node';
8
+ import { map, unique } from 'remeda';
9
+
10
+ // assets/images.json
11
+ var images_exports = {};
12
+ __export(images_exports, {
13
+ alpine: () => alpine,
14
+ default: () => images_default,
15
+ "terminal-kubectl": () => terminal_kubectl,
16
+ ubuntu: () => ubuntu,
17
+ "worker.k8s-monitor": () => worker_k8s_monitor
18
+ });
19
+ var terminal_kubectl = {
20
+ name: "ghcr.io/highstate-io/highstate/terminal.kubectl",
21
+ tag: "latest",
22
+ image: "ghcr.io/highstate-io/highstate/terminal.kubectl:latest@sha256:31cf095ec6acc0b3a5088c92483d88dc1e2e7dd7fcbf2ec8de29a0171debd8aa"
23
+ };
24
+ var worker_k8s_monitor = {
25
+ name: "ghcr.io/highstate-io/highstate/worker.k8s-monitor",
26
+ tag: "debug",
27
+ image: "ghcr.io/highstate-io/highstate/worker.k8s-monitor:debug@sha256:808eccda739d1e963d345a92612f3ca64ecf64de71a6010daa0e1fffbfc7aa5c"
28
+ };
29
+ var alpine = {
30
+ name: "alpine",
31
+ tag: "latest",
32
+ image: "alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659"
33
+ };
34
+ var ubuntu = {
35
+ name: "ubuntu",
36
+ tag: "latest",
37
+ image: "ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103d36e876938d28895b"
38
+ };
39
+ var images_default = {
40
+ "terminal-kubectl": terminal_kubectl,
41
+ "worker.k8s-monitor": worker_k8s_monitor,
42
+ alpine,
43
+ ubuntu
44
+ };
45
+ var providers = /* @__PURE__ */ new Map();
46
+ function getProvider(cluster) {
47
+ const name = `${cluster.name}.${cluster.connectionId}`;
48
+ const existing = providers.get(name);
49
+ if (existing) {
50
+ return existing;
51
+ }
52
+ if (cluster.kubeconfig.content.type !== "embedded-secret") {
53
+ throw new Error("Only embedded secrets are supported for cluster kubeconfig for now");
54
+ }
55
+ const provider = new Provider(name, {
56
+ kubeconfig: secret(cluster.kubeconfig.content.value.value)
57
+ });
58
+ providers.set(name, provider);
59
+ return provider;
60
+ }
61
+ async function getProviderAsync(cluster) {
62
+ const resolvedCluster = await toPromise(cluster);
63
+ return getProvider(resolvedCluster);
64
+ }
65
+ function getEmbeddedSecretFileContent(file) {
66
+ return output(file).apply((file2) => {
67
+ if (file2.content.type !== "embedded-secret") {
68
+ throw new Error("Only embedded-secret file contents are supported for kubeconfig for now");
69
+ }
70
+ return file2.content.value.value;
71
+ });
72
+ }
73
+ function getClusterKubeconfigContent(cluster) {
74
+ return output(cluster).apply((cluster2) => {
75
+ if (cluster2.kubeconfig.content.type !== "embedded-secret") {
76
+ throw new Error(
77
+ "Only embedded-secret file contents are supported for cluster kubeconfig for now"
78
+ );
79
+ }
80
+ return cluster2.kubeconfig.content.value.value;
81
+ });
82
+ }
83
+ var commonExtraArgs = ["name", "namespace", "metadata"];
84
+ function mapMetadata(args, fallbackName) {
85
+ return output(args.metadata).apply(
86
+ (metadata) => output({
87
+ ...metadata,
88
+ name: args.name ?? metadata?.name ?? fallbackName,
89
+ namespace: metadata?.namespace ?? (args.namespace ? output(args.namespace).metadata.name : void 0)
90
+ })
91
+ );
92
+ }
93
+ function mapSelectorLikeToSelector(selector) {
94
+ if ("matchLabels" in selector || "matchExpressions" in selector) {
95
+ return selector;
96
+ }
97
+ return {
98
+ matchLabels: selector
99
+ };
100
+ }
101
+ function getNamespaceName(namespace) {
102
+ if (Namespace.isInstance(namespace)) {
103
+ return namespace.metadata.name;
104
+ }
105
+ if (core.v1.Namespace.isInstance(namespace)) {
106
+ return namespace.metadata.name;
107
+ }
108
+ return output(namespace);
109
+ }
110
+ function mapNamespaceNameToSelector(namespace) {
111
+ return {
112
+ matchLabels: {
113
+ "kubernetes.io/metadata.name": namespace
114
+ }
115
+ };
116
+ }
117
+ function validateCluster(entity, cluster) {
118
+ return output({ entity, cluster }).apply(({ entity: entity2, cluster: cluster2 }) => {
119
+ if (entity2.clusterId !== cluster2.id) {
120
+ throw new Error(
121
+ `Cluster mismatch for ${entity2.kind} "${entity2.metadata.name}": "${entity2.clusterId}" != "${cluster2.id}"`
122
+ );
123
+ }
124
+ return cluster2;
125
+ });
126
+ }
127
+ var Resource = class extends ComponentResource {
128
+ constructor(type, name, args, opts, cluster, metadata) {
129
+ super(type, name, args, opts);
130
+ this.cluster = cluster;
131
+ this.metadata = metadata;
132
+ }
133
+ /**
134
+ * The Kubernetes API version (e.g., "v1", "apps/v1", "batch/v1").
135
+ */
136
+ static apiVersion;
137
+ /**
138
+ * The Kubernetes kind (e.g., "ConfigMap", "Deployment", "CronJob").
139
+ */
140
+ static kind;
141
+ /**
142
+ * Whether the resource is namespaced.
143
+ */
144
+ static isNamespaced = false;
145
+ /**
146
+ * The Kubernetes API version (e.g., "v1", "apps/v1", "batch/v1").
147
+ */
148
+ get apiVersion() {
149
+ return this.constructor.apiVersion;
150
+ }
151
+ /**
152
+ * The Kubernetes kind (e.g., "ConfigMap", "Deployment", "CronJob").
153
+ */
154
+ get kind() {
155
+ return this.constructor.kind;
156
+ }
157
+ get isNamespaced() {
158
+ return this.constructor.isNamespaced;
159
+ }
160
+ get entityBase() {
161
+ return {
162
+ clusterId: this.cluster.id,
163
+ clusterName: this.cluster.name,
164
+ apiVersion: this.apiVersion,
165
+ kind: this.kind,
166
+ isNamespaced: false,
167
+ metadata: this.metadata
168
+ };
169
+ }
170
+ };
171
+ var NamespacedResource = class extends Resource {
172
+ constructor(type, name, args, opts, metadata, namespace) {
173
+ super(type, name, args, opts, namespace.cluster, metadata);
174
+ this.namespace = namespace;
175
+ }
176
+ static isNamespaced = true;
177
+ get entityBase() {
178
+ return {
179
+ clusterId: this.cluster.id,
180
+ clusterName: this.cluster.name,
181
+ apiVersion: this.apiVersion,
182
+ kind: this.kind,
183
+ isNamespaced: true,
184
+ metadata: this.metadata
185
+ };
186
+ }
187
+ };
188
+
189
+ // src/rbac.ts
190
+ var ClusterAccessScope = class extends ComponentResource {
191
+ /**
192
+ * The cluster entity with the reduced access.
193
+ */
194
+ cluster;
195
+ constructor(name, args, opts) {
196
+ super("highstate:k8s:ClusterAccessScope", name, args, opts);
197
+ const { serviceAccount, kubeconfig } = output(args.namespace).cluster.apply((cluster) => {
198
+ const provider = getProvider(cluster);
199
+ const namespaceName = output(args.namespace).metadata.name;
200
+ const serviceAccount2 = new core.v1.ServiceAccount(
201
+ name,
202
+ {
203
+ metadata: {
204
+ name,
205
+ namespace: namespaceName
206
+ }
207
+ },
208
+ { provider }
209
+ );
210
+ const clusterRole = new rbac.v1.ClusterRole(
211
+ name,
212
+ {
213
+ metadata: {
214
+ name: interpolate`hs.${namespaceName}.${name}`,
215
+ annotations: {
216
+ "kubernetes.io/description": interpolate`Created by Highstate for the ServiceAccount "${name}" in the namespace "${namespaceName}".`
217
+ }
218
+ },
219
+ rules: output({
220
+ rules: normalizeInputs(args.rule, args.rules),
221
+ resources: args.resources ?? []
222
+ }).apply(({ rules, resources }) => mergeResources(rules, resources))
223
+ },
224
+ { provider }
225
+ );
226
+ const createRoleBinding = (namespace) => {
227
+ return new rbac.v1.RoleBinding(
228
+ name,
229
+ {
230
+ metadata: { name, namespace },
231
+ roleRef: {
232
+ kind: "ClusterRole",
233
+ name: clusterRole.metadata.name,
234
+ apiGroup: "rbac.authorization.k8s.io"
235
+ },
236
+ subjects: [
237
+ {
238
+ kind: "ServiceAccount",
239
+ name: serviceAccount2.metadata.name,
240
+ namespace: namespaceName
241
+ }
242
+ ]
243
+ },
244
+ { provider }
245
+ );
246
+ };
247
+ if (args.clusterWide) {
248
+ new rbac.v1.ClusterRoleBinding(
249
+ name,
250
+ {
251
+ metadata: { name },
252
+ roleRef: {
253
+ kind: "ClusterRole",
254
+ name: clusterRole.metadata.name,
255
+ apiGroup: "rbac.authorization.k8s.io"
256
+ },
257
+ subjects: [
258
+ {
259
+ kind: "ServiceAccount",
260
+ name: serviceAccount2.metadata.name,
261
+ namespace: namespaceName
262
+ }
263
+ ]
264
+ },
265
+ { provider }
266
+ );
267
+ } else {
268
+ if (args.allowOriginNamespace !== false) {
269
+ createRoleBinding(namespaceName);
270
+ }
271
+ output(args.extraNamespaces ?? []).apply(map(getNamespaceName)).apply(map(createRoleBinding));
272
+ }
273
+ return { serviceAccount: serviceAccount2, kubeconfig: cluster.kubeconfig };
274
+ });
275
+ const accessTokenSecret = Secret.create(`${name}-token`, {
276
+ namespace: args.namespace,
277
+ type: "kubernetes.io/service-account-token",
278
+ metadata: {
279
+ annotations: {
280
+ "kubernetes.io/service-account.name": serviceAccount.metadata.name
281
+ }
282
+ }
283
+ });
284
+ this.cluster = output({
285
+ cluster: output(args.namespace).cluster,
286
+ kubeconfig,
287
+ newToken: accessTokenSecret.getValue("token"),
288
+ serviceAccount: serviceAccount.metadata.name,
289
+ serviceAccountId: serviceAccount.metadata.uid
290
+ }).apply(({ cluster, kubeconfig: kubeconfig2, newToken, serviceAccount: serviceAccount2, serviceAccountId }) => {
291
+ if (kubeconfig2.content.type !== "embedded-secret") {
292
+ throw new Error("Only embedded secrets are supported for cluster kubeconfig for now");
293
+ }
294
+ const config = new KubeConfig();
295
+ config.loadFromString(kubeconfig2.content.value.value);
296
+ config.users = [];
297
+ config.contexts = [];
298
+ config.addUser({ name: serviceAccount2, token: newToken });
299
+ config.addContext({
300
+ name: config.clusters[0].name,
301
+ cluster: config.clusters[0].name,
302
+ user: serviceAccount2
303
+ });
304
+ config.setCurrentContext(config.clusters[0].name);
305
+ return {
306
+ ...cluster,
307
+ connectionId: serviceAccountId,
308
+ kubeconfig: makeEntity({
309
+ entity: common.fileEntity,
310
+ identity: `${serviceAccountId}:kubeconfig`,
311
+ meta: {
312
+ title: `kubeconfig for SA ${serviceAccount2}`
313
+ },
314
+ value: {
315
+ content: {
316
+ type: "embedded-secret",
317
+ value: config.exportConfig()
318
+ },
319
+ meta: {
320
+ name: "kubeconfig",
321
+ contentType: "text/yaml",
322
+ mode: 384
323
+ }
324
+ }
325
+ })
326
+ };
327
+ });
328
+ }
329
+ };
330
+ async function mergeResources(rules, resources) {
331
+ for (const resource of resources) {
332
+ const entity = await toPromise(
333
+ resource instanceof NamespacedResource ? resource.entity : resource
334
+ );
335
+ const apiGroup = entity.apiVersion.includes("/") ? entity.apiVersion.split("/")[0] : "";
336
+ const resourceCollection = `${entity.kind.toLowerCase()}s`;
337
+ const matchingRule = rules.find((rule) => {
338
+ const apiGroupsMatch = rule.apiGroups?.length === 1 && rule.apiGroups[0] === apiGroup;
339
+ const resourcesMatch = rule.resources?.length === 1 && rule.resources[0] === resourceCollection;
340
+ return apiGroupsMatch && resourcesMatch;
341
+ });
342
+ if (!matchingRule) {
343
+ continue;
344
+ }
345
+ matchingRule.resourceNames = await toPromise(
346
+ unique([
347
+ //
348
+ ...matchingRule.resourceNames ?? [],
349
+ entity.metadata.name
350
+ ])
351
+ );
352
+ }
353
+ return rules;
354
+ }
355
+
356
+ // src/namespace.ts
357
+ var Namespace = class _Namespace extends Resource {
358
+ constructor(type, name, args, opts, cluster, metadata, spec, status) {
359
+ super(type, name, args, opts, cluster, metadata);
360
+ this.spec = spec;
361
+ this.status = status;
362
+ }
363
+ static apiVersion = "v1";
364
+ static kind = "Namespace";
365
+ /**
366
+ * The cluster entity authorized to port-forward into the namespace.
367
+ *
368
+ * Only created for namespaces created with `create` or `createOrGet` methods, not for wrapped or external namespaces.
369
+ */
370
+ portForwardCluster;
371
+ /**
372
+ * The Highstate namespace entity.
373
+ */
374
+ get entity() {
375
+ return makeEntityOutput({
376
+ entity: k8s.namespaceEntity,
377
+ identity: this.metadata.uid,
378
+ meta: {
379
+ title: this.metadata.name
380
+ },
381
+ value: {
382
+ ...this.entityBase
383
+ }
384
+ });
385
+ }
386
+ /**
387
+ * Creates a new namespace.
388
+ */
389
+ static create(name, args, opts) {
390
+ return new CreatedNamespace(name, args, opts);
391
+ }
392
+ /**
393
+ * Wraps an existing Kubernetes namespace.
394
+ */
395
+ static wrap(name, args, opts) {
396
+ return new WrappedNamespace(name, args, opts);
397
+ }
398
+ /**
399
+ * Creates a new namespace or gets an existing one.
400
+ *
401
+ * @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.
402
+ * @param args The arguments to create or get the namespace with.
403
+ * @param opts Optional resource options.
404
+ */
405
+ static async createOrGet(name, args, opts) {
406
+ if (args.resource) {
407
+ return await _Namespace.forResourceAsync(args.resource, args.cluster);
408
+ }
409
+ if (args.existing) {
410
+ return await _Namespace.forAsync(args.existing, args.cluster);
411
+ }
412
+ return new CreatedNamespace(name, args, opts);
413
+ }
414
+ /**
415
+ * Creates a new namespace or patches an existing one.
416
+ *
417
+ * @param name The name of the resource. May not be the same as the namespace name.
418
+ * @param args The arguments to create or patch the namespace with.
419
+ * @param opts Optional resource options.
420
+ */
421
+ static createOrPatch(name, args, opts) {
422
+ if (args.resource) {
423
+ return new NamespacePatch(name, {
424
+ ...args,
425
+ name: output$1(args.resource).metadata.namespace,
426
+ cluster: validateCluster(args.resource, args.cluster)
427
+ });
428
+ }
429
+ if (args.existing) {
430
+ return new NamespacePatch(name, {
431
+ ...args,
432
+ name: output$1(args.existing).metadata.name,
433
+ cluster: validateCluster(args.existing, args.cluster)
434
+ });
435
+ }
436
+ return new CreatedNamespace(name, args, opts);
437
+ }
438
+ /**
439
+ * Patches an existing namespace.
440
+ *
441
+ * Will throw an error if the namespace does not exist.
442
+ *
443
+ * @param name The name of the resource. May not be the same as the namespace name.
444
+ * @param args The arguments to patch the namespace with.
445
+ * @param opts Optional resource options.
446
+ */
447
+ static patch(name, args, opts) {
448
+ return new NamespacePatch(name, args, opts);
449
+ }
450
+ /**
451
+ * Gets an existing namespace.
452
+ *
453
+ * Will throw an error if the namespace does not exist.
454
+ *
455
+ * @param name The name of the resource. May not be the same as the namespace name.
456
+ * @param args The arguments to get the namespace with.
457
+ * @param opts Optional resource options.
458
+ */
459
+ static get(name, args, opts) {
460
+ return new ExternalNamespace(name, args, opts);
461
+ }
462
+ static namespaceCache = /* @__PURE__ */ new Map();
463
+ /**
464
+ * Gets an existing namespace for a given entity.
465
+ * Prefer this method over `get` when possible.
466
+ *
467
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{clusterId}`.
468
+ *
469
+ * This method it idempotent and will return the same instance for the same entity.
470
+ *
471
+ * @param entity The entity to get the namespace for.
472
+ * @param cluster The cluster where the namespace is located.
473
+ */
474
+ static for(entity, cluster) {
475
+ return getOrCreate(
476
+ _Namespace.namespaceCache,
477
+ `${entity.clusterName}.${entity.metadata.name}.${entity.clusterId}`,
478
+ (name) => {
479
+ return _Namespace.get(name, {
480
+ name: entity.metadata.name,
481
+ cluster: validateCluster(entity, cluster)
482
+ });
483
+ }
484
+ );
485
+ }
486
+ /**
487
+ * Gets an existing namespace for a given entity.
488
+ * Prefer this method over `get` when possible.
489
+ *
490
+ * @param entity The entity to get the namespace for.
491
+ * @param cluster The cluster where the namespace is located.
492
+ */
493
+ static async forAsync(entity, cluster) {
494
+ const resolvedEntity = await toPromise(entity);
495
+ return _Namespace.for(resolvedEntity, cluster);
496
+ }
497
+ /**
498
+ * Gets an existing namespace where the provided resource is located.
499
+ * Prefer this method over `get` when possible.
500
+ *
501
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{clusterId}`.
502
+ *
503
+ * This method it idempotent and will return the same instance for the same resource.
504
+ *
505
+ * @param resource The resource to get the namespace for.
506
+ * @param cluster The cluster where the namespace is located.
507
+ */
508
+ static forResource(resource, cluster) {
509
+ return getOrCreate(
510
+ _Namespace.namespaceCache,
511
+ `${resource.clusterName}.${resource.metadata.namespace}.${resource.clusterId}`,
512
+ (name) => {
513
+ return _Namespace.get(name, {
514
+ name: resource.metadata.namespace,
515
+ cluster: validateCluster(resource, cluster)
516
+ });
517
+ }
518
+ );
519
+ }
520
+ /**
521
+ * Gets an existing namespace for a given entity.
522
+ * Prefer this method over `get` when possible.
523
+ *
524
+ * @param resource The resource to get the namespace for.
525
+ * @param cluster The cluster where the namespace is located.
526
+ */
527
+ static async forResourceAsync(resource, cluster) {
528
+ const resolvedResource = await toPromise(resource);
529
+ return _Namespace.forResource(resolvedResource, cluster);
530
+ }
531
+ };
532
+ function mapNamespaceMetadata(args, fallbackName) {
533
+ return mapMetadata(args, fallbackName).apply((metadata) => {
534
+ if (args.privileged) {
535
+ metadata.labels = {
536
+ ...metadata.labels,
537
+ "pod-security.kubernetes.io/enforce": "privileged"
538
+ };
539
+ }
540
+ return metadata;
541
+ });
542
+ }
543
+ var CreatedNamespace = class extends Namespace {
544
+ constructor(name, args, opts) {
545
+ const namespace = output$1(args.cluster).apply((cluster) => {
546
+ return new core.v1.Namespace(
547
+ name,
548
+ { metadata: mapNamespaceMetadata(args, name) },
549
+ { ...opts, parent: this, provider: getProvider(cluster) }
550
+ );
551
+ });
552
+ super(
553
+ "highstate:k8s:Namespace",
554
+ name,
555
+ args,
556
+ opts,
557
+ output$1(args.cluster),
558
+ namespace.metadata,
559
+ namespace.spec,
560
+ namespace.status
561
+ );
562
+ const scope = new ClusterAccessScope(
563
+ `${name}-port-forward`,
564
+ {
565
+ namespace: this,
566
+ rules: [
567
+ {
568
+ apiGroups: [""],
569
+ resources: ["services"],
570
+ verbs: ["get"]
571
+ },
572
+ {
573
+ apiGroups: [""],
574
+ resources: ["pods"],
575
+ verbs: ["get", "list"]
576
+ },
577
+ {
578
+ apiGroups: [""],
579
+ resources: ["pods/portforward"],
580
+ verbs: ["create"]
581
+ }
582
+ ]
583
+ },
584
+ { parent: this }
585
+ );
586
+ this.portForwardCluster = scope.cluster;
587
+ }
588
+ };
589
+ var NamespacePatch = class extends Namespace {
590
+ constructor(name, args, opts) {
591
+ const namespace = output$1(args.cluster).apply((cluster) => {
592
+ return new core.v1.NamespacePatch(
593
+ name,
594
+ { metadata: mapNamespaceMetadata(args, name) },
595
+ { ...opts, parent: this, provider: getProvider(cluster) }
596
+ );
597
+ });
598
+ super(
599
+ "highstate:k8s:NamespacePatch",
600
+ name,
601
+ args,
602
+ opts,
603
+ output$1(args.cluster),
604
+ namespace.metadata,
605
+ namespace.spec,
606
+ namespace.status
607
+ );
608
+ }
609
+ };
610
+ var ExternalNamespace = class extends Namespace {
611
+ constructor(name, args, opts) {
612
+ const namespace = output$1(args.cluster).apply((cluster) => {
613
+ return core.v1.Namespace.get(name, args.name, {
614
+ ...opts,
615
+ parent: this,
616
+ provider: getProvider(cluster)
617
+ });
618
+ });
619
+ super(
620
+ "highstate:k8s:ExternalNamespace",
621
+ name,
622
+ args,
623
+ opts,
624
+ output$1(args.cluster),
625
+ namespace.metadata,
626
+ namespace.spec,
627
+ namespace.status
628
+ );
629
+ }
630
+ };
631
+ var WrappedNamespace = class extends Namespace {
632
+ constructor(name, args, opts) {
633
+ super(
634
+ "highstate:k8s:WrappedNamespace",
635
+ name,
636
+ args,
637
+ opts,
638
+ output$1(args.cluster),
639
+ output$1(args.namespace).metadata,
640
+ output$1(args.namespace).spec,
641
+ output$1(args.namespace).status
642
+ );
643
+ }
644
+ };
645
+
646
+ // src/secret.ts
647
+ var Secret = class _Secret extends NamespacedResource {
648
+ constructor(type, name, args, opts, metadata, namespace, data, stringData) {
649
+ super(type, name, args, opts, metadata, namespace);
650
+ this.data = data;
651
+ this.stringData = stringData;
652
+ }
653
+ static apiVersion = "v1";
654
+ static kind = "Secret";
655
+ /**
656
+ * The Highstate secret entity.
657
+ */
658
+ get entity() {
659
+ return makeEntityOutput({
660
+ entity: k8s.secretEntity,
661
+ identity: this.metadata.uid,
662
+ meta: {
663
+ title: this.metadata.name
664
+ },
665
+ value: {
666
+ ...this.entityBase
667
+ }
668
+ });
669
+ }
670
+ /**
671
+ * Gets the value of the secret field by the given key in `data`.
672
+ *
673
+ * Automatically decodes the base64 value.
674
+ *
675
+ * @param key The key of the secret.
676
+ * @returns The value of the secret.
677
+ */
678
+ getValue(key) {
679
+ return this.data[key].apply((value) => Buffer.from(value, "base64").toString());
680
+ }
681
+ /**
682
+ * Creates a new secret.
683
+ */
684
+ static create(name, args, opts) {
685
+ return new CreatedSecret(name, args, opts);
686
+ }
687
+ /**
688
+ * Creates a new secret or patches an existing one.
689
+ *
690
+ * @param name The name of the resource. May not be the same as the secret name.
691
+ * @param args The arguments to create or patch the secret with.
692
+ * @param opts Optional resource options.
693
+ */
694
+ static createOrPatch(name, args, opts) {
695
+ if (args.existing) {
696
+ return new SecretPatch(name, {
697
+ ...args,
698
+ name: output(args.existing).metadata.name
699
+ });
700
+ }
701
+ return new CreatedSecret(name, args, opts);
702
+ }
703
+ /**
704
+ * Creates a new secret or gets an existing one.
705
+ *
706
+ * @param name The name of the resource. May not be the same as the secret name. Will not be used when existing secret is retrieved.
707
+ * @param args The arguments to create or get the secret with.
708
+ * @param opts Optional resource options.
709
+ */
710
+ static async createOrGet(name, args, opts) {
711
+ if (args.existing) {
712
+ return await _Secret.forAsync(args.existing, output(args.namespace).cluster);
713
+ }
714
+ return new CreatedSecret(name, args, opts);
715
+ }
716
+ /**
717
+ * Patches an existing secret.
718
+ *
719
+ * Will throw an error if the secret does not exist.
720
+ *
721
+ * @param name The name of the resource. May not be the same as the secret name.
722
+ * @param args The arguments to patch the secret with.
723
+ * @param opts Optional resource options.
724
+ */
725
+ static patch(name, args, opts) {
726
+ return new SecretPatch(name, args, opts);
727
+ }
728
+ /**
729
+ * Wraps an existing Kubernetes secret.
730
+ */
731
+ static wrap(name, args, opts) {
732
+ return new WrappedSecret(name, args, opts);
733
+ }
734
+ /**
735
+ * Gets an existing secret.
736
+ *
737
+ * Will throw an error if the secret does not exist.
738
+ */
739
+ static get(name, args, opts) {
740
+ return new ExternalSecret(name, args, opts);
741
+ }
742
+ static secretCache = /* @__PURE__ */ new Map();
743
+ /**
744
+ * Gets an existing secret for a given entity.
745
+ * Prefer this method over `get` when possible.
746
+ *
747
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
748
+ *
749
+ * This method is idempotent and will return the same instance for the same entity.
750
+ *
751
+ * @param entity The entity to get the secret for.
752
+ * @param cluster The cluster where the secret is located.
753
+ */
754
+ static for(entity, cluster) {
755
+ return getOrCreate(
756
+ _Secret.secretCache,
757
+ `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
758
+ (name) => {
759
+ return _Secret.get(name, {
760
+ name: entity.metadata.name,
761
+ namespace: Namespace.forResource(entity, cluster)
762
+ });
763
+ }
764
+ );
765
+ }
766
+ /**
767
+ * Gets an existing secret for a given entity.
768
+ * Prefer this method over `get` when possible.
769
+ *
770
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
771
+ *
772
+ * This method is idempotent and will return the same instance for the same entity.
773
+ *
774
+ * @param entity The entity to get the secret for.
775
+ * @param cluster The cluster where the secret is located.
776
+ */
777
+ static async forAsync(entity, cluster) {
778
+ const resolvedEntity = await toPromise(entity);
779
+ return _Secret.for(resolvedEntity, cluster);
780
+ }
781
+ };
782
+ var CreatedSecret = class extends Secret {
783
+ constructor(name, args, opts) {
784
+ const secret2 = output(args.namespace).cluster.apply((cluster) => {
785
+ return new core.v1.Secret(
786
+ name,
787
+ {
788
+ metadata: mapMetadata(args, name),
789
+ data: args.data,
790
+ stringData: args.stringData,
791
+ type: args.type,
792
+ immutable: args.immutable
793
+ },
794
+ {
795
+ ...opts,
796
+ parent: this,
797
+ provider: getProvider(cluster)
798
+ }
799
+ );
800
+ });
801
+ super(
802
+ "highstate:k8s:Secret",
803
+ name,
804
+ args,
805
+ opts,
806
+ secret2.metadata,
807
+ output(args.namespace),
808
+ secret2.data,
809
+ secret2.stringData
810
+ );
811
+ }
812
+ };
813
+ var SecretPatch = class extends Secret {
814
+ constructor(name, args, opts) {
815
+ const secret2 = output(args.namespace).cluster.apply((cluster) => {
816
+ return new core.v1.SecretPatch(
817
+ name,
818
+ {
819
+ metadata: mapMetadata(args, name),
820
+ data: args.data,
821
+ stringData: args.stringData,
822
+ type: args.type,
823
+ immutable: args.immutable
824
+ },
825
+ {
826
+ ...opts,
827
+ parent: this,
828
+ provider: getProvider(cluster)
829
+ }
830
+ );
831
+ });
832
+ super(
833
+ "highstate:k8s:SecretPatch",
834
+ name,
835
+ args,
836
+ opts,
837
+ secret2.metadata,
838
+ output(args.namespace),
839
+ secret2.data,
840
+ secret2.stringData
841
+ );
842
+ }
843
+ };
844
+ var WrappedSecret = class extends Secret {
845
+ constructor(name, args, opts) {
846
+ super(
847
+ "highstate:k8s:WrappedSecret",
848
+ name,
849
+ args,
850
+ opts,
851
+ output(args.secret).metadata,
852
+ output(args.namespace),
853
+ output(args.secret).data,
854
+ output(args.secret).stringData
855
+ );
856
+ }
857
+ };
858
+ var ExternalSecret = class extends Secret {
859
+ constructor(name, args, opts) {
860
+ const secret2 = output(args.namespace).cluster.apply(async (cluster) => {
861
+ const secret3 = core.v1.Secret.get(
862
+ name,
863
+ interpolate`${output(args.namespace).metadata.name}/${args.name}`,
864
+ { ...opts, parent: this, provider: getProvider(cluster) }
865
+ );
866
+ const namespace = await toPromise(output(args.namespace).metadata.name);
867
+ const resolvedName = await toPromise(args.name);
868
+ const metadata = await toPromise(secret3.metadata);
869
+ if (!metadata) {
870
+ throw new Error(`Secret ${resolvedName} in namespace ${namespace} not found`);
871
+ }
872
+ return secret3;
873
+ });
874
+ super(
875
+ "highstate:k8s:ExternalSecret",
876
+ name,
877
+ args,
878
+ opts,
879
+ secret2.metadata,
880
+ output(args.namespace),
881
+ secret2.data,
882
+ secret2.stringData
883
+ );
884
+ }
885
+ };
886
+
887
+ export { ClusterAccessScope, Namespace, NamespacedResource, Resource, Secret, commonExtraArgs, getClusterKubeconfigContent, getEmbeddedSecretFileContent, getNamespaceName, getProvider, getProviderAsync, images_exports, mapMetadata, mapNamespaceNameToSelector, mapSelectorLikeToSelector, validateCluster };
888
+ //# sourceMappingURL=chunk-TOLFVF4S.js.map
889
+ //# sourceMappingURL=chunk-TOLFVF4S.js.map