@highstate/k8s 0.14.2 → 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 +7 -12
  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/src/service.ts CHANGED
@@ -1,4 +1,10 @@
1
- import { filterEndpoints, l4EndpointToString, parseL3Endpoint } from "@highstate/common"
1
+ import {
2
+ addEndpointMetadata,
3
+ l3EndpointToL4,
4
+ mergeEndpoints,
5
+ parseEndpoint,
6
+ parseL4Protocol,
7
+ } from "@highstate/common"
2
8
  import { check, getOrCreate } from "@highstate/contract"
3
9
  import { k8s, type network } from "@highstate/library"
4
10
  import {
@@ -12,14 +18,13 @@ import {
12
18
  toPromise,
13
19
  } from "@highstate/pulumi"
14
20
  import { core, type types } from "@pulumi/kubernetes"
15
- import { deepmerge } from "deepmerge-ts"
16
- import { omit, uniqueBy } from "remeda"
21
+ import { omit, pipe } from "remeda"
17
22
  import { Namespace } from "./namespace"
18
23
  import {
19
24
  commonExtraArgs,
20
25
  getProvider,
21
26
  mapMetadata,
22
- ScopedResource,
27
+ NamespacedResource,
23
28
  type ScopedResourceArgs,
24
29
  } from "./shared"
25
30
 
@@ -66,17 +71,18 @@ export function isEndpointFromCluster(
66
71
  /**
67
72
  * Represents a Kubernetes Service resource with endpoints and metadata.
68
73
  */
69
- export abstract class Service extends ScopedResource {
74
+ export abstract class Service extends NamespacedResource {
75
+ static apiVersion = "v1"
76
+ static kind = "Service"
77
+
70
78
  protected constructor(
71
79
  type: string,
72
80
  name: string,
73
81
  args: Inputs,
74
82
  opts: ComponentResourceOptions | undefined,
75
83
 
76
- apiVersion: Output<string>,
77
- kind: Output<string>,
78
- namespace: Output<Namespace>,
79
84
  metadata: Output<types.output.meta.v1.ObjectMeta>,
85
+ namespace: Output<Namespace>,
80
86
 
81
87
  /**
82
88
  * The spec of the underlying Kubernetes service.
@@ -88,7 +94,7 @@ export abstract class Service extends ScopedResource {
88
94
  */
89
95
  readonly status: Output<types.output.core.v1.ServiceStatus>,
90
96
  ) {
91
- super(type, name, args, opts, apiVersion, kind, namespace, metadata)
97
+ super(type, name, args, opts, metadata, namespace)
92
98
  }
93
99
 
94
100
  /**
@@ -96,10 +102,7 @@ export abstract class Service extends ScopedResource {
96
102
  */
97
103
  get entity(): Output<k8s.Service> {
98
104
  return output({
99
- type: "service",
100
- clusterId: this.cluster.id,
101
- clusterName: this.cluster.name,
102
- metadata: this.metadata,
105
+ ...this.entityBase,
103
106
  endpoints: this.endpoints,
104
107
  })
105
108
  }
@@ -225,18 +228,6 @@ export abstract class Service extends ScopedResource {
225
228
  return Service.for(resolvedEntity, output(cluster))
226
229
  }
227
230
 
228
- /**
229
- * Returns the endpoints of the service applying the given filter.
230
- *
231
- * If no filter is specified, the default behavior of `filterEndpoints` is used.
232
- *
233
- * @param filter If specified, the endpoints are filtered based on the given filter.
234
- * @returns The endpoints of the service.
235
- */
236
- filterEndpoints(filter?: network.EndpointFilter): Output<k8s.ServiceEndpoint[]> {
237
- return output(this.endpoints).apply(endpoints => filterEndpoints(endpoints, filter))
238
- }
239
-
240
231
  /**
241
232
  * Returns the endpoints of the service including both internal and external endpoints.
242
233
  */
@@ -247,64 +238,57 @@ export abstract class Service extends ScopedResource {
247
238
  spec: this.spec,
248
239
  status: this.status,
249
240
  }).apply(({ cluster, metadata, spec, status }) => {
250
- const endpointMetadata: k8s.EndpointServiceMetadata = {
251
- "k8s.service": {
252
- clusterId: cluster.id,
253
- clusterName: cluster.name,
254
- name: metadata.name,
255
- namespace: metadata.namespace,
256
- selector: spec.selector,
257
- targetPort: spec.ports[0].targetPort ?? spec.ports[0].port,
258
- },
241
+ function createMetadata(isInternal: boolean): k8s.EndpointServiceMetadata {
242
+ return {
243
+ "k8s.service": {
244
+ clusterId: cluster.id,
245
+ clusterName: cluster.name,
246
+ name: metadata.name,
247
+ namespace: metadata.namespace,
248
+ isInternal,
249
+ selector: spec.selector,
250
+ targetPort: spec.ports[0].targetPort ?? spec.ports[0].port,
251
+ },
252
+ }
259
253
  }
260
254
 
261
- const clusterIpEndpoints = spec.clusterIPs?.map(ip => ({
262
- ...parseL3Endpoint(ip),
263
- visibility: "internal" as network.EndpointVisibility,
264
- port: spec.ports[0].port,
265
- protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,
266
- metadata: endpointMetadata,
267
- }))
268
-
269
- if (clusterIpEndpoints.length > 0) {
270
- clusterIpEndpoints.unshift({
271
- type: "hostname",
272
- visibility: "internal",
273
- hostname: `${metadata.name}.${metadata.namespace}.svc.cluster.local`,
274
- port: spec.ports[0].port,
275
- protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,
276
- metadata: endpointMetadata,
277
- })
278
- }
279
-
280
- const nodePortEndpoints =
281
- spec.type === "NodePort"
282
- ? cluster.endpoints.map(endpoint => ({
283
- ...(endpoint as network.L3Endpoint),
284
- port: spec.ports[0].nodePort,
285
- protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,
286
- metadata: endpointMetadata,
287
- }))
288
- : []
255
+ const internalHosts = spec.clusterIPs.length
256
+ ? [...spec.clusterIPs, `${metadata.name}.${metadata.namespace}.svc.cluster.local`]
257
+ : []
258
+
259
+ const internalEndpoints = internalHosts.flatMap(ip =>
260
+ spec.ports.map(port =>
261
+ pipe(
262
+ ip,
263
+ parseEndpoint,
264
+ endpoint => l3EndpointToL4(endpoint, port.port, parseL4Protocol(port.protocol)),
265
+ endpoint => addEndpointMetadata(endpoint, createMetadata(true)),
266
+ ),
267
+ ),
268
+ )
289
269
 
290
- const loadBalancerEndpoints =
291
- spec.type === "LoadBalancer"
292
- ? status.loadBalancer?.ingress?.map(endpoint => ({
293
- ...parseL3Endpoint(endpoint.ip ?? endpoint.hostname),
294
- port: spec.ports[0].port,
295
- protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,
296
- metadata: endpointMetadata,
297
- }))
270
+ const externalHosts =
271
+ spec.type === "NodePort" || spec.type === "LoadBalancer"
272
+ ? [
273
+ ...spec.externalIPs,
274
+ ...cluster.endpoints,
275
+ ...(status.loadBalancer?.ingress?.map(ingress => ingress.ip ?? ingress.hostname) ??
276
+ []),
277
+ ]
298
278
  : []
299
279
 
300
- return uniqueBy(
301
- [
302
- ...(clusterIpEndpoints ?? []),
303
- ...(loadBalancerEndpoints ?? []),
304
- ...(nodePortEndpoints ?? []),
305
- ],
306
- l4EndpointToString,
280
+ const externalEndpoints = externalHosts.flatMap(ip =>
281
+ spec.ports.map(port =>
282
+ pipe(
283
+ ip,
284
+ parseEndpoint,
285
+ endpoint => l3EndpointToL4(endpoint, port.port, parseL4Protocol(port.protocol)),
286
+ endpoint => addEndpointMetadata(endpoint, createMetadata(false)),
287
+ ),
288
+ ),
307
289
  )
290
+
291
+ return mergeEndpoints([...internalEndpoints, ...externalEndpoints])
308
292
  })
309
293
  }
310
294
  }
@@ -316,22 +300,31 @@ export abstract class Service extends ScopedResource {
316
300
  * @param cluster The cluster where the service will be created.
317
301
  * @returns The service spec configuration.
318
302
  */
319
- function createServiceSpec(args: ServiceArgs, cluster: k8s.Cluster) {
303
+ export function createServiceSpec(
304
+ args: Partial<ServiceArgs>,
305
+ cluster: k8s.Cluster,
306
+ ): Output<types.input.core.v1.ServiceSpec> {
320
307
  return output(args).apply(args => {
321
- return deepmerge(
322
- {
323
- ports: normalize(args.port, args.ports),
308
+ return {
309
+ ...omit(args, serviceExtraArgs),
310
+
311
+ ports: normalize(args.port, args.ports),
312
+
313
+ // externalIPs: args.external
314
+ // ? args.externalIPs
315
+ // ? args.externalIPs
316
+ // : cluster.externalIps.map(ip => ip.value)
317
+ // : normalize(undefined, args.externalIPs),
324
318
 
325
- externalIPs: args.external
319
+ // TODO: check for args.external being falsey
320
+ // for now we always set externalIPs since it for some reason fails if its empty
321
+ externalIPs:
322
+ args.externalIPs && args.externalIPs.length > 0
326
323
  ? args.externalIPs
327
- ? args.externalIPs
328
- : cluster.externalIps
329
- : normalize(undefined, args.externalIPs),
324
+ : cluster.externalIps.map(ip => ip.value),
330
325
 
331
- type: getServiceType(args, cluster),
332
- },
333
- omit(args, serviceExtraArgs),
334
- )
326
+ type: getServiceType(args, cluster),
327
+ }
335
328
  })
336
329
  }
337
330
 
@@ -353,11 +346,8 @@ class CreatedService extends Service {
353
346
  name,
354
347
  args,
355
348
  opts,
356
-
357
- service.apiVersion,
358
- service.kind,
359
- output(args.namespace),
360
349
  service.metadata,
350
+ output(args.namespace),
361
351
  service.spec,
362
352
  service.status,
363
353
  )
@@ -382,11 +372,8 @@ class ServicePatch extends Service {
382
372
  name,
383
373
  args,
384
374
  opts,
385
-
386
- service.apiVersion,
387
- service.kind,
388
- output(args.namespace),
389
375
  service.metadata,
376
+ output(args.namespace),
390
377
  service.spec,
391
378
  service.status,
392
379
  )
@@ -412,11 +399,8 @@ class WrappedService extends Service {
412
399
  name,
413
400
  args,
414
401
  opts,
415
-
416
- output(args.service).apiVersion,
417
- output(args.service).kind,
418
- output(args.namespace),
419
402
  output(args.service).metadata,
403
+ output(args.namespace),
420
404
  output(args.service).spec,
421
405
  output(args.service).status,
422
406
  )
@@ -450,11 +434,8 @@ class ExternalService extends Service {
450
434
  name,
451
435
  args,
452
436
  opts,
453
-
454
- service.apiVersion,
455
- service.kind,
456
- output(args.namespace),
457
437
  service.metadata,
438
+ output(args.namespace),
458
439
  service.spec,
459
440
  service.status,
460
441
  )
package/src/shared.ts CHANGED
@@ -114,7 +114,7 @@ export function validateCluster(
114
114
  return output({ entity, cluster }).apply(({ entity, cluster }) => {
115
115
  if (entity.clusterId !== cluster.id) {
116
116
  throw new Error(
117
- `Cluster mismatch for ${entity.type} "${entity.metadata.name}": "${entity.clusterId}" != "${cluster.id}"`,
117
+ `Cluster mismatch for ${entity.kind} "${entity.metadata.name}": "${entity.clusterId}" != "${cluster.id}"`,
118
118
  )
119
119
  }
120
120
 
@@ -125,11 +125,26 @@ export function validateCluster(
125
125
  export { images }
126
126
 
127
127
  /**
128
- * Base class for all Kubernetes scoped resources.
128
+ * Base class for all Kubernetes resources.
129
129
  *
130
- * Provides common functionality for resources that have a cluster, namespace, metadata, and entity.
130
+ * Provides common functionality for resources that have a cluster and entity.
131
131
  */
132
- export abstract class ScopedResource extends ComponentResource {
132
+ export abstract class Resource extends ComponentResource {
133
+ /**
134
+ * The Kubernetes API version (e.g., "v1", "apps/v1", "batch/v1").
135
+ */
136
+ static readonly apiVersion: string
137
+
138
+ /**
139
+ * The Kubernetes kind (e.g., "ConfigMap", "Deployment", "CronJob").
140
+ */
141
+ static readonly kind: string
142
+
143
+ /**
144
+ * Whether the resource is namespaced.
145
+ */
146
+ static readonly isNamespaced: boolean = false
147
+
133
148
  protected constructor(
134
149
  type: string,
135
150
  name: string,
@@ -137,19 +152,9 @@ export abstract class ScopedResource extends ComponentResource {
137
152
  opts: ComponentResourceOptions | undefined,
138
153
 
139
154
  /**
140
- * The Kubernetes API version (e.g., "v1", "apps/v1", "batch/v1").
141
- */
142
- readonly apiVersion: Output<string>,
143
-
144
- /**
145
- * The Kubernetes kind (e.g., "ConfigMap", "Deployment", "CronJob").
146
- */
147
- readonly kind: Output<string>,
148
-
149
- /**
150
- * The namespace where the resource is located.
155
+ * The cluster where the resource is located.
151
156
  */
152
- readonly namespace: Output<Namespace>,
157
+ readonly cluster: Output<k8s.Cluster>,
153
158
 
154
159
  /**
155
160
  * The metadata of the underlying Kubernetes resource.
@@ -160,14 +165,71 @@ export abstract class ScopedResource extends ComponentResource {
160
165
  }
161
166
 
162
167
  /**
163
- * The cluster where the resource is located.
168
+ * The Kubernetes API version (e.g., "v1", "apps/v1", "batch/v1").
164
169
  */
165
- get cluster(): Output<k8s.Cluster> {
166
- return this.namespace.cluster
170
+ get apiVersion() {
171
+ return (this.constructor as typeof Resource).apiVersion
172
+ }
173
+
174
+ /**
175
+ * The Kubernetes kind (e.g., "ConfigMap", "Deployment", "CronJob").
176
+ */
177
+ get kind() {
178
+ return (this.constructor as typeof Resource).kind
179
+ }
180
+
181
+ get isNamespaced() {
182
+ return (this.constructor as typeof Resource).isNamespaced
183
+ }
184
+
185
+ protected get entityBase() {
186
+ return {
187
+ clusterId: this.cluster.id,
188
+ clusterName: this.cluster.name,
189
+ apiVersion: this.apiVersion,
190
+ kind: this.kind,
191
+ isNamespaced: false,
192
+ metadata: this.metadata,
193
+ }
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Base class for all Kubernetes namespaced resources.
199
+ *
200
+ * Provides common functionality for resources that have a cluster, namespace, metadata, and entity.
201
+ */
202
+ export abstract class NamespacedResource extends Resource {
203
+ static readonly isNamespaced = true
204
+
205
+ protected constructor(
206
+ type: string,
207
+ name: string,
208
+ args: Inputs,
209
+ opts: ComponentResourceOptions | undefined,
210
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
211
+
212
+ /**
213
+ * The namespace where the resource is located.
214
+ */
215
+ readonly namespace: Output<Namespace>,
216
+ ) {
217
+ super(type, name, args, opts, namespace.cluster, metadata)
167
218
  }
168
219
 
169
220
  /**
170
221
  * The Highstate resource entity.
171
222
  */
172
- abstract get entity(): Output<k8s.ScopedResource>
223
+ abstract get entity(): Output<k8s.NamespacedResource>
224
+
225
+ protected get entityBase() {
226
+ return {
227
+ clusterId: this.cluster.id,
228
+ clusterName: this.cluster.name,
229
+ apiVersion: this.apiVersion,
230
+ kind: this.kind,
231
+ isNamespaced: true,
232
+ metadata: this.metadata,
233
+ } as const
234
+ }
173
235
  }
@@ -43,18 +43,19 @@ export type CreateOrGetStatefulSetArgs = StatefulSetArgs & {
43
43
  }
44
44
 
45
45
  export abstract class StatefulSet extends ExposableWorkload {
46
+ static apiVersion = "apps/v1"
47
+ static kind = "StatefulSet"
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>,
54
57
  terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,
55
58
  containers: Output<Container[]>,
56
- namespace: Output<Namespace>,
57
- metadata: Output<types.output.meta.v1.ObjectMeta>,
58
59
  networkPolicy: Output<NetworkPolicy | undefined>,
59
60
 
60
61
  service: Output<Service | undefined>,
@@ -75,12 +76,10 @@ export abstract class StatefulSet extends ExposableWorkload {
75
76
  name,
76
77
  args,
77
78
  opts,
78
- apiVersion,
79
- kind,
79
+ metadata,
80
+ namespace,
80
81
  terminalArgs,
81
82
  containers,
82
- namespace,
83
- metadata,
84
83
  spec.template,
85
84
  networkPolicy,
86
85
  service,
@@ -97,11 +96,9 @@ export abstract class StatefulSet extends ExposableWorkload {
97
96
  */
98
97
  get entity(): Output<k8s.StatefulSet> {
99
98
  return output({
100
- type: "stateful-set",
101
- clusterId: this.cluster.id,
102
- clusterName: this.cluster.name,
103
- metadata: this.metadata,
99
+ ...this.entityBase,
104
100
  service: this.service.entity,
101
+ endpoints: this.service.endpoints,
105
102
  })
106
103
  }
107
104
 
@@ -297,12 +294,10 @@ class CreatedStatefulSet extends StatefulSet {
297
294
  args,
298
295
  opts,
299
296
 
300
- statefulSet.apiVersion,
301
- statefulSet.kind,
297
+ statefulSet.metadata,
298
+ output(args.namespace),
302
299
  output(args.terminal ?? {}),
303
300
  containers,
304
- output(args.namespace),
305
- statefulSet.metadata,
306
301
  networkPolicy,
307
302
 
308
303
  service,
@@ -345,12 +340,10 @@ class StatefulSetPatch extends StatefulSet {
345
340
  args,
346
341
  opts,
347
342
 
348
- statefulSet.apiVersion,
349
- statefulSet.kind,
343
+ statefulSet.metadata,
344
+ output(args.namespace),
350
345
  output(args.terminal ?? {}),
351
346
  containers,
352
- output(args.namespace),
353
- statefulSet.metadata,
354
347
  networkPolicy,
355
348
 
356
349
  service,
@@ -390,12 +383,10 @@ class WrappedStatefulSet extends StatefulSet {
390
383
  args,
391
384
  opts,
392
385
 
393
- output(args.statefulSet).apiVersion,
394
- output(args.statefulSet).kind,
386
+ output(args.statefulSet).metadata,
387
+ output(args.namespace),
395
388
  output(args.terminal ?? {}),
396
389
  output([]),
397
- output(args.namespace),
398
- output(args.statefulSet).metadata,
399
390
 
400
391
  output(undefined),
401
392
  output(args.service),
@@ -435,12 +426,10 @@ class ExternalStatefulSet extends StatefulSet {
435
426
  args,
436
427
  opts,
437
428
 
438
- statefulSet.apiVersion,
439
- statefulSet.kind,
429
+ statefulSet.metadata,
430
+ output(args.namespace),
440
431
  output({}),
441
432
  output([]),
442
- output(args.namespace),
443
- statefulSet.metadata,
444
433
 
445
434
  output(undefined),
446
435
  output(undefined),
package/src/tls.ts CHANGED
@@ -3,7 +3,6 @@ import type { types } from "@pulumi/kubernetes"
3
3
  import { cert_manager, type types as cmTypes } from "@highstate/cert-manager"
4
4
  import { getOrCreate } from "@highstate/contract"
5
5
  import {
6
- ComponentResource,
7
6
  type ComponentResourceOptions,
8
7
  type Input,
9
8
  type Inputs,
@@ -15,7 +14,13 @@ import {
15
14
  import { omit } from "remeda"
16
15
  import { Namespace } from "./namespace"
17
16
  import { Secret } from "./secret"
18
- import { commonExtraArgs, getProvider, mapMetadata, type ScopedResourceArgs } from "./shared"
17
+ import {
18
+ commonExtraArgs,
19
+ getProvider,
20
+ mapMetadata,
21
+ NamespacedResource,
22
+ type ScopedResourceArgs,
23
+ } from "./shared"
19
24
 
20
25
  export type CertificateArgs = ScopedResourceArgs & cmTypes.input.cert_manager.v1.CertificateSpec
21
26
 
@@ -29,7 +34,10 @@ export type CreateOrGetCertificateArgs = CertificateArgs & {
29
34
  /**
30
35
  * Represents a cert-manager Certificate resource with metadata and secret.
31
36
  */
32
- export abstract class Certificate extends ComponentResource {
37
+ export abstract class Certificate extends NamespacedResource {
38
+ static readonly apiVersion = "cert-manager.io/v1"
39
+ static readonly kind = "Certificate"
40
+
33
41
  private _secret?: Output<Secret>
34
42
 
35
43
  protected constructor(
@@ -38,15 +46,8 @@ export abstract class Certificate extends ComponentResource {
38
46
  args: Inputs,
39
47
  opts: ComponentResourceOptions | undefined,
40
48
 
41
- /**
42
- * The namespace where the certificate is located.
43
- */
44
- readonly namespace: Output<Namespace>,
45
-
46
- /**
47
- * The metadata of the underlying cert-manager certificate.
48
- */
49
- readonly metadata: Output<types.output.meta.v1.ObjectMeta>,
49
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
50
+ namespace: Output<Namespace>,
50
51
 
51
52
  /**
52
53
  * The spec of the underlying cert-manager certificate.
@@ -58,26 +59,14 @@ export abstract class Certificate extends ComponentResource {
58
59
  */
59
60
  readonly status: Output<cmTypes.output.cert_manager.v1.CertificateStatus>,
60
61
  ) {
61
- super(type, name, args, opts)
62
- }
63
-
64
- /**
65
- * The cluster where the certificate is located.
66
- */
67
- get cluster(): Output<k8s.Cluster> {
68
- return this.namespace.cluster
62
+ super(type, name, args, opts, metadata, namespace)
69
63
  }
70
64
 
71
65
  /**
72
66
  * The Highstate certificate entity.
73
67
  */
74
- get entity(): Output<k8s.ScopedResource> {
75
- return output({
76
- type: "certificate",
77
- clusterId: this.cluster.id,
78
- clusterName: this.cluster.name,
79
- metadata: this.metadata,
80
- })
68
+ get entity(): Output<k8s.NamespacedResource> {
69
+ return output(this.entityBase)
81
70
  }
82
71
 
83
72
  /**
@@ -252,8 +241,8 @@ class CreatedCertificate extends Certificate {
252
241
  args,
253
242
  opts,
254
243
 
255
- output(args.namespace),
256
244
  certificate.metadata as Output<types.output.meta.v1.ObjectMeta>,
245
+ output(args.namespace),
257
246
  certificate.spec,
258
247
  certificate.status,
259
248
  )
@@ -279,8 +268,8 @@ class CertificatePatch extends Certificate {
279
268
  args,
280
269
  opts,
281
270
 
282
- output(args.namespace),
283
271
  certificate.metadata as Output<types.output.meta.v1.ObjectMeta>,
272
+ output(args.namespace),
284
273
  certificate.spec,
285
274
  certificate.status,
286
275
  )
@@ -307,8 +296,8 @@ class WrappedCertificate extends Certificate {
307
296
  args,
308
297
  opts,
309
298
 
310
- output(args.namespace),
311
299
  output(args.certificate).metadata as Output<types.output.meta.v1.ObjectMeta>,
300
+ output(args.namespace),
312
301
  output(args.certificate).spec,
313
302
  output(args.certificate).status,
314
303
  )
@@ -343,8 +332,8 @@ class ExternalCertificate extends Certificate {
343
332
  args,
344
333
  opts,
345
334
 
346
- output(args.namespace),
347
335
  certificate.metadata as Output<types.output.meta.v1.ObjectMeta>,
336
+ output(args.namespace),
348
337
  certificate.spec,
349
338
  certificate.status,
350
339
  )