@highstate/k8s 0.9.3 → 0.9.5
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.
- package/dist/chunk-DQSCJM5S.js +183 -0
- package/dist/chunk-DQSCJM5S.js.map +1 -0
- package/dist/chunk-FKNHHKOL.js +260 -0
- package/dist/chunk-FKNHHKOL.js.map +1 -0
- package/dist/chunk-HW3NS3MC.js +347 -0
- package/dist/chunk-HW3NS3MC.js.map +1 -0
- package/dist/chunk-OQ7UXASD.js +193 -0
- package/dist/chunk-OQ7UXASD.js.map +1 -0
- package/dist/chunk-QGHMLKTW.js +1123 -0
- package/dist/chunk-QGHMLKTW.js.map +1 -0
- package/dist/chunk-UNVSWG6D.js +214 -0
- package/dist/chunk-UNVSWG6D.js.map +1 -0
- package/dist/deployment-ZP3ASKPT.js +10 -0
- package/dist/deployment-ZP3ASKPT.js.map +1 -0
- package/dist/highstate.manifest.json +8 -6
- package/dist/index.js +291 -954
- package/dist/index.js.map +1 -1
- package/dist/stateful-set-2AH7RAF7.js +10 -0
- package/dist/stateful-set-2AH7RAF7.js.map +1 -0
- package/dist/units/access-point/index.js +6 -1
- package/dist/units/access-point/index.js.map +1 -1
- package/dist/units/cert-manager/index.js +19 -24
- package/dist/units/cert-manager/index.js.map +1 -1
- package/dist/units/cluster-dns/index.js +36 -0
- package/dist/units/cluster-dns/index.js.map +1 -0
- package/dist/units/cluster-patch/index.js +34 -0
- package/dist/units/cluster-patch/index.js.map +1 -0
- package/dist/units/dns01-issuer/index.js +2 -2
- package/dist/units/dns01-issuer/index.js.map +1 -1
- package/dist/units/existing-cluster/index.js +23 -15
- package/dist/units/existing-cluster/index.js.map +1 -1
- package/dist/units/gateway-api/index.js +1 -1
- package/package.json +12 -10
- package/src/access-point.ts +44 -39
- package/src/container.ts +54 -5
- package/src/cron-job.ts +14 -30
- package/src/deployment.ts +170 -127
- package/src/gateway/http-route.ts +7 -5
- package/src/helm.ts +57 -8
- package/src/index.ts +11 -4
- package/src/job.ts +14 -32
- package/src/namespace.ts +241 -0
- package/src/network-policy.ts +371 -87
- package/src/network.ts +41 -0
- package/src/pvc.ts +43 -25
- package/src/scripting/bundle.ts +125 -22
- package/src/scripting/container.ts +16 -11
- package/src/scripting/environment.ts +56 -6
- package/src/secret.ts +195 -0
- package/src/service.ts +209 -89
- package/src/shared.ts +42 -51
- package/src/stateful-set.ts +193 -88
- package/src/units/access-point/index.ts +8 -1
- package/src/units/cert-manager/index.ts +15 -20
- package/src/units/cluster-dns/index.ts +37 -0
- package/src/units/cluster-patch/index.ts +35 -0
- package/src/units/dns01-issuer/index.ts +1 -1
- package/src/units/existing-cluster/index.ts +26 -15
- package/src/workload.ts +342 -44
- package/dist/chunk-K4WKJ4L5.js +0 -455
- package/dist/chunk-K4WKJ4L5.js.map +0 -1
- package/dist/chunk-T5Z2M4JE.js +0 -103
- package/dist/chunk-T5Z2M4JE.js.map +0 -1
@@ -8,10 +8,16 @@ import { k8s } from "@highstate/library";
|
|
8
8
|
import { forUnit, secret, toPromise } from "@highstate/pulumi";
|
9
9
|
import { core, Provider } from "@pulumi/kubernetes";
|
10
10
|
import { KubeConfig, AppsV1Api } from "@kubernetes/client-node";
|
11
|
+
import {
|
12
|
+
l3EndpointToString,
|
13
|
+
l4EndpointToString,
|
14
|
+
parseL3Endpoint,
|
15
|
+
parseL4Endpoint
|
16
|
+
} from "@highstate/common";
|
11
17
|
var { name, args, secrets, outputs } = forUnit(k8s.existingCluster);
|
12
18
|
var kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringify));
|
13
19
|
var provider = new Provider(name, { kubeconfig: kubeconfigContent });
|
14
|
-
var cni;
|
20
|
+
var cni = "other";
|
15
21
|
var kubeConfig = new KubeConfig();
|
16
22
|
kubeConfig.loadFromString(kubeconfigContent);
|
17
23
|
var appsApi = kubeConfig.makeApiClient(AppsV1Api);
|
@@ -19,27 +25,29 @@ var isCilium = await appsApi.readNamespacedDaemonSet({ name: "cilium", namespace
|
|
19
25
|
if (isCilium) {
|
20
26
|
cni = "cilium";
|
21
27
|
}
|
22
|
-
var externalIps = await detectExternalIps(kubeConfig, args.internalIpsPolicy);
|
28
|
+
var externalIps = args.externalIps ?? await detectExternalIps(kubeConfig, args.internalIpsPolicy);
|
29
|
+
var endpoints = externalIps.map(parseL3Endpoint);
|
30
|
+
var apiEndpoints = [parseL4Endpoint(kubeConfig.clusters[0].server.replace("https://", ""))];
|
23
31
|
var kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provider });
|
24
32
|
var existing_cluster_default = outputs({
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
k8sCluster: {
|
34
|
+
id: kubeSystem.metadata.uid,
|
35
|
+
name,
|
36
|
+
cni,
|
37
|
+
externalIps,
|
38
|
+
endpoints,
|
39
|
+
apiEndpoints,
|
40
|
+
quirks: args.quirks,
|
33
41
|
kubeconfig: secret(kubeconfigContent)
|
34
42
|
},
|
43
|
+
endpoints,
|
44
|
+
apiEndpoints,
|
35
45
|
$terminals: [createK8sTerminal(kubeconfigContent)],
|
36
46
|
$status: {
|
37
47
|
clusterId: kubeSystem.metadata.uid,
|
38
|
-
cni
|
39
|
-
|
40
|
-
|
41
|
-
complementaryTo: "externalIps"
|
42
|
-
}
|
48
|
+
cni,
|
49
|
+
endpoints: endpoints.map(l3EndpointToString),
|
50
|
+
apiEndpoints: apiEndpoints.map(l4EndpointToString)
|
43
51
|
}
|
44
52
|
});
|
45
53
|
export {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/units/existing-cluster/index.ts"],"sourcesContent":["import { k8s } from \"@highstate/library\"\nimport { forUnit, secret, toPromise } from \"@highstate/pulumi\"\nimport { core, Provider } from \"@pulumi/kubernetes\"\nimport { KubeConfig, AppsV1Api } from \"@kubernetes/client-node\"\nimport { createK8sTerminal, detectExternalIps } from \"../../cluster\"\n\nconst { name, args, secrets, outputs } = forUnit(k8s.existingCluster)\n\nconst kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringify))\n\nconst provider = new Provider(name, { kubeconfig: kubeconfigContent })\n\nlet cni:
|
1
|
+
{"version":3,"sources":["../../../src/units/existing-cluster/index.ts"],"sourcesContent":["import { k8s } from \"@highstate/library\"\nimport { forUnit, secret, toPromise } from \"@highstate/pulumi\"\nimport { core, Provider } from \"@pulumi/kubernetes\"\nimport { KubeConfig, AppsV1Api } from \"@kubernetes/client-node\"\nimport {\n l3EndpointToString,\n l4EndpointToString,\n parseL3Endpoint,\n parseL4Endpoint,\n} from \"@highstate/common\"\nimport { createK8sTerminal, detectExternalIps } from \"../../cluster\"\n\nconst { name, args, secrets, outputs } = forUnit(k8s.existingCluster)\n\nconst kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringify))\n\nconst provider = new Provider(name, { kubeconfig: kubeconfigContent })\n\nlet cni: k8s.CNI = \"other\"\n\nconst kubeConfig = new KubeConfig()\nkubeConfig.loadFromString(kubeconfigContent)\n\nconst appsApi = kubeConfig.makeApiClient(AppsV1Api)\n\nconst isCilium = await appsApi\n .readNamespacedDaemonSet({ name: \"cilium\", namespace: \"kube-system\" })\n .then(() => true)\n .catch(() => false)\n\nif (isCilium) {\n cni = \"cilium\"\n}\n\nconst externalIps =\n args.externalIps ?? (await detectExternalIps(kubeConfig, args.internalIpsPolicy))\n\nconst endpoints = externalIps.map(parseL3Endpoint)\nconst apiEndpoints = [parseL4Endpoint(kubeConfig.clusters[0].server.replace(\"https://\", \"\"))]\n\nconst kubeSystem = core.v1.Namespace.get(\"kube-system\", \"kube-system\", { provider })\n\nexport default outputs({\n k8sCluster: {\n id: kubeSystem.metadata.uid,\n name,\n cni,\n externalIps,\n endpoints,\n apiEndpoints,\n quirks: args.quirks,\n kubeconfig: secret(kubeconfigContent),\n },\n\n endpoints,\n apiEndpoints,\n\n $terminals: [createK8sTerminal(kubeconfigContent)],\n\n $status: {\n clusterId: kubeSystem.metadata.uid,\n cni,\n endpoints: endpoints.map(l3EndpointToString),\n apiEndpoints: apiEndpoints.map(l4EndpointToString),\n },\n})\n"],"mappings":";;;;;;AAAA,SAAS,WAAW;AACpB,SAAS,SAAS,QAAQ,iBAAiB;AAC3C,SAAS,MAAM,gBAAgB;AAC/B,SAAS,YAAY,iBAAiB;AACtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,IAAM,EAAE,MAAM,MAAM,SAAS,QAAQ,IAAI,QAAQ,IAAI,eAAe;AAEpE,IAAM,oBAAoB,MAAM,UAAU,QAAQ,WAAW,MAAM,KAAK,SAAS,CAAC;AAElF,IAAM,WAAW,IAAI,SAAS,MAAM,EAAE,YAAY,kBAAkB,CAAC;AAErE,IAAI,MAAe;AAEnB,IAAM,aAAa,IAAI,WAAW;AAClC,WAAW,eAAe,iBAAiB;AAE3C,IAAM,UAAU,WAAW,cAAc,SAAS;AAElD,IAAM,WAAW,MAAM,QACpB,wBAAwB,EAAE,MAAM,UAAU,WAAW,cAAc,CAAC,EACpE,KAAK,MAAM,IAAI,EACf,MAAM,MAAM,KAAK;AAEpB,IAAI,UAAU;AACZ,QAAM;AACR;AAEA,IAAM,cACJ,KAAK,eAAgB,MAAM,kBAAkB,YAAY,KAAK,iBAAiB;AAEjF,IAAM,YAAY,YAAY,IAAI,eAAe;AACjD,IAAM,eAAe,CAAC,gBAAgB,WAAW,SAAS,CAAC,EAAE,OAAO,QAAQ,YAAY,EAAE,CAAC,CAAC;AAE5F,IAAM,aAAa,KAAK,GAAG,UAAU,IAAI,eAAe,eAAe,EAAE,SAAS,CAAC;AAEnF,IAAO,2BAAQ,QAAQ;AAAA,EACrB,YAAY;AAAA,IACV,IAAI,WAAW,SAAS;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,YAAY,OAAO,iBAAiB;AAAA,EACtC;AAAA,EAEA;AAAA,EACA;AAAA,EAEA,YAAY,CAAC,kBAAkB,iBAAiB,CAAC;AAAA,EAEjD,SAAS;AAAA,IACP,WAAW,WAAW,SAAS;AAAA,IAC/B;AAAA,IACA,WAAW,UAAU,IAAI,kBAAkB;AAAA,IAC3C,cAAc,aAAa,IAAI,kBAAkB;AAAA,EACnD;AACF,CAAC;","names":[]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@highstate/k8s",
|
3
|
-
"version": "0.9.
|
3
|
+
"version": "0.9.5",
|
4
4
|
"type": "module",
|
5
5
|
"files": [
|
6
6
|
"dist",
|
@@ -13,6 +13,8 @@
|
|
13
13
|
},
|
14
14
|
"./units/access-point": "./dist/units/access-point/index.js",
|
15
15
|
"./units/cert-manager": "./dist/units/cert-manager/index.js",
|
16
|
+
"./units/cluster-patch": "./dist/units/cluster-patch/index.js",
|
17
|
+
"./units/cluster-dns": "./dist/units/cluster-dns/index.js",
|
16
18
|
"./units/dns01-issuer": "./dist/units/dns01-issuer/index.js",
|
17
19
|
"./units/existing-cluster": "./dist/units/existing-cluster/index.js",
|
18
20
|
"./units/gateway-api": "./dist/units/gateway-api/index.js"
|
@@ -26,12 +28,12 @@
|
|
26
28
|
"generate-crds": "./scripts/generate-crds.sh"
|
27
29
|
},
|
28
30
|
"dependencies": {
|
29
|
-
"@highstate/cert-manager": "^0.9.
|
30
|
-
"@highstate/common": "^0.9.
|
31
|
-
"@highstate/contract": "^0.9.
|
32
|
-
"@highstate/gateway-api": "^0.9.
|
33
|
-
"@highstate/library": "^0.9.
|
34
|
-
"@highstate/pulumi": "^0.9.
|
31
|
+
"@highstate/cert-manager": "^0.9.5",
|
32
|
+
"@highstate/common": "^0.9.5",
|
33
|
+
"@highstate/contract": "^0.9.5",
|
34
|
+
"@highstate/gateway-api": "^0.9.5",
|
35
|
+
"@highstate/library": "^0.9.5",
|
36
|
+
"@highstate/pulumi": "^0.9.5",
|
35
37
|
"@kubernetes/client-node": "^1.1.0",
|
36
38
|
"@pulumi/command": "^1.0.2",
|
37
39
|
"@pulumi/kubernetes": "^4.18.0",
|
@@ -40,11 +42,11 @@
|
|
40
42
|
"deepmerge-ts": "^7.1.5",
|
41
43
|
"glob": "^11.0.1",
|
42
44
|
"nano-spawn": "^0.2.0",
|
43
|
-
"
|
45
|
+
"pkg-types": "^2.1.0",
|
44
46
|
"remeda": "^2.21.0"
|
45
47
|
},
|
46
48
|
"devDependencies": {
|
47
|
-
"@highstate/cli": "^0.9.
|
49
|
+
"@highstate/cli": "^0.9.5"
|
48
50
|
},
|
49
|
-
"gitHead": "
|
51
|
+
"gitHead": "93fa1e8b1189a5232055c852fd79a684d8b80444"
|
50
52
|
}
|
package/src/access-point.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import type { k8s } from "@highstate/library"
|
2
|
-
import type {
|
3
|
-
import {
|
2
|
+
import type { Provider } from "@pulumi/kubernetes"
|
3
|
+
import type { Namespace } from "./namespace"
|
4
|
+
import { DnsRecordSet, filterEndpoints, l3EndpointToString } from "@highstate/common"
|
4
5
|
import { gateway } from "@highstate/gateway-api"
|
5
6
|
import {
|
6
7
|
normalize,
|
@@ -11,7 +12,8 @@ import {
|
|
11
12
|
type InputArray,
|
12
13
|
} from "@highstate/pulumi"
|
13
14
|
import { NetworkPolicy } from "./network-policy"
|
14
|
-
import {
|
15
|
+
import { getProvider, mapNamespaceLikeToNamespaceName } from "./shared"
|
16
|
+
import { isFromCluster } from "./service"
|
15
17
|
|
16
18
|
export type UseAccessPointResult = {
|
17
19
|
/**
|
@@ -20,9 +22,9 @@ export type UseAccessPointResult = {
|
|
20
22
|
gateway: gateway.v1.Gateway
|
21
23
|
|
22
24
|
/**
|
23
|
-
* The DNS record associated created according to the access point and gateway.
|
25
|
+
* The DNS record sets associated created according to the access point and gateway.
|
24
26
|
*/
|
25
|
-
|
27
|
+
dnsRecordSets: DnsRecordSet[]
|
26
28
|
|
27
29
|
/**
|
28
30
|
* The network policies associated with the access point.
|
@@ -37,6 +39,12 @@ export type UseAccessPointArgs = Omit<CreateGatewayArgs, "gateway"> & {
|
|
37
39
|
export function useAccessPoint(args: UseAccessPointArgs): Promise<UseAccessPointResult> {
|
38
40
|
const result = output({ args, namespaceName: output(args.namespace).metadata.name }).apply(
|
39
41
|
({ args, namespaceName }) => {
|
42
|
+
if (args.accessPoint.clusterId !== args.cluster.id) {
|
43
|
+
throw new Error(
|
44
|
+
"The provided Kubernetes cluster is different from the one where the access point is deployed.",
|
45
|
+
)
|
46
|
+
}
|
47
|
+
|
40
48
|
const gateway = createGateway({
|
41
49
|
...args,
|
42
50
|
annotations: {
|
@@ -45,43 +53,41 @@ export function useAccessPoint(args: UseAccessPointArgs): Promise<UseAccessPoint
|
|
45
53
|
gateway: args.accessPoint.gateway,
|
46
54
|
})
|
47
55
|
|
48
|
-
const
|
49
|
-
return
|
56
|
+
const dnsRecordSets = normalize(args.fqdn, args.fqdns).flatMap(fqdn => {
|
57
|
+
return DnsRecordSet.create(fqdn, {
|
50
58
|
providers: args.accessPoint.dnsProviders,
|
51
|
-
|
52
|
-
|
59
|
+
values: filterEndpoints(
|
60
|
+
args.accessPoint.gateway.endpoints.filter(endpoint => endpoint.type !== "hostname"),
|
61
|
+
),
|
53
62
|
})
|
54
63
|
})
|
55
64
|
|
56
|
-
const networkPolicies: Output<NetworkPolicy>[] = [
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
NetworkPolicy.create(
|
63
|
-
`allow-ingress-from-${getAppName(args.accessPoint.gateway.service.metadata)}`,
|
64
|
-
{
|
65
|
-
namespace: args.namespace,
|
66
|
-
cluster: args.cluster,
|
65
|
+
const networkPolicies: Output<NetworkPolicy>[] = [
|
66
|
+
NetworkPolicy.create(
|
67
|
+
`allow-ingress-from-${l3EndpointToString(args.accessPoint.gateway.endpoints[0])}`,
|
68
|
+
{
|
69
|
+
namespace: args.namespace,
|
70
|
+
cluster: args.cluster,
|
67
71
|
|
68
|
-
|
72
|
+
description: `Allow ingress traffic from the gateway at "${l3EndpointToString(args.accessPoint.gateway.endpoints[0])}".`,
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
fromSelector: args.accessPoint.gateway.service.spec.selector,
|
73
|
-
},
|
74
|
+
ingressRule: {
|
75
|
+
fromEndpoints: args.accessPoint.gateway.endpoints,
|
74
76
|
},
|
75
|
-
|
76
|
-
|
77
|
+
},
|
78
|
+
{ provider: args.provider },
|
79
|
+
),
|
80
|
+
]
|
77
81
|
|
82
|
+
if (isFromCluster(args.accessPoint.gateway.endpoints[0], args.cluster)) {
|
83
|
+
networkPolicies.push(
|
78
84
|
NetworkPolicy.create(
|
79
85
|
`allow-egress-to-${namespaceName}`,
|
80
86
|
{
|
81
|
-
namespace: args.accessPoint.gateway.
|
87
|
+
namespace: args.accessPoint.gateway.endpoints[0].metadata.k8sService.namespace,
|
82
88
|
cluster: args.cluster,
|
83
89
|
|
84
|
-
selector: args.accessPoint.gateway.
|
90
|
+
selector: args.accessPoint.gateway.endpoints[0].metadata.k8sService.selector,
|
85
91
|
|
86
92
|
description: `Allow egress traffic to the namespace "${namespaceName}".`,
|
87
93
|
|
@@ -96,7 +102,7 @@ export function useAccessPoint(args: UseAccessPointArgs): Promise<UseAccessPoint
|
|
96
102
|
|
97
103
|
return output({
|
98
104
|
gateway,
|
99
|
-
|
105
|
+
dnsRecordSets,
|
100
106
|
networkPolicies,
|
101
107
|
})
|
102
108
|
},
|
@@ -106,6 +112,7 @@ export function useAccessPoint(args: UseAccessPointArgs): Promise<UseAccessPoint
|
|
106
112
|
}
|
107
113
|
|
108
114
|
export type StandardAccessPointArgs = {
|
115
|
+
appName: string
|
109
116
|
fqdn: string
|
110
117
|
}
|
111
118
|
|
@@ -114,28 +121,26 @@ export type StandardAccessPointInputs = {
|
|
114
121
|
k8sCluster: Output<k8s.Cluster>
|
115
122
|
}
|
116
123
|
|
117
|
-
export function useStandardAcessPoint(
|
118
|
-
|
119
|
-
namespace: core.v1.Namespace,
|
124
|
+
export async function useStandardAcessPoint(
|
125
|
+
namespace: Namespace,
|
120
126
|
args: StandardAccessPointArgs,
|
121
127
|
inputs: StandardAccessPointInputs,
|
122
|
-
provider: Provider,
|
123
128
|
): Promise<UseAccessPointResult> {
|
124
|
-
return useAccessPoint({
|
125
|
-
name: appName,
|
129
|
+
return await useAccessPoint({
|
130
|
+
name: args.appName,
|
126
131
|
namespace,
|
127
132
|
|
128
133
|
fqdn: args.fqdn,
|
129
134
|
|
130
135
|
accessPoint: inputs.accessPoint,
|
131
136
|
cluster: inputs.k8sCluster,
|
132
|
-
provider,
|
137
|
+
provider: await getProvider(inputs.k8sCluster),
|
133
138
|
})
|
134
139
|
}
|
135
140
|
|
136
141
|
export type CreateGatewayArgs = {
|
137
142
|
name: string
|
138
|
-
namespace: Input<
|
143
|
+
namespace: Input<Namespace>
|
139
144
|
annotations?: Input<Record<string, string>>
|
140
145
|
|
141
146
|
fqdn?: Input<string>
|
@@ -148,7 +153,7 @@ export type CreateGatewayArgs = {
|
|
148
153
|
|
149
154
|
export function createGateway(args: CreateGatewayArgs): Output<gateway.v1.Gateway> {
|
150
155
|
return output(args).apply(args => {
|
151
|
-
if (args.cluster.
|
156
|
+
if (args.cluster.id !== args.gateway.clusterId) {
|
152
157
|
throw new Error(
|
153
158
|
"The provided Kubernetes cluster is different from the one where the gateway controller is deployed.",
|
154
159
|
)
|
package/src/container.ts
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
import type { PartialKeys } from "@highstate/contract"
|
2
|
+
import type { k8s, network } from "@highstate/library"
|
2
3
|
import { core, type types } from "@pulumi/kubernetes"
|
3
4
|
import { normalize, output, type Input, type InputArray, type Unwrap } from "@highstate/pulumi"
|
4
5
|
import { concat, map, omit } from "remeda"
|
5
6
|
import { PersistentVolumeClaim } from "./pvc"
|
7
|
+
import { Secret } from "./secret"
|
6
8
|
|
7
9
|
export type Container = Omit<PartialKeys<types.input.core.v1.Container, "name">, "volumeMounts"> & {
|
8
10
|
/**
|
@@ -51,6 +53,20 @@ export type Container = Omit<PartialKeys<types.input.core.v1.Container, "name">,
|
|
51
53
|
* It is like the `envFrom` property, but more convenient to use.
|
52
54
|
*/
|
53
55
|
environmentSources?: InputArray<ContainerEnvironmentSource>
|
56
|
+
|
57
|
+
/**
|
58
|
+
* The list of endpoints that the container is allowed to access.
|
59
|
+
*
|
60
|
+
* This is used to generate a network policy.
|
61
|
+
*/
|
62
|
+
allowedEndpoints?: InputArray<network.L34Endpoint>
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Enable the TUN device in the container.
|
66
|
+
*
|
67
|
+
* All necessary security context settings will be applied to the container.
|
68
|
+
*/
|
69
|
+
enableTun?: Input<boolean>
|
54
70
|
}
|
55
71
|
|
56
72
|
const containerExtraArgs = [
|
@@ -73,7 +89,7 @@ export type ContainerEnvironmentVariable =
|
|
73
89
|
/**
|
74
90
|
* The secret to select from.
|
75
91
|
*/
|
76
|
-
secret: Input<core.v1.Secret>
|
92
|
+
secret: Input<core.v1.Secret | Secret>
|
77
93
|
|
78
94
|
/**
|
79
95
|
* The key of the secret to select from.
|
@@ -110,16 +126,18 @@ export type WorkloadVolume =
|
|
110
126
|
| types.input.core.v1.Volume
|
111
127
|
| core.v1.PersistentVolumeClaim
|
112
128
|
| PersistentVolumeClaim
|
129
|
+
| Secret
|
113
130
|
| core.v1.ConfigMap
|
114
131
|
| core.v1.Secret
|
115
132
|
|
116
133
|
export function mapContainerToRaw(
|
117
134
|
container: Unwrap<Container>,
|
135
|
+
cluster: k8s.Cluster,
|
118
136
|
fallbackName: string,
|
119
137
|
): types.input.core.v1.Container {
|
120
138
|
const containerName = container.name ?? fallbackName
|
121
139
|
|
122
|
-
|
140
|
+
const spec = {
|
123
141
|
...omit(container, containerExtraArgs),
|
124
142
|
|
125
143
|
name: containerName,
|
@@ -139,7 +157,29 @@ export function mapContainerToRaw(
|
|
139
157
|
),
|
140
158
|
container.envFrom ?? [],
|
141
159
|
),
|
160
|
+
} as Unwrap<types.input.core.v1.Container>
|
161
|
+
|
162
|
+
if (container.enableTun) {
|
163
|
+
spec.securityContext ??= {}
|
164
|
+
spec.securityContext.capabilities ??= {}
|
165
|
+
spec.securityContext.capabilities.add = ["NET_ADMIN"]
|
166
|
+
|
167
|
+
if (cluster.quirks?.tunDevicePolicy?.type === "plugin") {
|
168
|
+
spec.resources ??= {}
|
169
|
+
spec.resources.limits ??= {}
|
170
|
+
spec.resources.limits[cluster.quirks.tunDevicePolicy.resourceName] =
|
171
|
+
cluster.quirks.tunDevicePolicy.resourceValue
|
172
|
+
} else {
|
173
|
+
spec.volumeMounts ??= []
|
174
|
+
spec.volumeMounts.push({
|
175
|
+
name: "tun-device",
|
176
|
+
mountPath: "/dev/net/tun",
|
177
|
+
readOnly: false,
|
178
|
+
})
|
179
|
+
}
|
142
180
|
}
|
181
|
+
|
182
|
+
return spec
|
143
183
|
}
|
144
184
|
|
145
185
|
export function mapContainerEnvironment(
|
@@ -240,7 +280,16 @@ export function mapWorkloadVolume(volume: WorkloadVolume) {
|
|
240
280
|
}
|
241
281
|
}
|
242
282
|
|
243
|
-
if (volume instanceof
|
283
|
+
if (volume instanceof Secret) {
|
284
|
+
return {
|
285
|
+
name: volume.metadata.name,
|
286
|
+
secret: {
|
287
|
+
secretName: volume.metadata.name,
|
288
|
+
},
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
if (core.v1.PersistentVolumeClaim.isInstance(volume)) {
|
244
293
|
return {
|
245
294
|
name: volume.metadata.name,
|
246
295
|
persistentVolumeClaim: {
|
@@ -249,7 +298,7 @@ export function mapWorkloadVolume(volume: WorkloadVolume) {
|
|
249
298
|
}
|
250
299
|
}
|
251
300
|
|
252
|
-
if (
|
301
|
+
if (core.v1.ConfigMap.isInstance(volume)) {
|
253
302
|
return {
|
254
303
|
name: volume.metadata.name,
|
255
304
|
configMap: {
|
@@ -258,7 +307,7 @@ export function mapWorkloadVolume(volume: WorkloadVolume) {
|
|
258
307
|
}
|
259
308
|
}
|
260
309
|
|
261
|
-
if (
|
310
|
+
if (core.v1.Secret.isInstance(volume)) {
|
262
311
|
return {
|
263
312
|
name: volume.metadata.name,
|
264
313
|
secret: {
|
package/src/cron-job.ts
CHANGED
@@ -1,22 +1,12 @@
|
|
1
1
|
import type { RequiredKeys } from "@highstate/contract"
|
2
2
|
import { batch, type types } from "@pulumi/kubernetes"
|
3
|
-
import {
|
4
|
-
ComponentResource,
|
5
|
-
normalize,
|
6
|
-
Output,
|
7
|
-
output,
|
8
|
-
type ComponentResourceOptions,
|
9
|
-
type Input,
|
10
|
-
type InputArray,
|
11
|
-
} from "@highstate/pulumi"
|
3
|
+
import { ComponentResource, Output, output, type ComponentResourceOptions } from "@highstate/pulumi"
|
12
4
|
import { mergeDeep, omit } from "remeda"
|
13
|
-
import {
|
14
|
-
import {
|
5
|
+
import { commonExtraArgs, getProvider, mapMetadata } from "./shared"
|
6
|
+
import { getWorkloadComponents, type WorkloadArgs } from "./workload"
|
15
7
|
|
16
|
-
export type CronJobArgs =
|
17
|
-
|
18
|
-
containers?: InputArray<Container>
|
19
|
-
} & Omit<RequiredKeys<Partial<types.input.batch.v1.CronJobSpec>, "schedule">, "jobTemplate"> & {
|
8
|
+
export type CronJobArgs = WorkloadArgs &
|
9
|
+
Omit<RequiredKeys<Partial<types.input.batch.v1.CronJobSpec>, "schedule">, "jobTemplate"> & {
|
20
10
|
jobTemplate?: {
|
21
11
|
metadata?: types.input.meta.v1.ObjectMeta
|
22
12
|
spec?: Omit<types.input.batch.v1.JobSpec, "template"> & {
|
@@ -36,12 +26,12 @@ export class CronJob extends ComponentResource {
|
|
36
26
|
*/
|
37
27
|
public readonly cronJob: Output<batch.v1.CronJob>
|
38
28
|
|
39
|
-
constructor(name: string, args: CronJobArgs, opts
|
29
|
+
constructor(name: string, args: CronJobArgs, opts: ComponentResourceOptions) {
|
40
30
|
super("highstate:k8s:CronJob", name, args, opts)
|
41
31
|
|
42
|
-
|
43
|
-
const containers = normalize(args.container, args.containers)
|
32
|
+
const { podTemplate } = getWorkloadComponents(name, args, () => this, opts)
|
44
33
|
|
34
|
+
this.cronJob = output({ args, podTemplate }).apply(async ({ args, podTemplate }) => {
|
45
35
|
return new batch.v1.CronJob(
|
46
36
|
name,
|
47
37
|
{
|
@@ -51,15 +41,7 @@ export class CronJob extends ComponentResource {
|
|
51
41
|
{
|
52
42
|
jobTemplate: {
|
53
43
|
spec: {
|
54
|
-
template:
|
55
|
-
spec: {
|
56
|
-
containers: containers.map(container => mapContainerToRaw(container, name)),
|
57
|
-
|
58
|
-
volumes: containers
|
59
|
-
.flatMap(container => normalize(container.volume, container.volumes))
|
60
|
-
.map(mapWorkloadVolume),
|
61
|
-
},
|
62
|
-
},
|
44
|
+
template: podTemplate,
|
63
45
|
},
|
64
46
|
},
|
65
47
|
|
@@ -68,10 +50,12 @@ export class CronJob extends ComponentResource {
|
|
68
50
|
omit(args, cronJobExtraArgs) as types.input.batch.v1.CronJobSpec,
|
69
51
|
),
|
70
52
|
},
|
71
|
-
{
|
53
|
+
{
|
54
|
+
...opts,
|
55
|
+
parent: this,
|
56
|
+
provider: await getProvider(args.cluster),
|
57
|
+
},
|
72
58
|
)
|
73
59
|
})
|
74
|
-
|
75
|
-
this.registerOutputs({ cronJob: this.cronJob })
|
76
60
|
}
|
77
61
|
}
|