@highstate/k8s 0.19.1 → 0.21.1

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 (107) hide show
  1. package/dist/chunk-23vn2rdc.js +11 -0
  2. package/dist/chunk-2pfx13ay.js +11 -0
  3. package/dist/chunk-46ntav0c.js +299 -0
  4. package/dist/chunk-556pc9e6.js +155 -0
  5. package/dist/chunk-7kgjgcft.js +170 -0
  6. package/dist/{chunk-LGHFSXNT.js → chunk-9hs97f1q.js} +23 -17
  7. package/dist/chunk-aame3x1b.js +11 -0
  8. package/dist/chunk-b05q6fm2.js +37 -0
  9. package/dist/chunk-bmvc9d2d.js +11 -0
  10. package/dist/chunk-de82bbp2.js +7 -0
  11. package/dist/chunk-facs31cb.js +624 -0
  12. package/dist/chunk-h1b79v66.js +1425 -0
  13. package/dist/chunk-k4w9zpn5.js +215 -0
  14. package/dist/chunk-pqc6w52f.js +352 -0
  15. package/dist/chunk-qyshvz32.js +176 -0
  16. package/dist/chunk-tpfyj6fe.js +199 -0
  17. package/dist/chunk-z6bmpnm7.js +180 -0
  18. package/dist/highstate.manifest.json +3 -2
  19. package/dist/impl/dynamic-endpoint-resolver.js +91 -0
  20. package/dist/impl/gateway-route.js +226 -166
  21. package/dist/impl/tls-certificate.js +31 -31
  22. package/dist/index.js +293 -166
  23. package/dist/units/cert-manager/index.js +19 -14
  24. package/dist/units/cluster-patch/index.js +14 -13
  25. package/dist/units/dns01-issuer/index.js +82 -42
  26. package/dist/units/existing-cluster/index.js +59 -26
  27. package/dist/units/gateway-api/index.js +15 -16
  28. package/dist/units/reduced-access-cluster/index.js +32 -36
  29. package/package.json +23 -21
  30. package/src/cluster.ts +12 -8
  31. package/src/config-map.ts +15 -5
  32. package/src/container.ts +4 -2
  33. package/src/cron-job.ts +51 -5
  34. package/src/deployment.ts +49 -18
  35. package/src/gateway/backend.ts +3 -3
  36. package/src/gateway/gateway.ts +12 -56
  37. package/src/helm.ts +354 -22
  38. package/src/impl/dynamic-endpoint-resolver.ts +109 -0
  39. package/src/impl/gateway-route.ts +231 -57
  40. package/src/impl/tls-certificate.ts +8 -3
  41. package/src/index.ts +1 -0
  42. package/src/job.ts +38 -6
  43. package/src/kubectl.ts +166 -0
  44. package/src/namespace.ts +47 -3
  45. package/src/network-policy.ts +1 -1
  46. package/src/pvc.ts +12 -2
  47. package/src/rbac.ts +28 -5
  48. package/src/scripting/bundle.ts +21 -98
  49. package/src/scripting/environment.ts +4 -10
  50. package/src/secret.ts +15 -5
  51. package/src/service.ts +28 -6
  52. package/src/shared.ts +31 -3
  53. package/src/stateful-set.ts +49 -18
  54. package/src/tls.ts +31 -5
  55. package/src/units/cluster-patch/index.ts +5 -5
  56. package/src/units/dns01-issuer/index.ts +56 -12
  57. package/src/units/existing-cluster/index.ts +36 -15
  58. package/src/units/reduced-access-cluster/index.ts +6 -3
  59. package/src/worker.ts +4 -2
  60. package/src/workload.ts +474 -217
  61. package/LICENSE +0 -21
  62. package/dist/chunk-4G6LLC2X.js +0 -240
  63. package/dist/chunk-4G6LLC2X.js.map +0 -1
  64. package/dist/chunk-BR2CLUUD.js +0 -230
  65. package/dist/chunk-BR2CLUUD.js.map +0 -1
  66. package/dist/chunk-DCUMJSO6.js +0 -427
  67. package/dist/chunk-DCUMJSO6.js.map +0 -1
  68. package/dist/chunk-FE4SHRAJ.js +0 -286
  69. package/dist/chunk-FE4SHRAJ.js.map +0 -1
  70. package/dist/chunk-HH2JJELM.js +0 -13
  71. package/dist/chunk-HH2JJELM.js.map +0 -1
  72. package/dist/chunk-KMLRI5UZ.js +0 -155
  73. package/dist/chunk-KMLRI5UZ.js.map +0 -1
  74. package/dist/chunk-LGHFSXNT.js.map +0 -1
  75. package/dist/chunk-MIC2BHGS.js +0 -301
  76. package/dist/chunk-MIC2BHGS.js.map +0 -1
  77. package/dist/chunk-OBDQONMV.js +0 -401
  78. package/dist/chunk-OBDQONMV.js.map +0 -1
  79. package/dist/chunk-P2VOUU7E.js +0 -1626
  80. package/dist/chunk-P2VOUU7E.js.map +0 -1
  81. package/dist/chunk-PZ5AY32C.js +0 -9
  82. package/dist/chunk-PZ5AY32C.js.map +0 -1
  83. package/dist/chunk-RVB4WWZZ.js +0 -267
  84. package/dist/chunk-RVB4WWZZ.js.map +0 -1
  85. package/dist/chunk-TWBMG6TD.js +0 -315
  86. package/dist/chunk-TWBMG6TD.js.map +0 -1
  87. package/dist/chunk-VCXWCZ43.js +0 -279
  88. package/dist/chunk-VCXWCZ43.js.map +0 -1
  89. package/dist/chunk-YIJUVPU2.js +0 -297
  90. package/dist/chunk-YIJUVPU2.js.map +0 -1
  91. package/dist/cron-job-NX4HD4FI.js +0 -8
  92. package/dist/cron-job-NX4HD4FI.js.map +0 -1
  93. package/dist/deployment-O2LJ5WR5.js +0 -8
  94. package/dist/deployment-O2LJ5WR5.js.map +0 -1
  95. package/dist/impl/gateway-route.js.map +0 -1
  96. package/dist/impl/tls-certificate.js.map +0 -1
  97. package/dist/index.js.map +0 -1
  98. package/dist/job-SYME6Y43.js +0 -8
  99. package/dist/job-SYME6Y43.js.map +0 -1
  100. package/dist/stateful-set-VJYKTQ72.js +0 -8
  101. package/dist/stateful-set-VJYKTQ72.js.map +0 -1
  102. package/dist/units/cert-manager/index.js.map +0 -1
  103. package/dist/units/cluster-patch/index.js.map +0 -1
  104. package/dist/units/dns01-issuer/index.js.map +0 -1
  105. package/dist/units/existing-cluster/index.js.map +0 -1
  106. package/dist/units/gateway-api/index.js.map +0 -1
  107. package/dist/units/reduced-access-cluster/index.js.map +0 -1
@@ -1,14 +1,15 @@
1
1
  import type { AccessPointRoute } from "@highstate/common"
2
- import type { k8s } from "@highstate/library"
3
2
  import type { Container } from "./container"
4
3
  import type { NetworkPolicy } from "./network-policy"
5
4
  import type { Service } from "./service"
6
5
  import { getOrCreate, type UnitTerminal } from "@highstate/contract"
6
+ import { k8s } from "@highstate/library"
7
7
  import {
8
8
  type ComponentResourceOptions,
9
9
  type Input,
10
10
  type Inputs,
11
11
  interpolate,
12
+ makeEntityOutput,
12
13
  type Output,
13
14
  output,
14
15
  toPromise,
@@ -20,14 +21,15 @@ import { omit } from "remeda"
20
21
  import { Namespace } from "./namespace"
21
22
  import { getProvider, mapMetadata } from "./shared"
22
23
  import {
23
- ExposableWorkload,
24
- type ExposableWorkloadArgs,
25
- exposableWorkloadExtraArgs,
26
- getExposableWorkloadComponents,
24
+ filterPatchOwnedContainersInTemplate,
25
+ getWorkloadServiceComponents,
26
+ Workload,
27
+ type WorkloadServiceArgs,
27
28
  type WorkloadTerminalArgs,
29
+ workloadServiceExtraArgs,
28
30
  } from "./workload"
29
31
 
30
- export type StatefulSetArgs = Omit<ExposableWorkloadArgs, "existing"> &
32
+ export type StatefulSetArgs = Omit<WorkloadServiceArgs, "existing"> &
31
33
  Omit<Partial<types.input.apps.v1.StatefulSetSpec>, "template"> & {
32
34
  template?: {
33
35
  metadata?: types.input.meta.v1.ObjectMeta
@@ -42,7 +44,7 @@ export type CreateOrGetStatefulSetArgs = StatefulSetArgs & {
42
44
  existing: Input<k8s.StatefulSet> | undefined
43
45
  }
44
46
 
45
- export abstract class StatefulSet extends ExposableWorkload {
47
+ export abstract class StatefulSet extends Workload {
46
48
  static apiVersion = "apps/v1"
47
49
  static kind = "StatefulSet"
48
50
 
@@ -95,10 +97,17 @@ export abstract class StatefulSet extends ExposableWorkload {
95
97
  * The Highstate stateful set entity.
96
98
  */
97
99
  get entity(): Output<k8s.StatefulSet> {
98
- return output({
99
- ...this.entityBase,
100
- service: this.service.entity,
101
- endpoints: this.service.endpoints,
100
+ return makeEntityOutput({
101
+ entity: k8s.statefulSetEntity,
102
+ identity: this.metadata.uid,
103
+ meta: {
104
+ title: this.metadata.name,
105
+ },
106
+ value: {
107
+ ...this.entityBase,
108
+ service: this.service.entity,
109
+ spec: this.spec,
110
+ },
102
111
  })
103
112
  }
104
113
 
@@ -250,7 +259,7 @@ export abstract class StatefulSet extends ExposableWorkload {
250
259
  class CreatedStatefulSet extends StatefulSet {
251
260
  constructor(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions) {
252
261
  const { labels, podTemplate, networkPolicy, containers, service, routes } =
253
- getExposableWorkloadComponents(
262
+ getWorkloadServiceComponents(
254
263
  name,
255
264
  {
256
265
  ...args,
@@ -275,7 +284,7 @@ class CreatedStatefulSet extends StatefulSet {
275
284
  template: podTemplate,
276
285
  selector: { matchLabels: labels },
277
286
  },
278
- omit(args, exposableWorkloadExtraArgs),
287
+ omit(args, workloadServiceExtraArgs),
279
288
  ) as types.input.apps.v1.StatefulSetSpec
280
289
  },
281
290
  ),
@@ -312,7 +321,7 @@ class CreatedStatefulSet extends StatefulSet {
312
321
  class StatefulSetPatch extends StatefulSet {
313
322
  constructor(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions) {
314
323
  const { podTemplate, networkPolicy, containers, service, routes } =
315
- getExposableWorkloadComponents(name, args, () => this, opts, true)
324
+ getWorkloadServiceComponents(name, args, () => this, opts, true)
316
325
 
317
326
  const statefulSet = output(args.namespace).cluster.apply(cluster => {
318
327
  return new apps.v1.StatefulSetPatch(
@@ -320,10 +329,16 @@ class StatefulSetPatch extends StatefulSet {
320
329
  {
321
330
  metadata: mapMetadata(args, name),
322
331
  spec: output({ args, podTemplate }).apply(({ args, podTemplate }) => {
323
- return deepmerge(
332
+ const spec = deepmerge(
324
333
  { template: podTemplate },
325
- omit(args, exposableWorkloadExtraArgs),
326
- ) as types.input.apps.v1.StatefulSetSpec
334
+ omit(args, workloadServiceExtraArgs),
335
+ ) as Unwrap<types.input.apps.v1.StatefulSetSpec>
336
+
337
+ if (spec.template) {
338
+ spec.template = filterPatchOwnedContainersInTemplate(spec.template, podTemplate)
339
+ }
340
+
341
+ return spec
327
342
  }),
328
343
  },
329
344
  {
@@ -334,6 +349,22 @@ class StatefulSetPatch extends StatefulSet {
334
349
  )
335
350
  })
336
351
 
352
+ const filteredSpec = output({ spec: statefulSet.spec, podTemplate }).apply(
353
+ ({ spec, podTemplate }) => {
354
+ if (!spec.template) {
355
+ return spec
356
+ }
357
+
358
+ return {
359
+ ...spec,
360
+ template: filterPatchOwnedContainersInTemplate(
361
+ spec.template as Unwrap<types.input.core.v1.PodTemplateSpec>,
362
+ podTemplate,
363
+ ) as types.output.core.v1.PodTemplateSpec,
364
+ }
365
+ },
366
+ ) as Output<types.output.apps.v1.StatefulSetSpec>
367
+
337
368
  super(
338
369
  "highstate:k8s:StatefulSetPatch",
339
370
  name,
@@ -349,7 +380,7 @@ class StatefulSetPatch extends StatefulSet {
349
380
  service,
350
381
  routes,
351
382
 
352
- statefulSet.spec,
383
+ filteredSpec,
353
384
  statefulSet.status,
354
385
  )
355
386
  }
package/src/tls.ts CHANGED
@@ -1,12 +1,13 @@
1
- import type { k8s } from "@highstate/library"
2
1
  import type { types } from "@pulumi/kubernetes"
3
2
  import { cert_manager, type types as cmTypes } from "@highstate/cert-manager"
4
3
  import { getOrCreate } from "@highstate/contract"
4
+ import { k8s } from "@highstate/library"
5
5
  import {
6
6
  type ComponentResourceOptions,
7
7
  type Input,
8
8
  type Inputs,
9
9
  interpolate,
10
+ makeEntityOutput,
10
11
  type Output,
11
12
  output,
12
13
  toPromise,
@@ -31,6 +32,22 @@ export type CreateOrGetCertificateArgs = CertificateArgs & {
31
32
  existing: Input<k8s.Certificate> | undefined
32
33
  }
33
34
 
35
+ const certManagerCertificateWaitFor = "condition=Ready"
36
+
37
+ function mapCertificateMetadata(
38
+ args: CertificateArgs,
39
+ fallbackName: string,
40
+ ): Output<types.input.meta.v1.ObjectMeta> {
41
+ return mapMetadata(args, fallbackName).apply(metadata => ({
42
+ ...metadata,
43
+ annotations: {
44
+ ...metadata.annotations,
45
+ "pulumi.com/waitFor":
46
+ metadata.annotations?.["pulumi.com/waitFor"] ?? certManagerCertificateWaitFor,
47
+ },
48
+ }))
49
+ }
50
+
34
51
  /**
35
52
  * Represents a cert-manager Certificate resource with metadata and secret.
36
53
  */
@@ -65,8 +82,17 @@ export abstract class Certificate extends NamespacedResource {
65
82
  /**
66
83
  * The Highstate certificate entity.
67
84
  */
68
- get entity(): Output<k8s.NamespacedResource> {
69
- return output(this.entityBase)
85
+ get entity(): Output<k8s.Certificate> {
86
+ return makeEntityOutput({
87
+ entity: k8s.certificateEntity,
88
+ identity: this.metadata.uid,
89
+ meta: {
90
+ title: this.metadata.name,
91
+ },
92
+ value: {
93
+ ...this.entityBase,
94
+ },
95
+ })
70
96
  }
71
97
 
72
98
  /**
@@ -228,7 +254,7 @@ class CreatedCertificate extends Certificate {
228
254
  return new cert_manager.v1.Certificate(
229
255
  name,
230
256
  {
231
- metadata: mapMetadata(args, name),
257
+ metadata: mapCertificateMetadata(args, name),
232
258
  spec: omit(args, commonExtraArgs),
233
259
  },
234
260
  { ...opts, parent: this, provider: getProvider(cluster) },
@@ -255,7 +281,7 @@ class CertificatePatch extends Certificate {
255
281
  return new cert_manager.v1.CertificatePatch(
256
282
  name,
257
283
  {
258
- metadata: mapMetadata(args, name),
284
+ metadata: mapCertificateMetadata(args, name),
259
285
  spec: omit(args, commonExtraArgs),
260
286
  },
261
287
  { ...opts, parent: this, provider: getProvider(cluster) },
@@ -5,18 +5,18 @@ import { forUnit, toPromise } from "@highstate/pulumi"
5
5
  const { args, inputs, outputs } = forUnit(k8s.clusterPatch)
6
6
 
7
7
  const cluster = await toPromise(inputs.k8sCluster)
8
- const endpoints = await parseEndpoints(args.endpoints, inputs.endpoints, 3)
9
- const apiEndpoints = await parseEndpoints(args.apiEndpoints, inputs.apiEndpoints, 4)
8
+ const endpoints = parseEndpoints([...args.endpoints, ...inputs.endpoints], 3)
9
+ const apiEndpoints = parseEndpoints([...args.apiEndpoints, ...inputs.apiEndpoints], 4)
10
10
 
11
11
  const newEndpoints = endpoints.length > 0 ? endpoints : cluster.endpoints
12
12
  const newApiEndpoints = apiEndpoints.length > 0 ? apiEndpoints : cluster.apiEndpoints
13
13
 
14
14
  export default outputs({
15
- k8sCluster: inputs.k8sCluster.apply(k8sCluster => ({
16
- ...k8sCluster,
15
+ k8sCluster: {
16
+ ...inputs.k8sCluster,
17
17
  endpoints: newEndpoints,
18
18
  apiEndpoints: newApiEndpoints,
19
- })),
19
+ },
20
20
 
21
21
  $statusFields: {
22
22
  endpoints: endpoints.map(l3EndpointToString),
@@ -1,11 +1,12 @@
1
1
  import { cert_manager } from "@highstate/cert-manager"
2
- import { k8s } from "@highstate/library"
3
- import { forUnit } from "@highstate/pulumi"
2
+ import { common, k8s } from "@highstate/library"
3
+ import { forUnit, makeEntityOutput } from "@highstate/pulumi"
4
4
  import { dns01SolverMediator } from "../../dns01-solver"
5
5
  import { Namespace } from "../../namespace"
6
+ import { Secret } from "../../secret"
6
7
  import { getProviderAsync } from "../../shared"
7
8
 
8
- const { name, inputs, outputs } = forUnit(k8s.dns01TlsIssuer)
9
+ const { name, args, secrets, inputs, outputs } = forUnit(k8s.dns01TlsIssuer)
9
10
 
10
11
  const provider = await getProviderAsync(inputs.k8sCluster)
11
12
 
@@ -14,6 +15,33 @@ const certManagerNs = Namespace.get("cert-manager", {
14
15
  cluster: inputs.k8sCluster,
15
16
  })
16
17
 
18
+ let eabSecret: Secret | undefined
19
+
20
+ if (args.acmeServer.type === "zerossl") {
21
+ if (!secrets.eabKeyId || !secrets.eabKeySecret) {
22
+ throw new Error("EAB key ID and secret are required for ZeroSSL ACME server")
23
+ }
24
+
25
+ eabSecret = Secret.create(`${name}-eab`, {
26
+ namespace: certManagerNs,
27
+ stringData: {
28
+ keyId: secrets.eabKeyId,
29
+ keySecret: secrets.eabKeySecret,
30
+ },
31
+ })
32
+ }
33
+
34
+ const getAcmeServer = () => {
35
+ switch (args.acmeServer.type) {
36
+ case "zerossl":
37
+ return "https://acme.zerossl.com/v2/DV90"
38
+ case "letsencrypt":
39
+ return "https://acme-v02.api.letsencrypt.org/directory"
40
+ case "custom":
41
+ return args.acmeServer.url
42
+ }
43
+ }
44
+
17
45
  new cert_manager.v1.ClusterIssuer(
18
46
  name,
19
47
  {
@@ -22,7 +50,7 @@ new cert_manager.v1.ClusterIssuer(
22
50
  },
23
51
  spec: {
24
52
  acme: {
25
- server: "https://acme-v02.api.letsencrypt.org/directory",
53
+ server: getAcmeServer(),
26
54
  solvers: [
27
55
  {
28
56
  dns01: dns01SolverMediator.callOutput(inputs.dnsProvider.implRef, {
@@ -34,6 +62,15 @@ new cert_manager.v1.ClusterIssuer(
34
62
  privateKeySecretRef: {
35
63
  name,
36
64
  },
65
+ externalAccountBinding: eabSecret
66
+ ? {
67
+ keyID: eabSecret.stringData.keyId,
68
+ keySecretRef: {
69
+ name: eabSecret.metadata.name,
70
+ key: "keySecret",
71
+ },
72
+ }
73
+ : undefined,
37
74
  },
38
75
  },
39
76
  },
@@ -41,16 +78,23 @@ new cert_manager.v1.ClusterIssuer(
41
78
  )
42
79
 
43
80
  export default outputs({
44
- tlsIssuer: {
45
- zones: inputs.dnsProvider.zones,
46
- implRef: {
47
- package: "@highstate/k8s",
48
- data: {
49
- clusterIssuerName: name,
50
- cluster: inputs.k8sCluster,
81
+ tlsIssuer: makeEntityOutput({
82
+ entity: common.tlsIssuerEntity,
83
+ identity: `${name}:tls-issuer`,
84
+ meta: {
85
+ title: name,
86
+ },
87
+ value: {
88
+ zones: inputs.dnsProvider.zones,
89
+ implRef: {
90
+ package: "@highstate/k8s",
91
+ data: {
92
+ clusterIssuerName: name,
93
+ cluster: inputs.k8sCluster,
94
+ },
51
95
  },
52
96
  },
53
- },
97
+ }),
54
98
 
55
99
  $statusFields: {
56
100
  zones: inputs.dnsProvider.zones,
@@ -7,8 +7,8 @@ import {
7
7
  parseEndpoint,
8
8
  parseEndpoints,
9
9
  } from "@highstate/common"
10
- import { type ImplementationReference, k8s } from "@highstate/library"
11
- import { forUnit, secret, toPromise } from "@highstate/pulumi"
10
+ import { common, type ImplementationReference, k8s } from "@highstate/library"
11
+ import { forUnit, makeEntityOutput, toPromise } from "@highstate/pulumi"
12
12
  import { AppsV1Api, KubeConfig } from "@kubernetes/client-node"
13
13
  import { core, Provider } from "@pulumi/kubernetes"
14
14
  import { createK8sTerminal, detectExternalIps } from "../../cluster"
@@ -47,7 +47,7 @@ if (args.autoDetectExternalIps) {
47
47
  }
48
48
 
49
49
  // calculate endpoints
50
- let endpoints = await parseEndpoints(args.endpoints, inputs.endpoints)
50
+ let endpoints = parseEndpoints([...args.endpoints, ...inputs.endpoints])
51
51
 
52
52
  if (args.useExternalIpsAsEndpoints) {
53
53
  const ipEndpoints = externalIps.map(ip => parseEndpoint(ip))
@@ -55,7 +55,7 @@ if (args.useExternalIpsAsEndpoints) {
55
55
  }
56
56
 
57
57
  // calculate api endpoints
58
- let apiEndpoints = await parseEndpoints(args.apiEndpoints, inputs.endpoints, 4)
58
+ let apiEndpoints = parseEndpoints([...args.apiEndpoints, ...inputs.endpoints], 4)
59
59
 
60
60
  if (args.useKubeconfigApiEndpoint) {
61
61
  const configEndpoint = parseEndpoint(kubeConfig.clusters[0].server.replace("https://", ""), 4)
@@ -65,17 +65,38 @@ if (args.useKubeconfigApiEndpoint) {
65
65
  const kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provider })
66
66
 
67
67
  export default outputs({
68
- k8sCluster: {
69
- id: kubeSystem.metadata.uid,
70
- connectionId: kubeSystem.metadata.uid,
71
- name,
72
- networkPolicyImplRef,
73
- externalIps,
74
- endpoints,
75
- apiEndpoints,
76
- quirks: args.quirks,
77
- kubeconfig: secret(kubeconfigContent),
78
- },
68
+ k8sCluster: makeEntityOutput({
69
+ entity: k8s.clusterEntity,
70
+ identity: kubeSystem.metadata.uid,
71
+ value: {
72
+ id: kubeSystem.metadata.uid,
73
+ connectionId: kubeSystem.metadata.uid,
74
+ name,
75
+ networkPolicyImplRef,
76
+ externalIps,
77
+ endpoints,
78
+ apiEndpoints,
79
+ quirks: args.quirks,
80
+ kubeconfig: makeEntityOutput({
81
+ entity: common.fileEntity,
82
+ identity: `${name}:kubeconfig`,
83
+ meta: {
84
+ title: "Kubeconfig",
85
+ },
86
+ value: {
87
+ content: {
88
+ type: "embedded-secret",
89
+ value: kubeconfigContent,
90
+ },
91
+ meta: {
92
+ name: "kubeconfig",
93
+ contentType: "text/yaml",
94
+ mode: 0o600,
95
+ },
96
+ },
97
+ }),
98
+ },
99
+ }),
79
100
 
80
101
  $terminals: [createK8sTerminal(kubeconfigContent)],
81
102
 
@@ -1,10 +1,11 @@
1
1
  import { text, trimIndentation } from "@highstate/contract"
2
2
  import { k8s } from "@highstate/library"
3
- import { fileFromString, forUnit, interpolate, output, secret, toPromise } from "@highstate/pulumi"
3
+ import { forUnit, interpolate, makeFileOutput, output, secret, toPromise } from "@highstate/pulumi"
4
4
  import { join } from "remeda"
5
5
  import { createK8sTerminal } from "../../cluster"
6
6
  import { Namespace } from "../../namespace"
7
7
  import { ClusterAccessScope } from "../../rbac"
8
+ import { getClusterKubeconfigContent } from "../../shared"
8
9
 
9
10
  const { args, inputs, outputs } = forUnit(k8s.reducedAccessCluster)
10
11
 
@@ -34,7 +35,7 @@ const resourceLines = await toPromise(
34
35
  export default outputs({
35
36
  k8sCluster: accessScope.cluster,
36
37
 
37
- $terminals: [createK8sTerminal(accessScope.cluster.kubeconfig)],
38
+ $terminals: [createK8sTerminal(secret(getClusterKubeconfigContent(accessScope.cluster)))],
38
39
 
39
40
  $pages: {
40
41
  index: {
@@ -58,7 +59,9 @@ export default outputs({
58
59
  },
59
60
  {
60
61
  type: "file",
61
- file: fileFromString("kubeconfig", accessScope.cluster.kubeconfig, {
62
+ file: makeFileOutput({
63
+ name: "kubeconfig",
64
+ content: secret(getClusterKubeconfigContent(accessScope.cluster)),
62
65
  contentType: "text/yaml",
63
66
  isSecret: true,
64
67
  }),
package/src/worker.ts CHANGED
@@ -4,7 +4,7 @@ import type { DeepInput, Input, InputArray, Unwrap } from "@highstate/pulumi"
4
4
  import type { Namespace } from "./namespace"
5
5
  import { type Output, output } from "@pulumi/pulumi"
6
6
  import { ClusterAccessScope } from "./rbac"
7
- import { images, type NamespacedResource } from "./shared"
7
+ import { getClusterKubeconfigContent, images, type NamespacedResource } from "./shared"
8
8
 
9
9
  export async function createMonitorWorker(
10
10
  namespace: Input<Namespace>,
@@ -12,6 +12,8 @@ export async function createMonitorWorker(
12
12
  ): Promise<Output<Unwrap<UnitWorker>>> {
13
13
  const scope = new ClusterAccessScope("monitor", {
14
14
  rule: {
15
+ apiGroups: ["", "apps"],
16
+ resources: ["deployments", "statefulsets", "services", "pods"],
15
17
  verbs: ["get", "list", "watch"],
16
18
  },
17
19
 
@@ -24,7 +26,7 @@ export async function createMonitorWorker(
24
26
  image: images["worker.k8s-monitor"].image,
25
27
 
26
28
  params: {
27
- kubeconfig: scope.cluster.kubeconfig,
29
+ kubeconfig: getClusterKubeconfigContent(scope.cluster),
28
30
  resources: output(resources).apply(resources => resources.map(r => r.entity)),
29
31
  } satisfies DeepInput<k8s.MonitorWorkerParams>,
30
32
  })