@highstate/k8s 0.15.0 → 0.16.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 (96) hide show
  1. package/dist/chunk-22GOWZQP.js +286 -0
  2. package/dist/chunk-22GOWZQP.js.map +1 -0
  3. package/dist/{chunk-VJL2BFKO.js → chunk-4G6LLC2X.js} +13 -24
  4. package/dist/chunk-4G6LLC2X.js.map +1 -0
  5. package/dist/{chunk-C6WHUOC3.js → chunk-BR2CLUUD.js} +15 -26
  6. package/dist/chunk-BR2CLUUD.js.map +1 -0
  7. package/dist/{chunk-EACAK6W4.js → chunk-DCUMJSO6.js} +17 -28
  8. package/dist/chunk-DCUMJSO6.js.map +1 -0
  9. package/dist/{chunk-NWXKLVBC.js → chunk-HJKJHTJM.js} +20 -30
  10. package/dist/chunk-HJKJHTJM.js.map +1 -0
  11. package/dist/{chunk-7H4L3DFC.js → chunk-KMLRI5UZ.js} +57 -70
  12. package/dist/chunk-KMLRI5UZ.js.map +1 -0
  13. package/dist/{chunk-6ACIPGW4.js → chunk-LGHFSXNT.js} +12 -13
  14. package/dist/chunk-LGHFSXNT.js.map +1 -0
  15. package/dist/{chunk-SEWB4FUB.js → chunk-OBDQONMV.js} +64 -23
  16. package/dist/chunk-OBDQONMV.js.map +1 -0
  17. package/dist/chunk-SL5CBM3A.js +301 -0
  18. package/dist/chunk-SL5CBM3A.js.map +1 -0
  19. package/dist/{chunk-3CKMDTYK.js → chunk-TWBMG6TD.js} +68 -91
  20. package/dist/chunk-TWBMG6TD.js.map +1 -0
  21. package/dist/{chunk-YTRQ6JRU.js → chunk-XRIC6EJ3.js} +159 -94
  22. package/dist/chunk-XRIC6EJ3.js.map +1 -0
  23. package/dist/{chunk-O64YZLA4.js → chunk-ZBFWQHE4.js} +21 -30
  24. package/dist/chunk-ZBFWQHE4.js.map +1 -0
  25. package/dist/{chunk-4VGISFL4.js → chunk-ZHVKK2U6.js} +12 -11
  26. package/dist/chunk-ZHVKK2U6.js.map +1 -0
  27. package/dist/cron-job-LX35I6HG.js +8 -0
  28. package/dist/cron-job-LX35I6HG.js.map +1 -0
  29. package/dist/deployment-HRJGAEJR.js +8 -0
  30. package/dist/{deployment-THUD5QUH.js.map → deployment-HRJGAEJR.js.map} +1 -1
  31. package/dist/highstate.manifest.json +2 -3
  32. package/dist/impl/gateway-route.js +10 -10
  33. package/dist/impl/gateway-route.js.map +1 -1
  34. package/dist/impl/tls-certificate.js +3 -3
  35. package/dist/index.js +39 -627
  36. package/dist/index.js.map +1 -1
  37. package/dist/job-J4BKBVQD.js +8 -0
  38. package/dist/job-J4BKBVQD.js.map +1 -0
  39. package/dist/stateful-set-LAJR5RL4.js +8 -0
  40. package/dist/{stateful-set-ABCZML4L.js.map → stateful-set-LAJR5RL4.js.map} +1 -1
  41. package/dist/units/cert-manager/index.js +7 -7
  42. package/dist/units/cluster-patch/index.js +9 -18
  43. package/dist/units/cluster-patch/index.js.map +1 -1
  44. package/dist/units/dns01-issuer/index.js +6 -6
  45. package/dist/units/dns01-issuer/index.js.map +1 -1
  46. package/dist/units/existing-cluster/index.js +19 -9
  47. package/dist/units/existing-cluster/index.js.map +1 -1
  48. package/dist/units/gateway-api/index.js +2 -2
  49. package/dist/units/gateway-api/index.js.map +1 -1
  50. package/dist/units/reduced-access-cluster/index.js +18 -25
  51. package/dist/units/reduced-access-cluster/index.js.map +1 -1
  52. package/package.json +6 -11
  53. package/src/cluster.ts +14 -14
  54. package/src/config-map.ts +16 -30
  55. package/src/container.ts +1 -1
  56. package/src/cron-job.ts +23 -41
  57. package/src/deployment.ts +23 -30
  58. package/src/gateway/gateway.ts +21 -29
  59. package/src/helm.ts +7 -8
  60. package/src/impl/gateway-route.ts +5 -13
  61. package/src/job.ts +20 -38
  62. package/src/namespace.ts +18 -22
  63. package/src/network-policy.ts +37 -36
  64. package/src/network.ts +18 -10
  65. package/src/pvc.ts +12 -28
  66. package/src/rbac.ts +75 -97
  67. package/src/scripting/bundle.ts +3 -3
  68. package/src/scripting/environment.ts +3 -3
  69. package/src/secret.ts +16 -30
  70. package/src/service.ts +86 -105
  71. package/src/shared.ts +82 -20
  72. package/src/stateful-set.ts +17 -28
  73. package/src/tls.ts +20 -31
  74. package/src/units/cluster-patch/index.ts +9 -19
  75. package/src/units/dns01-issuer/index.ts +6 -6
  76. package/src/units/existing-cluster/index.ts +28 -10
  77. package/src/units/gateway-api/index.ts +1 -1
  78. package/src/units/reduced-access-cluster/index.ts +16 -24
  79. package/src/worker.ts +7 -5
  80. package/src/workload.ts +172 -28
  81. package/dist/chunk-3CKMDTYK.js.map +0 -1
  82. package/dist/chunk-4VGISFL4.js.map +0 -1
  83. package/dist/chunk-6ACIPGW4.js.map +0 -1
  84. package/dist/chunk-7H4L3DFC.js.map +0 -1
  85. package/dist/chunk-C6WHUOC3.js.map +0 -1
  86. package/dist/chunk-EACAK6W4.js.map +0 -1
  87. package/dist/chunk-NWXKLVBC.js.map +0 -1
  88. package/dist/chunk-O64YZLA4.js.map +0 -1
  89. package/dist/chunk-SEWB4FUB.js.map +0 -1
  90. package/dist/chunk-VJL2BFKO.js.map +0 -1
  91. package/dist/chunk-YTRQ6JRU.js.map +0 -1
  92. package/dist/deployment-THUD5QUH.js +0 -8
  93. package/dist/stateful-set-ABCZML4L.js +0 -8
  94. package/dist/units/cluster-dns/index.js +0 -37
  95. package/dist/units/cluster-dns/index.js.map +0 -1
  96. package/src/units/cluster-dns/index.ts +0 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/k8s",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -20,10 +20,6 @@
20
20
  "mode": "manual",
21
21
  "version": "1"
22
22
  },
23
- "./units/cluster-dns": {
24
- "mode": "manual",
25
- "version": "1"
26
- },
27
23
  "./units/dns01-issuer": {
28
24
  "mode": "manual",
29
25
  "version": "1"
@@ -49,7 +45,6 @@
49
45
  },
50
46
  "./units/cert-manager": "./dist/units/cert-manager/index.js",
51
47
  "./units/cluster-patch": "./dist/units/cluster-patch/index.js",
52
- "./units/cluster-dns": "./dist/units/cluster-dns/index.js",
53
48
  "./units/dns01-issuer": "./dist/units/dns01-issuer/index.js",
54
49
  "./units/existing-cluster": "./dist/units/existing-cluster/index.js",
55
50
  "./units/gateway-api": "./dist/units/gateway-api/index.js",
@@ -77,18 +72,18 @@
77
72
  "pkg-types": "^2.1.0",
78
73
  "remeda": "^2.21.0",
79
74
  "yaml": "^2.8.1",
80
- "@highstate/contract": "0.16.0",
81
- "@highstate/common": "0.15.0",
82
75
  "@highstate/cert-manager": "0.14.0",
76
+ "@highstate/common": "0.16.0",
77
+ "@highstate/contract": "0.17.0",
83
78
  "@highstate/gateway-api": "0.14.0",
84
- "@highstate/library": "0.15.0",
85
- "@highstate/pulumi": "0.16.0"
79
+ "@highstate/library": "0.16.0",
80
+ "@highstate/pulumi": "0.17.0"
86
81
  },
87
82
  "devDependencies": {
88
83
  "@biomejs/biome": "2.2.0",
89
84
  "@typescript/native-preview": "^7.0.0-dev.20250920.1",
90
85
  "type-fest": "^4.41.0",
91
- "@highstate/cli": "0.16.0"
86
+ "@highstate/cli": "0.17.0"
92
87
  },
93
88
  "repository": {
94
89
  "url": "https://github.com/highstate-io/highstate"
package/src/cluster.ts CHANGED
@@ -1,38 +1,38 @@
1
- import type { k8s } from "@highstate/library"
1
+ import type { k8s, network } from "@highstate/library"
2
+ import { isPrivateAddress, parseAddress } from "@highstate/common"
2
3
  import { text, type UnitTerminal } from "@highstate/contract"
3
4
  import { fileFromString, type Input, type Output, output } from "@highstate/pulumi"
4
5
  import { CoreV1Api, type KubeConfig } from "@kubernetes/client-node"
5
6
  import { images } from "./shared"
6
7
 
7
- function isPrivateIp(ip: string) {
8
- const privateIpRegex = /^(10|172\.16|192\.168)\./
9
- return privateIpRegex.test(ip)
10
- }
11
-
12
8
  export async function detectExternalIps(
13
9
  kubeConfig: KubeConfig,
14
10
  internalIpsPolicy: k8s.InternalIpsPolicy,
15
- ): Promise<string[]> {
11
+ ): Promise<network.Address[]> {
16
12
  const nodeApi = kubeConfig.makeApiClient(CoreV1Api)
17
13
  const nodes = await nodeApi.listNode()
18
14
 
19
15
  return nodes.items.flatMap(node => {
20
16
  const addresses = node.status?.addresses ?? []
17
+
21
18
  const externalIp = addresses.find(address => address.type === "ExternalIP")
22
19
  const internalIp = addresses.find(address => address.type === "InternalIP")
23
20
 
24
- const result: string[] = []
21
+ const externalAddress = externalIp ? parseAddress(externalIp.address) : undefined
22
+ const internalAddress = internalIp ? parseAddress(internalIp.address) : undefined
23
+
24
+ const result: network.Address[] = []
25
25
 
26
- if (externalIp?.address) {
27
- result.push(externalIp.address)
26
+ if (externalAddress) {
27
+ result.push(externalAddress)
28
28
  }
29
29
 
30
- if (internalIp?.address && internalIpsPolicy === "always") {
31
- result.push(internalIp.address)
30
+ if (internalAddress && internalIpsPolicy === "always") {
31
+ result.push(internalAddress)
32
32
  }
33
33
 
34
- if (internalIp?.address && internalIpsPolicy === "public" && !isPrivateIp(internalIp.address)) {
35
- result.push(internalIp.address)
34
+ if (internalAddress && internalIpsPolicy === "public" && !isPrivateAddress(internalAddress)) {
35
+ result.push(internalAddress)
36
36
  }
37
37
 
38
38
  return result
package/src/config-map.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  output,
12
12
  } from "@pulumi/pulumi"
13
13
  import { Namespace } from "./namespace"
14
- import { getProvider, mapMetadata, ScopedResource, type ScopedResourceArgs } from "./shared"
14
+ import { getProvider, mapMetadata, NamespacedResource, type ScopedResourceArgs } from "./shared"
15
15
 
16
16
  export type ConfigMapArgs = ScopedResourceArgs &
17
17
  Omit<types.input.core.v1.ConfigMap, "kind" | "metadata" | "apiVersion">
@@ -20,42 +20,38 @@ export type CreateOrGetConfigMapArgs = ConfigMapArgs & {
20
20
  /**
21
21
  * The config map entity to patch/retrieve.
22
22
  */
23
- existing: Input<k8s.ScopedResource> | undefined
23
+ existing: Input<k8s.NamespacedResource> | undefined
24
24
  }
25
25
 
26
26
  /**
27
27
  * Represents a Kubernetes ConfigMap resource with metadata and data.
28
28
  */
29
- export abstract class ConfigMap extends ScopedResource {
29
+ export abstract class ConfigMap extends NamespacedResource {
30
+ static apiVersion = "v1"
31
+ static kind = "ConfigMap"
32
+
30
33
  protected constructor(
31
34
  type: string,
32
35
  name: string,
33
36
  args: Inputs,
34
37
  opts: ComponentResourceOptions | undefined,
35
38
 
36
- apiVersion: Output<string>,
37
- kind: Output<string>,
38
- namespace: Output<Namespace>,
39
39
  metadata: Output<types.output.meta.v1.ObjectMeta>,
40
+ namespace: Output<Namespace>,
40
41
 
41
42
  /**
42
43
  * The data of the underlying Kubernetes config map.
43
44
  */
44
45
  readonly data: Output<Record<string, string>>,
45
46
  ) {
46
- super(type, name, args, opts, apiVersion, kind, namespace, metadata)
47
+ super(type, name, args, opts, metadata, namespace)
47
48
  }
48
49
 
49
50
  /**
50
51
  * The Highstate config map entity.
51
52
  */
52
- get entity(): Output<k8s.ScopedResource> {
53
- return output({
54
- type: "config-map",
55
- clusterId: this.cluster.id,
56
- clusterName: this.cluster.name,
57
- metadata: this.metadata,
58
- })
53
+ get entity(): Output<k8s.ConfigMap> {
54
+ return output(this.entityBase)
59
55
  }
60
56
 
61
57
  /**
@@ -156,7 +152,7 @@ export abstract class ConfigMap extends ScopedResource {
156
152
  * @param entity The entity to get the config map for.
157
153
  * @param cluster The cluster where the config map is located.
158
154
  */
159
- static for(entity: k8s.ScopedResource, cluster: Input<k8s.Cluster>): ConfigMap {
155
+ static for(entity: k8s.NamespacedResource, cluster: Input<k8s.Cluster>): ConfigMap {
160
156
  return getOrCreate(
161
157
  ConfigMap.configMapCache,
162
158
  `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
@@ -181,7 +177,7 @@ export abstract class ConfigMap extends ScopedResource {
181
177
  * @param cluster The cluster where the config map is located.
182
178
  */
183
179
  static async forAsync(
184
- entity: Input<k8s.ScopedResource>,
180
+ entity: Input<k8s.NamespacedResource>,
185
181
  cluster: Input<k8s.Cluster>,
186
182
  ): Promise<ConfigMap> {
187
183
  const resolvedEntity = await toPromise(entity)
@@ -211,10 +207,8 @@ class CreatedConfigMap extends ConfigMap {
211
207
  name,
212
208
  args,
213
209
  opts,
214
- configMap.apiVersion,
215
- configMap.kind,
216
- output(args.namespace),
217
210
  configMap.metadata,
211
+ output(args.namespace),
218
212
  configMap.data,
219
213
  )
220
214
  }
@@ -242,10 +236,8 @@ class ConfigMapPatch extends ConfigMap {
242
236
  name,
243
237
  args,
244
238
  opts,
245
- configMap.apiVersion,
246
- configMap.kind,
247
- output(args.namespace),
248
239
  configMap.metadata,
240
+ output(args.namespace),
249
241
  configMap.data,
250
242
  )
251
243
  }
@@ -270,11 +262,8 @@ class WrappedConfigMap extends ConfigMap {
270
262
  name,
271
263
  args,
272
264
  opts,
273
-
274
- output(args.configMap).apiVersion,
275
- output(args.configMap).kind,
276
- output(args.namespace),
277
265
  output(args.configMap).metadata,
266
+ output(args.namespace),
278
267
  output(args.configMap).data,
279
268
  )
280
269
  }
@@ -307,11 +296,8 @@ class ExternalConfigMap extends ConfigMap {
307
296
  name,
308
297
  args,
309
298
  opts,
310
-
311
- configMap.apiVersion,
312
- configMap.kind,
313
- output(args.namespace),
314
299
  configMap.metadata,
300
+ output(args.namespace),
315
301
  configMap.data,
316
302
  )
317
303
  }
package/src/container.ts CHANGED
@@ -67,7 +67,7 @@ export type Container = Omit<PartialKeys<types.input.core.v1.Container, "name">,
67
67
  *
68
68
  * This is used to generate a network policy.
69
69
  */
70
- allowedEndpoints?: InputArray<network.L34Endpoint>
70
+ allowedEndpoints?: InputArray<network.L3Endpoint>
71
71
 
72
72
  /**
73
73
  * Enable the TUN device in the container.
package/src/cron-job.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { RequiredKeys, UnitTerminal } from "@highstate/contract"
1
+ import type { UnitTerminal } from "@highstate/contract"
2
2
  import type { k8s } from "@highstate/library"
3
3
  import type { Container } from "./container"
4
4
  import type { NetworkPolicy } from "./network-policy"
@@ -26,7 +26,7 @@ import {
26
26
  } from "./workload"
27
27
 
28
28
  export type CronJobArgs = ScopedResourceArgs &
29
- Omit<RequiredKeys<Partial<types.input.batch.v1.CronJobSpec>, "schedule">, "jobTemplate"> & {
29
+ Omit<Partial<types.input.batch.v1.CronJobSpec>, "jobTemplate"> & {
30
30
  jobTemplate?: {
31
31
  metadata?: types.input.meta.v1.ObjectMeta
32
32
  spec?: Omit<types.input.batch.v1.JobSpec, "template"> & {
@@ -42,25 +42,26 @@ export type CreateOrGetCronJobArgs = CronJobArgs & {
42
42
  /**
43
43
  * The cron job entity to patch/retrieve.
44
44
  */
45
- existing: Input<k8s.ScopedResource> | undefined
45
+ existing: Input<k8s.NamespacedResource> | undefined
46
46
  }
47
47
 
48
48
  /**
49
49
  * Represents a Kubernetes CronJob resource with metadata and spec.
50
50
  */
51
51
  export abstract class CronJob extends Workload {
52
+ static apiVersion = "batch/v1"
53
+ static kind = "CronJob"
54
+
52
55
  protected constructor(
53
56
  type: string,
54
57
  name: string,
55
58
  args: Inputs,
56
59
  opts: ComponentResourceOptions | undefined,
57
60
 
58
- apiVersion: Output<string>,
59
- kind: Output<string>,
61
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
62
+ namespace: Output<Namespace>,
60
63
  terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,
61
64
  containers: Output<Container[]>,
62
- namespace: Output<Namespace>,
63
- metadata: Output<types.output.meta.v1.ObjectMeta>,
64
65
  networkPolicy: Output<NetworkPolicy | undefined>,
65
66
 
66
67
  /**
@@ -78,12 +79,10 @@ export abstract class CronJob extends Workload {
78
79
  name,
79
80
  args,
80
81
  opts,
81
- apiVersion,
82
- kind,
82
+ metadata,
83
+ namespace,
83
84
  terminalArgs,
84
85
  containers,
85
- namespace,
86
- metadata,
87
86
  spec.jobTemplate.spec.template,
88
87
  networkPolicy,
89
88
  )
@@ -96,13 +95,8 @@ export abstract class CronJob extends Workload {
96
95
  /**
97
96
  * The Highstate cron job entity.
98
97
  */
99
- get entity(): Output<k8s.ScopedResource> {
100
- return output({
101
- type: "cron-job",
102
- clusterId: this.cluster.id,
103
- clusterName: this.cluster.name,
104
- metadata: this.metadata,
105
- })
98
+ get entity(): Output<k8s.CronJob> {
99
+ return output(this.entityBase)
106
100
  }
107
101
 
108
102
  protected getTerminalMeta(): Output<UnitTerminal["meta"]> {
@@ -209,7 +203,7 @@ export abstract class CronJob extends Workload {
209
203
  * @param entity The entity to get the cron job for.
210
204
  * @param cluster The cluster where the cron job is located.
211
205
  */
212
- static for(entity: k8s.ScopedResource, cluster: Input<k8s.Cluster>): CronJob {
206
+ static for(entity: k8s.NamespacedResource, cluster: Input<k8s.Cluster>): CronJob {
213
207
  return getOrCreate(
214
208
  CronJob.cronJobCache,
215
209
  `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
@@ -234,7 +228,7 @@ export abstract class CronJob extends Workload {
234
228
  * @param cluster The cluster where the cron job is located.
235
229
  */
236
230
  static async forAsync(
237
- entity: Input<k8s.ScopedResource>,
231
+ entity: Input<k8s.NamespacedResource>,
238
232
  cluster: Input<k8s.Cluster>,
239
233
  ): Promise<CronJob> {
240
234
  const resolvedEntity = await toPromise(entity)
@@ -292,15 +286,11 @@ class CreatedCronJob extends CronJob {
292
286
  name,
293
287
  args,
294
288
  opts,
295
-
296
- cronJob.apiVersion,
297
- cronJob.kind,
289
+ cronJob.metadata,
290
+ output(args.namespace),
298
291
  output(args.terminal ?? {}),
299
292
  containers,
300
- output(args.namespace),
301
- cronJob.metadata,
302
293
  networkPolicy,
303
-
304
294
  cronJob.spec,
305
295
  cronJob.status,
306
296
  )
@@ -330,7 +320,7 @@ class CronJobPatch extends CronJob {
330
320
  template: podTemplate,
331
321
  },
332
322
  },
333
- schedule: args.schedule,
323
+ schedule: args.schedule!,
334
324
  } satisfies types.input.batch.v1.CronJobSpec,
335
325
  omit(args, cronJobExtraArgs) as types.input.batch.v1.CronJobSpec,
336
326
  )
@@ -349,15 +339,11 @@ class CronJobPatch extends CronJob {
349
339
  name,
350
340
  args,
351
341
  opts,
352
-
353
- cronJob.apiVersion,
354
- cronJob.kind,
342
+ cronJob.metadata,
343
+ output(args.namespace),
355
344
  output(args.terminal ?? {}),
356
345
  containers,
357
- output(args.namespace),
358
- cronJob.metadata,
359
346
  networkPolicy,
360
-
361
347
  cronJob.spec,
362
348
  cronJob.status,
363
349
  )
@@ -389,12 +375,10 @@ class WrappedCronJob extends CronJob {
389
375
  args,
390
376
  opts,
391
377
 
392
- output(args.cronJob).apiVersion,
393
- output(args.cronJob).kind,
378
+ output(args.cronJob).metadata,
379
+ output(args.namespace),
394
380
  output(args.terminal ?? {}),
395
381
  output([]),
396
- output(args.namespace),
397
- output(args.cronJob).metadata,
398
382
  output(undefined),
399
383
 
400
384
  output(args.cronJob).spec,
@@ -431,12 +415,10 @@ class ExternalCronJob extends CronJob {
431
415
  args,
432
416
  opts,
433
417
 
434
- cronJob.apiVersion,
435
- cronJob.kind,
418
+ cronJob.metadata,
419
+ output(args.namespace),
436
420
  output({}),
437
421
  output([]),
438
- output(args.namespace),
439
- cronJob.metadata,
440
422
  output(undefined),
441
423
 
442
424
  cronJob.spec,
package/src/deployment.ts CHANGED
@@ -43,18 +43,20 @@ export type CreateOrGetDeploymentArgs = DeploymentArgs & {
43
43
  }
44
44
 
45
45
  export abstract class Deployment extends ExposableWorkload {
46
+ static readonly apiVersion = "apps/v1"
47
+ static readonly kind = "Deployment"
48
+
46
49
  protected constructor(
47
50
  type: string,
48
51
  name: string,
49
52
  args: Inputs,
50
53
  opts: ComponentResourceOptions | undefined,
51
54
 
52
- apiVersion: Output<string>,
53
- kind: Output<string>,
55
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
56
+ namespace: Output<Namespace>,
57
+
54
58
  terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,
55
59
  containers: Output<Container[]>,
56
- namespace: Output<Namespace>,
57
- metadata: Output<types.output.meta.v1.ObjectMeta>,
58
60
  networkPolicy: Output<NetworkPolicy | undefined>,
59
61
 
60
62
  service: Output<Service | undefined>,
@@ -75,12 +77,10 @@ export abstract class Deployment extends ExposableWorkload {
75
77
  name,
76
78
  args,
77
79
  opts,
78
- apiVersion,
79
- kind,
80
+ metadata,
81
+ namespace,
80
82
  terminalArgs,
81
83
  containers,
82
- namespace,
83
- metadata,
84
84
  spec.template,
85
85
  networkPolicy,
86
86
  service,
@@ -105,12 +105,12 @@ export abstract class Deployment extends ExposableWorkload {
105
105
  * The Highstate deployment entity.
106
106
  */
107
107
  get entity(): Output<k8s.Deployment> {
108
+ const service = this._service.apply(service => service?.entity)
109
+
108
110
  return output({
109
- type: "deployment",
110
- clusterId: this.cluster.id,
111
- clusterName: this.cluster.name,
112
- metadata: this.metadata,
113
- service: this._service.apply(service => service?.entity),
111
+ ...this.entityBase,
112
+ service,
113
+ endpoints: service.apply(svc => output(svc?.endpoints ?? [])),
114
114
  })
115
115
  }
116
116
 
@@ -276,14 +276,13 @@ class CreatedDeployment extends Deployment {
276
276
  args,
277
277
  opts,
278
278
 
279
- deployment.apiVersion,
280
- deployment.kind,
279
+ deployment.metadata,
280
+ output(args.namespace),
281
+
281
282
  output(args.terminal ?? {}),
282
283
  containers,
283
- output(args.namespace),
284
- deployment.metadata,
285
- networkPolicy,
286
284
 
285
+ networkPolicy,
287
286
  service,
288
287
  routes,
289
288
 
@@ -324,12 +323,10 @@ class DeploymentPatch extends Deployment {
324
323
  args,
325
324
  opts,
326
325
 
327
- deployment.apiVersion,
328
- deployment.kind,
326
+ deployment.metadata,
327
+ output(args.namespace),
329
328
  output(args.terminal ?? {}),
330
329
  containers,
331
- output(args.namespace),
332
- deployment.metadata,
333
330
  networkPolicy,
334
331
 
335
332
  service,
@@ -366,12 +363,10 @@ class WrappedDeployment extends Deployment {
366
363
  args,
367
364
  opts,
368
365
 
369
- output(args.deployment).apiVersion,
370
- output(args.deployment).kind,
366
+ output(args.deployment).metadata,
367
+ output(args.namespace),
371
368
  output(args.terminal ?? {}),
372
369
  output([]),
373
- output(args.namespace),
374
- output(args.deployment).metadata,
375
370
 
376
371
  output(undefined),
377
372
  output(undefined),
@@ -411,12 +406,10 @@ class ExternalDeployment extends Deployment {
411
406
  args,
412
407
  opts,
413
408
 
414
- deployment.apiVersion,
415
- deployment.kind,
409
+ deployment.metadata,
410
+ output(args.namespace),
416
411
  output({}),
417
412
  output([]),
418
- output(args.namespace),
419
- deployment.metadata,
420
413
 
421
414
  output(undefined),
422
415
  output(undefined),
@@ -1,11 +1,10 @@
1
1
  import type { k8s, network } from "@highstate/library"
2
2
  import type { types } from "@pulumi/kubernetes"
3
3
  import type { SetRequired } from "type-fest"
4
- import { parseL3Endpoint } from "@highstate/common"
4
+ import { parseEndpoint } from "@highstate/common"
5
5
  import { getOrCreate } from "@highstate/contract"
6
6
  import { gateway, type types as gwTypes } from "@highstate/gateway-api"
7
7
  import {
8
- ComponentResource,
9
8
  type ComponentResourceOptions,
10
9
  type Input,
11
10
  type InputArray,
@@ -17,7 +16,13 @@ import {
17
16
  } from "@highstate/pulumi"
18
17
  import { omit } from "remeda"
19
18
  import { Namespace } from "../namespace"
20
- import { commonExtraArgs, getProvider, mapMetadata, type ScopedResourceArgs } from "../shared"
19
+ import {
20
+ commonExtraArgs,
21
+ getProvider,
22
+ mapMetadata,
23
+ NamespacedResource,
24
+ type ScopedResourceArgs,
25
+ } from "../shared"
21
26
 
22
27
  export type GatewayArgs = ScopedResourceArgs & {
23
28
  /**
@@ -43,7 +48,10 @@ const gatewayExtraArgs = [...commonExtraArgs, "fqdn", "fqdns"] as const
43
48
  /**
44
49
  * Represents a Kubernetes Gateway resource.
45
50
  */
46
- export abstract class Gateway extends ComponentResource {
51
+ export abstract class Gateway extends NamespacedResource {
52
+ static readonly apiVersion = "gateway.networking.k8s.io/v1"
53
+ static readonly kind = "Gateway"
54
+
47
55
  protected constructor(
48
56
  type: string,
49
57
  name: string,
@@ -53,12 +61,8 @@ export abstract class Gateway extends ComponentResource {
53
61
  /**
54
62
  * The namespace where the gateway is located.
55
63
  */
56
- readonly namespace: Output<Namespace>,
57
-
58
- /**
59
- * The metadata of the underlying Kubernetes gateway.
60
- */
61
- readonly metadata: Output<types.output.meta.v1.ObjectMeta>,
64
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
65
+ namespace: Output<Namespace>,
62
66
 
63
67
  /**
64
68
  * The spec of the underlying Gateway resource.
@@ -70,26 +74,14 @@ export abstract class Gateway extends ComponentResource {
70
74
  */
71
75
  readonly status: Output<gwTypes.output.gateway.v1.GatewayStatus>,
72
76
  ) {
73
- super(type, name, args, opts)
74
- }
75
-
76
- /**
77
- * The cluster where the gateway is located.
78
- */
79
- get cluster(): Output<k8s.Cluster> {
80
- return this.namespace.cluster
77
+ super(type, name, args, opts, metadata, namespace)
81
78
  }
82
79
 
83
80
  /**
84
81
  * The Highstate gateway entity.
85
82
  */
86
83
  get entity(): Output<k8s.Gateway> {
87
- return output({
88
- type: "gateway",
89
- clusterId: this.cluster.id,
90
- clusterName: this.cluster.name,
91
- metadata: this.metadata,
92
- })
84
+ return output(this.entityBase)
93
85
  }
94
86
 
95
87
  /**
@@ -101,7 +93,7 @@ export abstract class Gateway extends ComponentResource {
101
93
  return []
102
94
  }
103
95
 
104
- return addresses.map(address => parseL3Endpoint(address.value))
96
+ return addresses.map(address => parseEndpoint(address.value))
105
97
  })
106
98
  }
107
99
 
@@ -299,8 +291,8 @@ class CreatedGateway extends Gateway {
299
291
  args,
300
292
  opts,
301
293
 
302
- output(args.namespace),
303
294
  gatewayResource.metadata as Output<types.output.meta.v1.ObjectMeta>,
295
+ output(args.namespace),
304
296
  gatewayResource.spec,
305
297
  gatewayResource.status,
306
298
  )
@@ -326,8 +318,8 @@ class GatewayPatch extends Gateway {
326
318
  args,
327
319
  opts,
328
320
 
329
- output(args.namespace),
330
321
  gatewayResource.metadata as Output<types.output.meta.v1.ObjectMeta>,
322
+ output(args.namespace),
331
323
  gatewayResource.spec,
332
324
  gatewayResource.status,
333
325
  )
@@ -354,8 +346,8 @@ class WrappedGateway extends Gateway {
354
346
  args,
355
347
  opts,
356
348
 
357
- output(args.namespace),
358
349
  output(args.gateway).metadata as Output<types.output.meta.v1.ObjectMeta>,
350
+ output(args.namespace),
359
351
  output(args.gateway).spec,
360
352
  output(args.gateway).status,
361
353
  )
@@ -390,8 +382,8 @@ class ExternalGateway extends Gateway {
390
382
  args,
391
383
  opts,
392
384
 
393
- output(args.namespace),
394
385
  gatewayResource.metadata as Output<types.output.meta.v1.ObjectMeta>,
386
+ output(args.namespace),
395
387
  gatewayResource.spec,
396
388
  gatewayResource.status,
397
389
  )
package/src/helm.ts CHANGED
@@ -26,7 +26,7 @@ import spawn from "nano-spawn"
26
26
  import { isNonNullish, omit } from "remeda"
27
27
  import { Deployment } from "./deployment"
28
28
  import { NetworkPolicy, type NetworkPolicyArgs } from "./network-policy"
29
- import { getServiceType, Service, type ServiceArgs } from "./service"
29
+ import { createServiceSpec, Service, type ServiceArgs } from "./service"
30
30
  import { getNamespaceName, getProvider, type NamespaceLike } from "./shared"
31
31
  import { StatefulSet } from "./stateful-set"
32
32
 
@@ -147,19 +147,18 @@ export class Chart extends ComponentResource {
147
147
  resourceArgs.type === "kubernetes:core/v1:Service" &&
148
148
  resourceArgs.name === expectedName
149
149
  ) {
150
- const spec = resourceArgs.props.spec as types.input.core.v1.ServiceSpec
150
+ const spec = await toPromise(
151
+ resourceArgs.props.spec as types.input.core.v1.ServiceSpec,
152
+ )
153
+
154
+ const serviceSpec = await toPromise(createServiceSpec(args.service ?? {}, cluster))
151
155
 
152
156
  return {
153
157
  props: {
154
158
  ...resourceArgs.props,
155
159
  spec: {
156
160
  ...spec,
157
- ...(args.service ?? {}),
158
-
159
- type: getServiceType(args.service, cluster),
160
-
161
- externalIPs:
162
- args.service?.externalIPs ?? cluster.externalIps ?? spec.externalIPs,
161
+ ...omit(serviceSpec, ["ports"]),
163
162
  },
164
163
  },
165
164
  opts: resourceArgs.opts,