@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/src/tls.ts ADDED
@@ -0,0 +1,344 @@
1
+ import type { k8s } from "@highstate/library"
2
+ import type { types } from "@pulumi/kubernetes"
3
+ import { cert_manager, type types as cmTypes } from "@highstate/cert-manager"
4
+ import { getOrCreate } from "@highstate/contract"
5
+ import {
6
+ ComponentResource,
7
+ type ComponentResourceOptions,
8
+ type Input,
9
+ type Inputs,
10
+ interpolate,
11
+ type Output,
12
+ output,
13
+ toPromise,
14
+ } from "@highstate/pulumi"
15
+ import { omit } from "remeda"
16
+ import { Namespace } from "./namespace"
17
+ import { Secret } from "./secret"
18
+ import { commonExtraArgs, getProvider, mapMetadata, type ScopedResourceArgs } from "./shared"
19
+
20
+ export type CertificateArgs = ScopedResourceArgs & cmTypes.input.cert_manager.v1.CertificateSpec
21
+
22
+ export type CreateOrGetCertificateArgs = CertificateArgs & {
23
+ /**
24
+ * The certificate entity to patch/retrieve.
25
+ */
26
+ existing: Input<k8s.Certificate> | undefined
27
+ }
28
+
29
+ /**
30
+ * Represents a cert-manager Certificate resource with metadata and secret.
31
+ */
32
+ export abstract class Certificate extends ComponentResource {
33
+ protected constructor(
34
+ type: string,
35
+ private readonly name: string,
36
+ args: Inputs,
37
+ opts: ComponentResourceOptions | undefined,
38
+
39
+ /**
40
+ * The namespace where the certificate is located.
41
+ */
42
+ readonly namespace: Output<Namespace>,
43
+
44
+ /**
45
+ * The metadata of the underlying cert-manager certificate.
46
+ */
47
+ readonly metadata: Output<types.output.meta.v1.ObjectMeta>,
48
+
49
+ /**
50
+ * The spec of the underlying cert-manager certificate.
51
+ */
52
+ readonly spec: Output<cmTypes.output.cert_manager.v1.CertificateSpec>,
53
+
54
+ /**
55
+ * The status of the underlying cert-manager certificate.
56
+ */
57
+ readonly status: Output<cmTypes.output.cert_manager.v1.CertificateStatus>,
58
+ ) {
59
+ super(type, name, args, opts)
60
+ }
61
+
62
+ /**
63
+ * The cluster where the certificate is located.
64
+ */
65
+ get cluster(): Output<k8s.Cluster> {
66
+ return this.namespace.cluster
67
+ }
68
+
69
+ /**
70
+ * The Highstate certificate entity.
71
+ */
72
+ get entity(): Output<k8s.ScopedResource> {
73
+ return output({
74
+ type: "certificate",
75
+ clusterId: this.cluster.id,
76
+ clusterName: this.cluster.name,
77
+ metadata: this.metadata,
78
+ })
79
+ }
80
+
81
+ /**
82
+ * The secret containing the certificate data.
83
+ */
84
+ get secret(): Output<Secret> {
85
+ return output({
86
+ secretName: this.spec.apply(spec => spec.secretName),
87
+ namespace: this.namespace,
88
+ }).apply(({ secretName, namespace }) => {
89
+ return Secret.get(`${this.name}.secret`, {
90
+ name: secretName,
91
+ namespace,
92
+ })
93
+ })
94
+ }
95
+
96
+ /**
97
+ * Creates a new certificate.
98
+ */
99
+ static create(name: string, args: CertificateArgs, opts?: ComponentResourceOptions): Certificate {
100
+ return new CreatedCertificate(name, args, opts)
101
+ }
102
+
103
+ /**
104
+ * Creates a new certificate or patches an existing one.
105
+ *
106
+ * @param name The name of the resource. May not be the same as the certificate name.
107
+ * @param args The arguments to create or patch the certificate with.
108
+ * @param opts Optional resource options.
109
+ */
110
+ static createOrPatch(
111
+ name: string,
112
+ args: CreateOrGetCertificateArgs,
113
+ opts?: ComponentResourceOptions,
114
+ ): Certificate {
115
+ if (args.existing) {
116
+ return new CertificatePatch(name, {
117
+ ...args,
118
+ name: output(args.existing).metadata.name,
119
+ namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),
120
+ })
121
+ }
122
+
123
+ return new CreatedCertificate(name, args, opts)
124
+ }
125
+
126
+ /**
127
+ * Creates a new certificate or gets an existing one.
128
+ *
129
+ * @param name The name of the resource. May not be the same as the certificate name. Will not be used when existing certificate is retrieved.
130
+ * @param args The arguments to create or get the certificate with.
131
+ * @param opts Optional resource options.
132
+ */
133
+ static async createOrGet(
134
+ name: string,
135
+ args: CreateOrGetCertificateArgs,
136
+ opts?: ComponentResourceOptions,
137
+ ): Promise<Certificate> {
138
+ if (args.existing) {
139
+ return await Certificate.forAsync(args.existing, output(args.namespace).cluster)
140
+ }
141
+
142
+ return new CreatedCertificate(name, args, opts)
143
+ }
144
+
145
+ /**
146
+ * Patches an existing certificate.
147
+ *
148
+ * Will throw an error if the certificate does not exist.
149
+ *
150
+ * @param name The name of the resource. May not be the same as the certificate name.
151
+ * @param args The arguments to patch the certificate with.
152
+ * @param opts Optional resource options.
153
+ */
154
+ static patch(name: string, args: CertificateArgs, opts?: ComponentResourceOptions): Certificate {
155
+ return new CertificatePatch(name, args, opts)
156
+ }
157
+
158
+ /**
159
+ * Wraps an existing cert-manager certificate.
160
+ */
161
+ static wrap(
162
+ name: string,
163
+ args: WrappedCertificateArgs,
164
+ opts?: ComponentResourceOptions,
165
+ ): Certificate {
166
+ return new WrappedCertificate(name, args, opts)
167
+ }
168
+
169
+ /**
170
+ * Gets an existing certificate.
171
+ *
172
+ * Will throw an error if the certificate does not exist.
173
+ */
174
+ static get(
175
+ name: string,
176
+ args: ExternalCertificateArgs,
177
+ opts?: ComponentResourceOptions,
178
+ ): Certificate {
179
+ return new ExternalCertificate(name, args, opts)
180
+ }
181
+
182
+ private static readonly certificateCache = new Map<string, Certificate>()
183
+
184
+ /**
185
+ * Gets an existing certificate for a given entity.
186
+ * Prefer this method over `get` when possible.
187
+ *
188
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
189
+ *
190
+ * This method is idempotent and will return the same instance for the same entity.
191
+ *
192
+ * @param entity The entity to get the certificate for.
193
+ * @param cluster The cluster where the certificate is located.
194
+ */
195
+ static for(entity: k8s.Certificate, cluster: Input<k8s.Cluster>): Certificate {
196
+ return getOrCreate(
197
+ Certificate.certificateCache,
198
+ `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
199
+ name => {
200
+ return Certificate.get(name, {
201
+ name: entity.metadata.name,
202
+ namespace: Namespace.forResourceAsync(entity, cluster),
203
+ })
204
+ },
205
+ )
206
+ }
207
+
208
+ /**
209
+ * Gets an existing certificate for a given entity.
210
+ * Prefer this method over `get` when possible.
211
+ *
212
+ * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.
213
+ *
214
+ * This method is idempotent and will return the same instance for the same entity.
215
+ *
216
+ * @param entity The entity to get the certificate for.
217
+ * @param cluster The cluster where the certificate is located.
218
+ */
219
+ static async forAsync(
220
+ entity: Input<k8s.Certificate>,
221
+ cluster: Input<k8s.Cluster>,
222
+ ): Promise<Certificate> {
223
+ const resolvedEntity = await toPromise(entity)
224
+ return Certificate.for(resolvedEntity, output(cluster))
225
+ }
226
+ }
227
+
228
+ class CreatedCertificate extends Certificate {
229
+ constructor(name: string, args: CertificateArgs, opts?: ComponentResourceOptions) {
230
+ const certificate = output(args.namespace).cluster.apply(cluster => {
231
+ return new cert_manager.v1.Certificate(
232
+ name,
233
+ {
234
+ metadata: mapMetadata(args, name),
235
+ spec: omit(args, commonExtraArgs),
236
+ },
237
+ { ...opts, parent: this, provider: getProvider(cluster) },
238
+ )
239
+ })
240
+
241
+ super(
242
+ "highstate:k8s:Certificate",
243
+ name,
244
+ args,
245
+ opts,
246
+
247
+ output(args.namespace),
248
+ certificate.metadata as Output<types.output.meta.v1.ObjectMeta>,
249
+ certificate.spec,
250
+ certificate.status,
251
+ )
252
+ }
253
+ }
254
+
255
+ class CertificatePatch extends Certificate {
256
+ constructor(name: string, args: CertificateArgs, opts?: ComponentResourceOptions) {
257
+ const certificate = output(args.namespace).cluster.apply(cluster => {
258
+ return new cert_manager.v1.CertificatePatch(
259
+ name,
260
+ {
261
+ metadata: mapMetadata(args, name),
262
+ spec: omit(args, commonExtraArgs),
263
+ },
264
+ { ...opts, parent: this, provider: getProvider(cluster) },
265
+ )
266
+ })
267
+
268
+ super(
269
+ "highstate:k8s:CertificatePatch",
270
+ name,
271
+ args,
272
+ opts,
273
+
274
+ output(args.namespace),
275
+ certificate.metadata as Output<types.output.meta.v1.ObjectMeta>,
276
+ certificate.spec,
277
+ certificate.status,
278
+ )
279
+ }
280
+ }
281
+
282
+ export type WrappedCertificateArgs = {
283
+ /**
284
+ * The underlying cert-manager certificate to wrap.
285
+ */
286
+ certificate: Input<cert_manager.v1.Certificate>
287
+
288
+ /**
289
+ * The namespace where the certificate is located.
290
+ */
291
+ namespace: Input<Namespace>
292
+ }
293
+
294
+ class WrappedCertificate extends Certificate {
295
+ constructor(name: string, args: WrappedCertificateArgs, opts?: ComponentResourceOptions) {
296
+ super(
297
+ "highstate:k8s:WrappedCertificate",
298
+ name,
299
+ args,
300
+ opts,
301
+
302
+ output(args.namespace),
303
+ output(args.certificate).metadata as Output<types.output.meta.v1.ObjectMeta>,
304
+ output(args.certificate).spec,
305
+ output(args.certificate).status,
306
+ )
307
+ }
308
+ }
309
+
310
+ export type ExternalCertificateArgs = {
311
+ /**
312
+ * The name of the certificate to get.
313
+ */
314
+ name: Input<string>
315
+
316
+ /**
317
+ * The namespace of the certificate to get.
318
+ */
319
+ namespace: Input<Namespace>
320
+ }
321
+
322
+ class ExternalCertificate extends Certificate {
323
+ constructor(name: string, args: ExternalCertificateArgs, opts?: ComponentResourceOptions) {
324
+ const certificate = output(args.namespace).cluster.apply(cluster => {
325
+ return cert_manager.v1.Certificate.get(
326
+ name,
327
+ interpolate`${output(args.namespace).metadata.name}/${args.name}`,
328
+ { ...opts, parent: this, provider: getProvider(cluster) },
329
+ )
330
+ })
331
+
332
+ super(
333
+ "highstate:k8s:ExternalCertificate",
334
+ name,
335
+ args,
336
+ opts,
337
+
338
+ output(args.namespace),
339
+ certificate.metadata as Output<types.output.meta.v1.ObjectMeta>,
340
+ certificate.spec,
341
+ certificate.status,
342
+ )
343
+ }
344
+ }
@@ -4,12 +4,11 @@ import { Chart } from "../../helm"
4
4
  import charts from "../../../assets/charts.json"
5
5
  import { Namespace } from "../../namespace"
6
6
 
7
- const { inputs, outputs } = forUnit(k8s.certManager)
7
+ const { args, inputs, outputs } = forUnit(k8s.certManager)
8
8
 
9
9
  const namespace = Namespace.create("cert-manager", { cluster: inputs.k8sCluster })
10
10
 
11
11
  new Chart("cert-manager", {
12
- cluster: inputs.k8sCluster,
13
12
  namespace,
14
13
 
15
14
  chart: charts["cert-manager"],
@@ -22,7 +21,7 @@ new Chart("cert-manager", {
22
21
  config: {
23
22
  apiVersion: "controller.config.cert-manager.io/v1alpha1",
24
23
  kind: "ControllerConfiguration",
25
- enableGatewayAPI: true,
24
+ enableGatewayAPI: args.enableGatewayApi,
26
25
  },
27
26
  },
28
27
  })
@@ -1,12 +1,18 @@
1
1
  import { k8s } from "@highstate/library"
2
- import { forUnit, unsecret } from "@highstate/pulumi"
2
+ import { forUnit } from "@highstate/pulumi"
3
3
  import { cert_manager } from "@highstate/cert-manager"
4
- import { getProvider } from "../../shared"
5
- import { createDns01Solver } from "./solver"
4
+ import { getProviderAsync } from "../../shared"
5
+ import { dns01SolverMediator } from "../../dns01-solver"
6
+ import { Namespace } from "../../namespace"
6
7
 
7
8
  const { name, inputs, outputs } = forUnit(k8s.dns01TlsIssuer)
8
9
 
9
- const provider = await getProvider(inputs.k8sCluster)
10
+ const provider = await getProviderAsync(inputs.k8sCluster)
11
+
12
+ const certManagerNs = Namespace.get("cert-manager", {
13
+ name: "cert-manager",
14
+ cluster: inputs.k8sCluster,
15
+ })
10
16
 
11
17
  new cert_manager.v1.ClusterIssuer(
12
18
  name,
@@ -17,14 +23,14 @@ new cert_manager.v1.ClusterIssuer(
17
23
  spec: {
18
24
  acme: {
19
25
  server: "https://acme-v02.api.letsencrypt.org/directory",
20
- solvers: inputs.dnsProviders.apply(dnsProviders =>
21
- dnsProviders.map(dnsProvider => {
22
- return {
23
- dns01: createDns01Solver(dnsProvider, provider),
24
- selector: { dnsZones: [dnsProvider.domain] },
25
- }
26
- }),
27
- ),
26
+ solvers: [
27
+ {
28
+ dns01: dns01SolverMediator.callOutput(inputs.dnsProvider.implRef, {
29
+ namespace: certManagerNs,
30
+ }),
31
+ selector: { dnsZones: [inputs.dnsProvider.domain] },
32
+ },
33
+ ],
28
34
  privateKeySecretRef: {
29
35
  name,
30
36
  },
@@ -35,8 +41,18 @@ new cert_manager.v1.ClusterIssuer(
35
41
  )
36
42
 
37
43
  export default outputs({
44
+ $statusFields: {
45
+ domain: inputs.dnsProvider.domain,
46
+ },
47
+
38
48
  tlsIssuer: {
39
- clusterId: unsecret(inputs.k8sCluster.id),
40
- clusterIssuerName: name,
49
+ domain: inputs.dnsProvider.domain,
50
+ implRef: {
51
+ package: "@highstate/k8s",
52
+ data: {
53
+ clusterIssuerName: name,
54
+ cluster: inputs.k8sCluster,
55
+ },
56
+ },
41
57
  },
42
58
  })
@@ -1,4 +1,4 @@
1
- import { k8s } from "@highstate/library"
1
+ import { k8s, type ImplementationReference } from "@highstate/library"
2
2
  import { forUnit, secret, toPromise } from "@highstate/pulumi"
3
3
  import { core, Provider } from "@pulumi/kubernetes"
4
4
  import { KubeConfig, AppsV1Api } from "@kubernetes/client-node"
@@ -16,20 +16,23 @@ const kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringif
16
16
 
17
17
  const provider = new Provider(name, { kubeconfig: kubeconfigContent })
18
18
 
19
- let cni: k8s.CNI = "other"
19
+ let networkPolicyImplRef: ImplementationReference | undefined
20
20
 
21
21
  const kubeConfig = new KubeConfig()
22
22
  kubeConfig.loadFromString(kubeconfigContent)
23
23
 
24
24
  const appsApi = kubeConfig.makeApiClient(AppsV1Api)
25
25
 
26
- const isCilium = await appsApi
26
+ const hasCilium = await appsApi
27
27
  .readNamespacedDaemonSet({ name: "cilium", namespace: "kube-system" })
28
28
  .then(() => true)
29
29
  .catch(() => false)
30
30
 
31
- if (isCilium) {
32
- cni = "cilium"
31
+ if (hasCilium) {
32
+ networkPolicyImplRef = {
33
+ package: "@highstate/cilium",
34
+ data: {},
35
+ }
33
36
  }
34
37
 
35
38
  const externalIps =
@@ -43,8 +46,9 @@ const kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provide
43
46
  export default outputs({
44
47
  k8sCluster: {
45
48
  id: kubeSystem.metadata.uid,
49
+ connectionId: kubeSystem.metadata.uid,
46
50
  name,
47
- cni,
51
+ networkPolicyImplRef,
48
52
  externalIps,
49
53
  endpoints,
50
54
  apiEndpoints,
@@ -59,7 +63,6 @@ export default outputs({
59
63
 
60
64
  $statusFields: {
61
65
  clusterId: kubeSystem.metadata.uid,
62
- cni,
63
66
  endpoints: endpoints.map(l3EndpointToString),
64
67
  apiEndpoints: apiEndpoints.map(l4EndpointToString),
65
68
  },
@@ -1,11 +1,11 @@
1
1
  import { k8s } from "@highstate/library"
2
2
  import { forUnit } from "@highstate/pulumi"
3
3
  import { yaml } from "@pulumi/kubernetes"
4
- import { getProvider } from "../../shared"
4
+ import { getProviderAsync } from "../../shared"
5
5
 
6
6
  const { inputs, outputs } = forUnit(k8s.gatewayApi)
7
7
 
8
- const provider = await getProvider(inputs.k8sCluster)
8
+ const provider = await getProviderAsync(inputs.k8sCluster)
9
9
 
10
10
  new yaml.v2.ConfigFile(
11
11
  "gateway-api",
package/src/worker.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type { UnitWorker } from "@highstate/contract"
2
+ import type { k8s } from "@highstate/library"
3
+ import type { DeepInput, InputArray, Unwrap } from "@highstate/pulumi"
4
+ import { type Output, output } from "@pulumi/pulumi"
5
+ import { ClusterAccessScope } from "./rbac"
6
+ import { images, type ScopedResource } from "./shared"
7
+
8
+ export async function createMonitorWorker(
9
+ resources: InputArray<ScopedResource>,
10
+ ): Promise<Output<Unwrap<UnitWorker>>> {
11
+ const scope = await ClusterAccessScope.forResources("monitor", resources, [
12
+ "get",
13
+ "list",
14
+ "watch",
15
+ ])
16
+
17
+ return output({
18
+ name: "monitor",
19
+ image: images["worker-k8s-monitor"].image,
20
+
21
+ params: {
22
+ kubeconfig: scope.cluster.kubeconfig,
23
+ resources: output(resources).apply(resources => resources.map(r => r.entity)),
24
+ } satisfies DeepInput<k8s.MonitorWorkerParams>,
25
+ })
26
+ }