@highstate/k8s 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/{chunk-FE4SHRAJ.js → chunk-23X5SXQG.js} +22 -7
  2. package/dist/chunk-23X5SXQG.js.map +1 -0
  3. package/dist/{chunk-LGHFSXNT.js → chunk-ADHZK6V2.js} +14 -10
  4. package/dist/chunk-ADHZK6V2.js.map +1 -0
  5. package/dist/{chunk-VCXWCZ43.js → chunk-BTAEFJ5N.js} +27 -15
  6. package/dist/chunk-BTAEFJ5N.js.map +1 -0
  7. package/dist/{chunk-BR2CLUUD.js → chunk-IXE3OKB4.js} +27 -8
  8. package/dist/chunk-IXE3OKB4.js.map +1 -0
  9. package/dist/{chunk-TWBMG6TD.js → chunk-OG2OPX7B.js} +30 -12
  10. package/dist/chunk-OG2OPX7B.js.map +1 -0
  11. package/dist/{chunk-DCUMJSO6.js → chunk-P26SQ2ZB.js} +17 -51
  12. package/dist/chunk-P26SQ2ZB.js.map +1 -0
  13. package/dist/{chunk-MIC2BHGS.js → chunk-PG27ZY2H.js} +25 -7
  14. package/dist/chunk-PG27ZY2H.js.map +1 -0
  15. package/dist/chunk-PZYGZSN5.js +54 -0
  16. package/dist/{chunk-PZ5AY32C.js.map → chunk-PZYGZSN5.js.map} +1 -1
  17. package/dist/{chunk-YIJUVPU2.js → chunk-S77TE7UC.js} +27 -15
  18. package/dist/chunk-S77TE7UC.js.map +1 -0
  19. package/dist/{chunk-P2VOUU7E.js → chunk-SZKOAHNX.js} +383 -205
  20. package/dist/chunk-SZKOAHNX.js.map +1 -0
  21. package/dist/chunk-TOLFVF4S.js +889 -0
  22. package/dist/chunk-TOLFVF4S.js.map +1 -0
  23. package/dist/{chunk-RVB4WWZZ.js → chunk-TVKT3ZYX.js} +174 -18
  24. package/dist/chunk-TVKT3ZYX.js.map +1 -0
  25. package/dist/cron-job-RKB2HYTO.js +7 -0
  26. package/dist/{cron-job-NX4HD4FI.js.map → cron-job-RKB2HYTO.js.map} +1 -1
  27. package/dist/deployment-T35TUOL2.js +7 -0
  28. package/dist/{deployment-O2LJ5WR5.js.map → deployment-T35TUOL2.js.map} +1 -1
  29. package/dist/highstate.manifest.json +3 -2
  30. package/dist/impl/dynamic-endpoint-resolver.js +90 -0
  31. package/dist/impl/dynamic-endpoint-resolver.js.map +1 -0
  32. package/dist/impl/gateway-route.js +159 -62
  33. package/dist/impl/gateway-route.js.map +1 -1
  34. package/dist/impl/tls-certificate.js +6 -5
  35. package/dist/impl/tls-certificate.js.map +1 -1
  36. package/dist/index.js +106 -23
  37. package/dist/index.js.map +1 -1
  38. package/dist/job-PE4AKOHB.js +7 -0
  39. package/dist/job-PE4AKOHB.js.map +1 -0
  40. package/dist/stateful-set-LUIRHQJY.js +7 -0
  41. package/dist/{stateful-set-VJYKTQ72.js.map → stateful-set-LUIRHQJY.js.map} +1 -1
  42. package/dist/units/cert-manager/index.js +7 -8
  43. package/dist/units/cert-manager/index.js.map +1 -1
  44. package/dist/units/cluster-patch/index.js +6 -6
  45. package/dist/units/cluster-patch/index.js.map +1 -1
  46. package/dist/units/dns01-issuer/index.js +52 -15
  47. package/dist/units/dns01-issuer/index.js.map +1 -1
  48. package/dist/units/existing-cluster/index.js +39 -18
  49. package/dist/units/existing-cluster/index.js.map +1 -1
  50. package/dist/units/gateway-api/index.js +2 -2
  51. package/dist/units/reduced-access-cluster/index.js +8 -8
  52. package/dist/units/reduced-access-cluster/index.js.map +1 -1
  53. package/package.json +9 -7
  54. package/src/cluster.ts +12 -8
  55. package/src/config-map.ts +15 -5
  56. package/src/container.ts +4 -2
  57. package/src/cron-job.ts +25 -4
  58. package/src/deployment.ts +32 -17
  59. package/src/gateway/backend.ts +3 -3
  60. package/src/gateway/gateway.ts +12 -56
  61. package/src/helm.ts +354 -22
  62. package/src/impl/dynamic-endpoint-resolver.ts +109 -0
  63. package/src/impl/gateway-route.ts +231 -57
  64. package/src/impl/tls-certificate.ts +8 -3
  65. package/src/index.ts +1 -0
  66. package/src/job.ts +23 -5
  67. package/src/kubectl.ts +166 -0
  68. package/src/namespace.ts +47 -3
  69. package/src/network-policy.ts +1 -1
  70. package/src/pvc.ts +12 -2
  71. package/src/rbac.ts +28 -5
  72. package/src/scripting/environment.ts +3 -2
  73. package/src/secret.ts +15 -5
  74. package/src/service.ts +28 -6
  75. package/src/shared.ts +30 -2
  76. package/src/stateful-set.ts +32 -17
  77. package/src/tls.ts +31 -5
  78. package/src/units/cluster-patch/index.ts +5 -5
  79. package/src/units/dns01-issuer/index.ts +56 -12
  80. package/src/units/existing-cluster/index.ts +36 -15
  81. package/src/units/reduced-access-cluster/index.ts +6 -3
  82. package/src/worker.ts +4 -2
  83. package/src/workload.ts +453 -213
  84. package/dist/chunk-4G6LLC2X.js +0 -240
  85. package/dist/chunk-4G6LLC2X.js.map +0 -1
  86. package/dist/chunk-BR2CLUUD.js.map +0 -1
  87. package/dist/chunk-DCUMJSO6.js.map +0 -1
  88. package/dist/chunk-FE4SHRAJ.js.map +0 -1
  89. package/dist/chunk-KMLRI5UZ.js +0 -155
  90. package/dist/chunk-KMLRI5UZ.js.map +0 -1
  91. package/dist/chunk-LGHFSXNT.js.map +0 -1
  92. package/dist/chunk-MIC2BHGS.js.map +0 -1
  93. package/dist/chunk-OBDQONMV.js +0 -401
  94. package/dist/chunk-OBDQONMV.js.map +0 -1
  95. package/dist/chunk-P2VOUU7E.js.map +0 -1
  96. package/dist/chunk-PZ5AY32C.js +0 -9
  97. package/dist/chunk-RVB4WWZZ.js.map +0 -1
  98. package/dist/chunk-TWBMG6TD.js.map +0 -1
  99. package/dist/chunk-VCXWCZ43.js.map +0 -1
  100. package/dist/chunk-YIJUVPU2.js.map +0 -1
  101. package/dist/cron-job-NX4HD4FI.js +0 -8
  102. package/dist/deployment-O2LJ5WR5.js +0 -8
  103. package/dist/job-SYME6Y43.js +0 -8
  104. package/dist/job-SYME6Y43.js.map +0 -1
  105. package/dist/stateful-set-VJYKTQ72.js +0 -8
@@ -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
  })