@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.
- package/dist/chunk-23vn2rdc.js +11 -0
- package/dist/chunk-2pfx13ay.js +11 -0
- package/dist/chunk-46ntav0c.js +299 -0
- package/dist/chunk-556pc9e6.js +155 -0
- package/dist/chunk-7kgjgcft.js +170 -0
- package/dist/{chunk-LGHFSXNT.js → chunk-9hs97f1q.js} +23 -17
- package/dist/chunk-aame3x1b.js +11 -0
- package/dist/chunk-b05q6fm2.js +37 -0
- package/dist/chunk-bmvc9d2d.js +11 -0
- package/dist/chunk-de82bbp2.js +7 -0
- package/dist/chunk-facs31cb.js +624 -0
- package/dist/chunk-h1b79v66.js +1425 -0
- package/dist/chunk-k4w9zpn5.js +215 -0
- package/dist/chunk-pqc6w52f.js +352 -0
- package/dist/chunk-qyshvz32.js +176 -0
- package/dist/chunk-tpfyj6fe.js +199 -0
- package/dist/chunk-z6bmpnm7.js +180 -0
- package/dist/highstate.manifest.json +3 -2
- package/dist/impl/dynamic-endpoint-resolver.js +91 -0
- package/dist/impl/gateway-route.js +226 -166
- package/dist/impl/tls-certificate.js +31 -31
- package/dist/index.js +293 -166
- package/dist/units/cert-manager/index.js +19 -14
- package/dist/units/cluster-patch/index.js +14 -13
- package/dist/units/dns01-issuer/index.js +82 -42
- package/dist/units/existing-cluster/index.js +59 -26
- package/dist/units/gateway-api/index.js +15 -16
- package/dist/units/reduced-access-cluster/index.js +32 -36
- package/package.json +23 -21
- package/src/cluster.ts +12 -8
- package/src/config-map.ts +15 -5
- package/src/container.ts +4 -2
- package/src/cron-job.ts +51 -5
- package/src/deployment.ts +49 -18
- package/src/gateway/backend.ts +3 -3
- package/src/gateway/gateway.ts +12 -56
- package/src/helm.ts +354 -22
- package/src/impl/dynamic-endpoint-resolver.ts +109 -0
- package/src/impl/gateway-route.ts +231 -57
- package/src/impl/tls-certificate.ts +8 -3
- package/src/index.ts +1 -0
- package/src/job.ts +38 -6
- package/src/kubectl.ts +166 -0
- package/src/namespace.ts +47 -3
- package/src/network-policy.ts +1 -1
- package/src/pvc.ts +12 -2
- package/src/rbac.ts +28 -5
- package/src/scripting/bundle.ts +21 -98
- package/src/scripting/environment.ts +4 -10
- package/src/secret.ts +15 -5
- package/src/service.ts +28 -6
- package/src/shared.ts +31 -3
- package/src/stateful-set.ts +49 -18
- package/src/tls.ts +31 -5
- package/src/units/cluster-patch/index.ts +5 -5
- package/src/units/dns01-issuer/index.ts +56 -12
- package/src/units/existing-cluster/index.ts +36 -15
- package/src/units/reduced-access-cluster/index.ts +6 -3
- package/src/worker.ts +4 -2
- package/src/workload.ts +474 -217
- package/LICENSE +0 -21
- package/dist/chunk-4G6LLC2X.js +0 -240
- package/dist/chunk-4G6LLC2X.js.map +0 -1
- package/dist/chunk-BR2CLUUD.js +0 -230
- package/dist/chunk-BR2CLUUD.js.map +0 -1
- package/dist/chunk-DCUMJSO6.js +0 -427
- package/dist/chunk-DCUMJSO6.js.map +0 -1
- package/dist/chunk-FE4SHRAJ.js +0 -286
- package/dist/chunk-FE4SHRAJ.js.map +0 -1
- package/dist/chunk-HH2JJELM.js +0 -13
- package/dist/chunk-HH2JJELM.js.map +0 -1
- package/dist/chunk-KMLRI5UZ.js +0 -155
- package/dist/chunk-KMLRI5UZ.js.map +0 -1
- package/dist/chunk-LGHFSXNT.js.map +0 -1
- package/dist/chunk-MIC2BHGS.js +0 -301
- package/dist/chunk-MIC2BHGS.js.map +0 -1
- package/dist/chunk-OBDQONMV.js +0 -401
- package/dist/chunk-OBDQONMV.js.map +0 -1
- package/dist/chunk-P2VOUU7E.js +0 -1626
- package/dist/chunk-P2VOUU7E.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -9
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-RVB4WWZZ.js +0 -267
- package/dist/chunk-RVB4WWZZ.js.map +0 -1
- package/dist/chunk-TWBMG6TD.js +0 -315
- package/dist/chunk-TWBMG6TD.js.map +0 -1
- package/dist/chunk-VCXWCZ43.js +0 -279
- package/dist/chunk-VCXWCZ43.js.map +0 -1
- package/dist/chunk-YIJUVPU2.js +0 -297
- package/dist/chunk-YIJUVPU2.js.map +0 -1
- package/dist/cron-job-NX4HD4FI.js +0 -8
- package/dist/cron-job-NX4HD4FI.js.map +0 -1
- package/dist/deployment-O2LJ5WR5.js +0 -8
- package/dist/deployment-O2LJ5WR5.js.map +0 -1
- package/dist/impl/gateway-route.js.map +0 -1
- package/dist/impl/tls-certificate.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/job-SYME6Y43.js +0 -8
- package/dist/job-SYME6Y43.js.map +0 -1
- package/dist/stateful-set-VJYKTQ72.js +0 -8
- package/dist/stateful-set-VJYKTQ72.js.map +0 -1
- package/dist/units/cert-manager/index.js.map +0 -1
- package/dist/units/cluster-patch/index.js.map +0 -1
- package/dist/units/dns01-issuer/index.js.map +0 -1
- package/dist/units/existing-cluster/index.js.map +0 -1
- package/dist/units/gateway-api/index.js.map +0 -1
- package/dist/units/reduced-access-cluster/index.js.map +0 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Workload,
|
|
4
|
+
filterPatchOwnedContainersInTemplate,
|
|
5
|
+
getWorkloadComponents
|
|
6
|
+
} from "./chunk-h1b79v66.js";
|
|
7
|
+
import {
|
|
8
|
+
Namespace,
|
|
9
|
+
commonExtraArgs,
|
|
10
|
+
getProvider,
|
|
11
|
+
mapMetadata
|
|
12
|
+
} from "./chunk-facs31cb.js";
|
|
13
|
+
|
|
14
|
+
// src/job.ts
|
|
15
|
+
import { getOrCreate } from "@highstate/contract";
|
|
16
|
+
import { k8s } from "@highstate/library";
|
|
17
|
+
import {
|
|
18
|
+
interpolate,
|
|
19
|
+
makeEntityOutput,
|
|
20
|
+
output,
|
|
21
|
+
toPromise
|
|
22
|
+
} from "@highstate/pulumi";
|
|
23
|
+
import { batch } from "@pulumi/kubernetes";
|
|
24
|
+
import { deepmerge } from "deepmerge-ts";
|
|
25
|
+
import { omit } from "remeda";
|
|
26
|
+
class Job extends Workload {
|
|
27
|
+
spec;
|
|
28
|
+
status;
|
|
29
|
+
static apiVersion = "batch/v1";
|
|
30
|
+
static kind = "Job";
|
|
31
|
+
constructor(type, name, args, opts, metadata, namespace, terminalArgs, containers, networkPolicy, spec, status) {
|
|
32
|
+
super(type, name, args, opts, metadata, namespace, terminalArgs, containers, spec.template, networkPolicy);
|
|
33
|
+
this.spec = spec;
|
|
34
|
+
this.status = status;
|
|
35
|
+
}
|
|
36
|
+
get templateMetadata() {
|
|
37
|
+
return this.spec.template.metadata;
|
|
38
|
+
}
|
|
39
|
+
get entity() {
|
|
40
|
+
return makeEntityOutput({
|
|
41
|
+
entity: k8s.jobEntity,
|
|
42
|
+
identity: this.metadata.uid,
|
|
43
|
+
meta: {
|
|
44
|
+
title: this.metadata.name
|
|
45
|
+
},
|
|
46
|
+
value: {
|
|
47
|
+
...this.entityBase,
|
|
48
|
+
spec: this.spec
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
getTerminalMeta() {
|
|
53
|
+
return output({
|
|
54
|
+
title: "Job",
|
|
55
|
+
globalTitle: interpolate`Job | ${this.metadata.name}`,
|
|
56
|
+
description: "The shell inside the job.",
|
|
57
|
+
icon: "devicon:kubernetes"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
get resourceType() {
|
|
61
|
+
return "job";
|
|
62
|
+
}
|
|
63
|
+
static create(name, args, opts) {
|
|
64
|
+
return new CreatedJob(name, args, opts);
|
|
65
|
+
}
|
|
66
|
+
static createOrPatch(name, args, opts) {
|
|
67
|
+
if (args.existing) {
|
|
68
|
+
return new JobPatch(name, {
|
|
69
|
+
...args,
|
|
70
|
+
name: output(args.existing).metadata.name,
|
|
71
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster)
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return new CreatedJob(name, args, opts);
|
|
75
|
+
}
|
|
76
|
+
static async createOrGet(name, args, opts) {
|
|
77
|
+
if (args.existing) {
|
|
78
|
+
return await Job.forAsync(args.existing, output(args.namespace).cluster);
|
|
79
|
+
}
|
|
80
|
+
return new CreatedJob(name, args, opts);
|
|
81
|
+
}
|
|
82
|
+
static patch(name, args, opts) {
|
|
83
|
+
return new JobPatch(name, args, opts);
|
|
84
|
+
}
|
|
85
|
+
static wrap(name, args, opts) {
|
|
86
|
+
return new WrappedJob(name, args, opts);
|
|
87
|
+
}
|
|
88
|
+
static get(name, args, opts) {
|
|
89
|
+
return new ExternalJob(name, args, opts);
|
|
90
|
+
}
|
|
91
|
+
static jobCache = new Map;
|
|
92
|
+
static for(entity, cluster) {
|
|
93
|
+
return getOrCreate(Job.jobCache, `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`, (name) => {
|
|
94
|
+
return Job.get(name, {
|
|
95
|
+
name: entity.metadata.name,
|
|
96
|
+
namespace: Namespace.forResource(entity, cluster)
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
static async forAsync(entity, cluster) {
|
|
101
|
+
const resolvedEntity = await toPromise(entity);
|
|
102
|
+
return Job.for(resolvedEntity, cluster);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
var jobExtraArgs = [...commonExtraArgs, "container", "containers"];
|
|
106
|
+
|
|
107
|
+
class CreatedJob extends Job {
|
|
108
|
+
constructor(name, args, opts) {
|
|
109
|
+
const { podTemplate, containers, networkPolicy } = getWorkloadComponents(name, args, () => this, opts);
|
|
110
|
+
const job = output(args.namespace).cluster.apply((cluster) => {
|
|
111
|
+
return new batch.v1.Job(name, {
|
|
112
|
+
metadata: mapMetadata(args, name),
|
|
113
|
+
spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
|
|
114
|
+
return deepmerge({
|
|
115
|
+
template: deepmerge({
|
|
116
|
+
spec: {
|
|
117
|
+
restartPolicy: "Never"
|
|
118
|
+
}
|
|
119
|
+
}, podTemplate2)
|
|
120
|
+
}, omit(args2, jobExtraArgs));
|
|
121
|
+
})
|
|
122
|
+
}, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
123
|
+
});
|
|
124
|
+
super("highstate:k8s:Job", name, args, opts, job.metadata, output(args.namespace), output(args.terminal ?? {}), containers, networkPolicy, job.spec, job.status);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class JobPatch extends Job {
|
|
129
|
+
constructor(name, args, opts) {
|
|
130
|
+
const { podTemplate, containers, networkPolicy } = getWorkloadComponents(name, args, () => this, opts, true);
|
|
131
|
+
const job = output(args.namespace).cluster.apply((cluster) => {
|
|
132
|
+
return new batch.v1.JobPatch(name, {
|
|
133
|
+
metadata: mapMetadata(args, name),
|
|
134
|
+
spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
|
|
135
|
+
const spec = deepmerge({ template: podTemplate2 }, omit(args2, jobExtraArgs));
|
|
136
|
+
if (spec.template) {
|
|
137
|
+
spec.template = filterPatchOwnedContainersInTemplate(spec.template, podTemplate2);
|
|
138
|
+
}
|
|
139
|
+
return spec;
|
|
140
|
+
})
|
|
141
|
+
}, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
142
|
+
});
|
|
143
|
+
const filteredSpec = output({ spec: job.spec, podTemplate }).apply(({ spec, podTemplate: podTemplate2 }) => {
|
|
144
|
+
if (!spec.template) {
|
|
145
|
+
return spec;
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
...spec,
|
|
149
|
+
template: filterPatchOwnedContainersInTemplate(spec.template, podTemplate2)
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
super("highstate:k8s:JobPatch", name, args, opts, job.metadata, output(args.namespace), output(args.terminal ?? {}), containers, networkPolicy, filteredSpec, job.status);
|
|
153
|
+
this.registerOutputs({
|
|
154
|
+
metadata: this.metadata,
|
|
155
|
+
spec: this.spec,
|
|
156
|
+
status: this.status
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
class WrappedJob extends Job {
|
|
162
|
+
constructor(name, args, opts) {
|
|
163
|
+
super("highstate:k8s:WrappedJob", name, args, opts, output(args.job).metadata, output(args.namespace), output(args.terminal ?? {}), output([]), output(undefined), output(args.job).spec, output(args.job).status);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
class ExternalJob extends Job {
|
|
168
|
+
constructor(name, args, opts) {
|
|
169
|
+
const job = output(args.namespace).cluster.apply((cluster) => {
|
|
170
|
+
return batch.v1.Job.get(name, interpolate`${output(args.namespace).metadata.name}/${args.name}`, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
171
|
+
});
|
|
172
|
+
super("highstate:k8s:ExternalJob", name, args, opts, job.metadata, output(args.namespace), output({}), output([]), output(undefined), job.spec, job.status);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export { Job };
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Workload,
|
|
4
|
+
filterPatchOwnedContainersInTemplate,
|
|
5
|
+
getWorkloadComponents
|
|
6
|
+
} from "./chunk-h1b79v66.js";
|
|
7
|
+
import {
|
|
8
|
+
Namespace,
|
|
9
|
+
commonExtraArgs,
|
|
10
|
+
getProvider,
|
|
11
|
+
mapMetadata
|
|
12
|
+
} from "./chunk-facs31cb.js";
|
|
13
|
+
|
|
14
|
+
// src/cron-job.ts
|
|
15
|
+
import { getOrCreate } from "@highstate/contract";
|
|
16
|
+
import { k8s } from "@highstate/library";
|
|
17
|
+
import {
|
|
18
|
+
interpolate,
|
|
19
|
+
makeEntityOutput,
|
|
20
|
+
output,
|
|
21
|
+
toPromise
|
|
22
|
+
} from "@highstate/pulumi";
|
|
23
|
+
import { batch } from "@pulumi/kubernetes";
|
|
24
|
+
import { deepmerge } from "deepmerge-ts";
|
|
25
|
+
import { omit } from "remeda";
|
|
26
|
+
class CronJob extends Workload {
|
|
27
|
+
spec;
|
|
28
|
+
status;
|
|
29
|
+
static apiVersion = "batch/v1";
|
|
30
|
+
static kind = "CronJob";
|
|
31
|
+
constructor(type, name, args, opts, metadata, namespace, terminalArgs, containers, networkPolicy, spec, status) {
|
|
32
|
+
super(type, name, args, opts, metadata, namespace, terminalArgs, containers, spec.jobTemplate.spec.template, networkPolicy);
|
|
33
|
+
this.spec = spec;
|
|
34
|
+
this.status = status;
|
|
35
|
+
}
|
|
36
|
+
get templateMetadata() {
|
|
37
|
+
return this.spec.jobTemplate.spec.template.metadata;
|
|
38
|
+
}
|
|
39
|
+
get entity() {
|
|
40
|
+
return makeEntityOutput({
|
|
41
|
+
entity: k8s.cronJobEntity,
|
|
42
|
+
identity: this.metadata.uid,
|
|
43
|
+
meta: {
|
|
44
|
+
title: this.metadata.name
|
|
45
|
+
},
|
|
46
|
+
value: {
|
|
47
|
+
...this.entityBase,
|
|
48
|
+
spec: this.spec.jobTemplate.spec
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
getTerminalMeta() {
|
|
53
|
+
return output({
|
|
54
|
+
title: "CronJob",
|
|
55
|
+
globalTitle: interpolate`CronJob | ${this.metadata.name}`,
|
|
56
|
+
description: "The shell inside the cron job.",
|
|
57
|
+
icon: "devicon:kubernetes"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
get resourceType() {
|
|
61
|
+
return "cronjob";
|
|
62
|
+
}
|
|
63
|
+
static create(name, args, opts) {
|
|
64
|
+
return new CreatedCronJob(name, args, opts);
|
|
65
|
+
}
|
|
66
|
+
static createOrPatch(name, args, opts) {
|
|
67
|
+
if (args.existing) {
|
|
68
|
+
return new CronJobPatch(name, {
|
|
69
|
+
...args,
|
|
70
|
+
name: output(args.existing).metadata.name,
|
|
71
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster)
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return new CreatedCronJob(name, args, opts);
|
|
75
|
+
}
|
|
76
|
+
static async createOrGet(name, args, opts) {
|
|
77
|
+
if (args.existing) {
|
|
78
|
+
return await CronJob.forAsync(args.existing, output(args.namespace).cluster);
|
|
79
|
+
}
|
|
80
|
+
return new CreatedCronJob(name, args, opts);
|
|
81
|
+
}
|
|
82
|
+
static patch(name, args, opts) {
|
|
83
|
+
return new CronJobPatch(name, args, opts);
|
|
84
|
+
}
|
|
85
|
+
static wrap(name, args, opts) {
|
|
86
|
+
return new WrappedCronJob(name, args, opts);
|
|
87
|
+
}
|
|
88
|
+
static get(name, args, opts) {
|
|
89
|
+
return new ExternalCronJob(name, args, opts);
|
|
90
|
+
}
|
|
91
|
+
static cronJobCache = new Map;
|
|
92
|
+
static for(entity, cluster) {
|
|
93
|
+
return getOrCreate(CronJob.cronJobCache, `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`, (name) => {
|
|
94
|
+
return CronJob.get(name, {
|
|
95
|
+
name: entity.metadata.name,
|
|
96
|
+
namespace: Namespace.forResource(entity, cluster)
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
static async forAsync(entity, cluster) {
|
|
101
|
+
const resolvedEntity = await toPromise(entity);
|
|
102
|
+
return CronJob.for(resolvedEntity, cluster);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
var cronJobExtraArgs = [...commonExtraArgs, "container", "containers"];
|
|
106
|
+
|
|
107
|
+
class CreatedCronJob extends CronJob {
|
|
108
|
+
constructor(name, args, opts) {
|
|
109
|
+
const { podTemplate, containers, networkPolicy } = getWorkloadComponents(name, args, () => this, opts);
|
|
110
|
+
const cronJob = output(args.namespace).cluster.apply((cluster) => {
|
|
111
|
+
return new batch.v1.CronJob(name, {
|
|
112
|
+
metadata: mapMetadata(args, name),
|
|
113
|
+
spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
|
|
114
|
+
return deepmerge({
|
|
115
|
+
jobTemplate: {
|
|
116
|
+
spec: {
|
|
117
|
+
template: deepmerge({
|
|
118
|
+
spec: {
|
|
119
|
+
restartPolicy: "Never"
|
|
120
|
+
}
|
|
121
|
+
}, podTemplate2)
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
schedule: args2.schedule
|
|
125
|
+
}, omit(args2, cronJobExtraArgs));
|
|
126
|
+
})
|
|
127
|
+
}, {
|
|
128
|
+
...opts,
|
|
129
|
+
parent: this,
|
|
130
|
+
provider: getProvider(cluster)
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
super("highstate:k8s:CronJob", name, args, opts, cronJob.metadata, output(args.namespace), output(args.terminal ?? {}), containers, networkPolicy, cronJob.spec, cronJob.status);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
class CronJobPatch extends CronJob {
|
|
138
|
+
constructor(name, args, opts) {
|
|
139
|
+
const { podTemplate, containers, networkPolicy } = getWorkloadComponents(name, args, () => this, opts, true);
|
|
140
|
+
const cronJob = output(args.namespace).cluster.apply((cluster) => {
|
|
141
|
+
return new batch.v1.CronJobPatch(name, {
|
|
142
|
+
metadata: mapMetadata(args, name),
|
|
143
|
+
spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
|
|
144
|
+
const spec = deepmerge({
|
|
145
|
+
jobTemplate: {
|
|
146
|
+
spec: {
|
|
147
|
+
template: podTemplate2
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
schedule: args2.schedule
|
|
151
|
+
}, omit(args2, cronJobExtraArgs));
|
|
152
|
+
if (spec.jobTemplate?.spec?.template) {
|
|
153
|
+
spec.jobTemplate.spec.template = filterPatchOwnedContainersInTemplate(spec.jobTemplate.spec.template, podTemplate2);
|
|
154
|
+
}
|
|
155
|
+
return spec;
|
|
156
|
+
})
|
|
157
|
+
}, {
|
|
158
|
+
...opts,
|
|
159
|
+
parent: this,
|
|
160
|
+
provider: getProvider(cluster)
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
const filteredSpec = output({ spec: cronJob.spec, podTemplate }).apply(({ spec, podTemplate: podTemplate2 }) => {
|
|
164
|
+
const template = spec.jobTemplate?.spec?.template;
|
|
165
|
+
if (!template) {
|
|
166
|
+
return spec;
|
|
167
|
+
}
|
|
168
|
+
const filteredTemplate = filterPatchOwnedContainersInTemplate(template, podTemplate2);
|
|
169
|
+
return {
|
|
170
|
+
...spec,
|
|
171
|
+
jobTemplate: {
|
|
172
|
+
...spec.jobTemplate,
|
|
173
|
+
spec: {
|
|
174
|
+
...spec.jobTemplate.spec,
|
|
175
|
+
template: filteredTemplate
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
super("highstate:k8s:CronJobPatch", name, args, opts, cronJob.metadata, output(args.namespace), output(args.terminal ?? {}), containers, networkPolicy, filteredSpec, cronJob.status);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
class WrappedCronJob extends CronJob {
|
|
185
|
+
constructor(name, args, opts) {
|
|
186
|
+
super("highstate:k8s:WrappedCronJob", name, args, opts, output(args.cronJob).metadata, output(args.namespace), output(args.terminal ?? {}), output([]), output(undefined), output(args.cronJob).spec, output(args.cronJob).status);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
class ExternalCronJob extends CronJob {
|
|
191
|
+
constructor(name, args, opts) {
|
|
192
|
+
const cronJob = output(args.namespace).cluster.apply((cluster) => {
|
|
193
|
+
return batch.v1.CronJob.get(name, interpolate`${output(args.namespace).metadata.name}/${args.name}`, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
194
|
+
});
|
|
195
|
+
super("highstate:k8s:ExternalCronJob", name, args, opts, cronJob.metadata, output(args.namespace), output({}), output([]), output(undefined), cronJob.spec, cronJob.status);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { CronJob };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Workload,
|
|
4
|
+
filterPatchOwnedContainersInTemplate,
|
|
5
|
+
getWorkloadServiceComponents,
|
|
6
|
+
workloadServiceExtraArgs
|
|
7
|
+
} from "./chunk-h1b79v66.js";
|
|
8
|
+
import {
|
|
9
|
+
Namespace,
|
|
10
|
+
getProvider,
|
|
11
|
+
mapMetadata
|
|
12
|
+
} from "./chunk-facs31cb.js";
|
|
13
|
+
|
|
14
|
+
// src/stateful-set.ts
|
|
15
|
+
import { getOrCreate } from "@highstate/contract";
|
|
16
|
+
import { k8s } from "@highstate/library";
|
|
17
|
+
import {
|
|
18
|
+
interpolate,
|
|
19
|
+
makeEntityOutput,
|
|
20
|
+
output,
|
|
21
|
+
toPromise
|
|
22
|
+
} from "@highstate/pulumi";
|
|
23
|
+
import { apps } from "@pulumi/kubernetes";
|
|
24
|
+
import { deepmerge } from "deepmerge-ts";
|
|
25
|
+
import { omit } from "remeda";
|
|
26
|
+
class StatefulSet extends Workload {
|
|
27
|
+
spec;
|
|
28
|
+
status;
|
|
29
|
+
static apiVersion = "apps/v1";
|
|
30
|
+
static kind = "StatefulSet";
|
|
31
|
+
constructor(type, name, args, opts, metadata, namespace, terminalArgs, containers, networkPolicy, service, routes, spec, status) {
|
|
32
|
+
super(type, name, args, opts, metadata, namespace, terminalArgs, containers, spec.template, networkPolicy, service, routes);
|
|
33
|
+
this.spec = spec;
|
|
34
|
+
this.status = status;
|
|
35
|
+
}
|
|
36
|
+
get templateMetadata() {
|
|
37
|
+
return this.spec.template.metadata;
|
|
38
|
+
}
|
|
39
|
+
get entity() {
|
|
40
|
+
return makeEntityOutput({
|
|
41
|
+
entity: k8s.statefulSetEntity,
|
|
42
|
+
identity: this.metadata.uid,
|
|
43
|
+
meta: {
|
|
44
|
+
title: this.metadata.name
|
|
45
|
+
},
|
|
46
|
+
value: {
|
|
47
|
+
...this.entityBase,
|
|
48
|
+
service: this.service.entity,
|
|
49
|
+
spec: this.spec
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
static create(name, args, opts) {
|
|
54
|
+
return new CreatedStatefulSet(name, args, opts);
|
|
55
|
+
}
|
|
56
|
+
static createOrPatch(name, args, opts) {
|
|
57
|
+
if (args.existing) {
|
|
58
|
+
return new StatefulSetPatch(name, {
|
|
59
|
+
...args,
|
|
60
|
+
name: output(args.existing).metadata.name,
|
|
61
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return new CreatedStatefulSet(name, args, opts);
|
|
65
|
+
}
|
|
66
|
+
static async createOrGet(name, args, opts) {
|
|
67
|
+
if (args.existing) {
|
|
68
|
+
return await StatefulSet.forAsync(args.existing, output(args.namespace).cluster);
|
|
69
|
+
}
|
|
70
|
+
return new CreatedStatefulSet(name, args, opts);
|
|
71
|
+
}
|
|
72
|
+
static patch(name, args, opts) {
|
|
73
|
+
return new StatefulSetPatch(name, args, opts);
|
|
74
|
+
}
|
|
75
|
+
static wrap(name, args, opts) {
|
|
76
|
+
return new WrappedStatefulSet(name, args, opts);
|
|
77
|
+
}
|
|
78
|
+
static get(name, args, opts) {
|
|
79
|
+
return new ExternalStatefulSet(name, args, opts);
|
|
80
|
+
}
|
|
81
|
+
static statefulSetCache = new Map;
|
|
82
|
+
static for(entity, cluster) {
|
|
83
|
+
return getOrCreate(StatefulSet.statefulSetCache, `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`, (name) => {
|
|
84
|
+
return StatefulSet.get(name, {
|
|
85
|
+
name: entity.metadata.name,
|
|
86
|
+
namespace: Namespace.forResource(entity, cluster)
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
static async forAsync(entity, cluster) {
|
|
91
|
+
const resolvedEntity = await toPromise(entity);
|
|
92
|
+
return StatefulSet.for(resolvedEntity, cluster);
|
|
93
|
+
}
|
|
94
|
+
getTerminalMeta() {
|
|
95
|
+
return output({
|
|
96
|
+
title: "StatefulSet",
|
|
97
|
+
globalTitle: interpolate`StatefulSet | ${this.metadata.name}`,
|
|
98
|
+
description: "The shell inside the stateful set.",
|
|
99
|
+
icon: "devicon:kubernetes"
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
get resourceType() {
|
|
103
|
+
return "statefulset";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
class CreatedStatefulSet extends StatefulSet {
|
|
108
|
+
constructor(name, args, opts) {
|
|
109
|
+
const { labels, podTemplate, networkPolicy, containers, service, routes } = getWorkloadServiceComponents(name, {
|
|
110
|
+
...args,
|
|
111
|
+
service: output(args.service).apply((service2) => ({ ...service2 }))
|
|
112
|
+
}, () => this, opts);
|
|
113
|
+
const statefulSet = output(args.namespace).cluster.apply((cluster) => {
|
|
114
|
+
return new apps.v1.StatefulSet(name, {
|
|
115
|
+
metadata: mapMetadata(args, name),
|
|
116
|
+
spec: output({ args, podTemplate, labels, service }).apply(({ args: args2, podTemplate: podTemplate2, labels: labels2, service: service2 }) => {
|
|
117
|
+
return deepmerge({
|
|
118
|
+
serviceName: service2?.metadata.name,
|
|
119
|
+
template: podTemplate2,
|
|
120
|
+
selector: { matchLabels: labels2 }
|
|
121
|
+
}, omit(args2, workloadServiceExtraArgs));
|
|
122
|
+
})
|
|
123
|
+
}, {
|
|
124
|
+
...opts,
|
|
125
|
+
parent: this,
|
|
126
|
+
provider: getProvider(cluster)
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
super("highstate:k8s:StatefulSet", name, args, opts, statefulSet.metadata, output(args.namespace), output(args.terminal ?? {}), containers, networkPolicy, service, routes, statefulSet.spec, statefulSet.status);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
class StatefulSetPatch extends StatefulSet {
|
|
134
|
+
constructor(name, args, opts) {
|
|
135
|
+
const { podTemplate, networkPolicy, containers, service, routes } = getWorkloadServiceComponents(name, args, () => this, opts, true);
|
|
136
|
+
const statefulSet = output(args.namespace).cluster.apply((cluster) => {
|
|
137
|
+
return new apps.v1.StatefulSetPatch(name, {
|
|
138
|
+
metadata: mapMetadata(args, name),
|
|
139
|
+
spec: output({ args, podTemplate }).apply(({ args: args2, podTemplate: podTemplate2 }) => {
|
|
140
|
+
const spec = deepmerge({ template: podTemplate2 }, omit(args2, workloadServiceExtraArgs));
|
|
141
|
+
if (spec.template) {
|
|
142
|
+
spec.template = filterPatchOwnedContainersInTemplate(spec.template, podTemplate2);
|
|
143
|
+
}
|
|
144
|
+
return spec;
|
|
145
|
+
})
|
|
146
|
+
}, {
|
|
147
|
+
...opts,
|
|
148
|
+
parent: this,
|
|
149
|
+
provider: getProvider(cluster)
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
const filteredSpec = output({ spec: statefulSet.spec, podTemplate }).apply(({ spec, podTemplate: podTemplate2 }) => {
|
|
153
|
+
if (!spec.template) {
|
|
154
|
+
return spec;
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
...spec,
|
|
158
|
+
template: filterPatchOwnedContainersInTemplate(spec.template, podTemplate2)
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
super("highstate:k8s:StatefulSetPatch", name, args, opts, statefulSet.metadata, output(args.namespace), output(args.terminal ?? {}), containers, networkPolicy, service, routes, filteredSpec, statefulSet.status);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
class WrappedStatefulSet extends StatefulSet {
|
|
166
|
+
constructor(name, args, opts) {
|
|
167
|
+
super("highstate:k8s:WrappedStatefulSet", name, args, opts, output(args.statefulSet).metadata, output(args.namespace), output(args.terminal ?? {}), output([]), output(undefined), output(args.service), output([]), output(args.statefulSet).spec, output(args.statefulSet).status);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
class ExternalStatefulSet extends StatefulSet {
|
|
172
|
+
constructor(name, args, opts) {
|
|
173
|
+
const statefulSet = output(args.namespace).cluster.apply((cluster) => {
|
|
174
|
+
return apps.v1.StatefulSet.get(name, interpolate`${output(args.namespace).metadata.name}/${args.name}`, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
175
|
+
});
|
|
176
|
+
super("highstate:k8s:ExternalStatefulSet", name, args, opts, statefulSet.metadata, output(args.namespace), output({}), output([]), output(undefined), output(undefined), output([]), statefulSet.spec, statefulSet.status);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { StatefulSet };
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
"./dist/units/existing-cluster/index.js": 2212294583,
|
|
8
8
|
"./dist/units/gateway-api/index.js": 2212294583,
|
|
9
9
|
"./dist/units/reduced-access-cluster/index.js": 2212294583,
|
|
10
|
-
"./dist/impl/
|
|
11
|
-
"./dist/impl/
|
|
10
|
+
"./dist/impl/dynamic-endpoint-resolver.js": 313156426,
|
|
11
|
+
"./dist/impl/gateway-route.js": 212793152,
|
|
12
|
+
"./dist/impl/tls-certificate.js": 2224932688
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
isEndpointFromCluster
|
|
4
|
+
} from "../chunk-k4w9zpn5.js";
|
|
5
|
+
import"../chunk-facs31cb.js";
|
|
6
|
+
import {
|
|
7
|
+
__callDispose,
|
|
8
|
+
__using
|
|
9
|
+
} from "../chunk-b05q6fm2.js";
|
|
10
|
+
|
|
11
|
+
// src/impl/dynamic-endpoint-resolver.ts
|
|
12
|
+
import { crc32 } from "zlib";
|
|
13
|
+
import {
|
|
14
|
+
dynamicEndpointResolverMediator,
|
|
15
|
+
endpointToString,
|
|
16
|
+
MaterializedFile,
|
|
17
|
+
parseEndpoint,
|
|
18
|
+
rebaseEndpoint
|
|
19
|
+
} from "@highstate/common";
|
|
20
|
+
import { z } from "@highstate/contract";
|
|
21
|
+
import { k8s } from "@highstate/library";
|
|
22
|
+
import { getUnitStateId } from "@highstate/pulumi";
|
|
23
|
+
import spawn, { SubprocessError } from "nano-spawn";
|
|
24
|
+
var resolveDynamicEndpoint = dynamicEndpointResolverMediator.implement(z.object({ cluster: k8s.clusterEntity.schema }), async ({ endpoint }, { cluster }) => {
|
|
25
|
+
if (!isEndpointFromCluster(endpoint, cluster)) {
|
|
26
|
+
throw new Error(`Endpoint "${endpointToString(endpoint)}" is not from cluster "${cluster.id}"`);
|
|
27
|
+
}
|
|
28
|
+
const { name, namespace } = endpoint.metadata["k8s.service"];
|
|
29
|
+
const localPort = getStablePort(`${cluster.id}:${namespace}:${name}`);
|
|
30
|
+
let subprocess;
|
|
31
|
+
return {
|
|
32
|
+
endpoint: rebaseEndpoint(endpoint, parseEndpoint(`localhost:${localPort}`)),
|
|
33
|
+
setup: async () => {
|
|
34
|
+
let __stack = [];
|
|
35
|
+
try {
|
|
36
|
+
console.log(`[port-forward] starting port-forward for service "${name}" in namespace "${namespace}" on local port ${localPort}`);
|
|
37
|
+
const config = MaterializedFile.for(cluster.kubeconfig);
|
|
38
|
+
const _ = __using(__stack, await config.open(), 1);
|
|
39
|
+
subprocess = spawn("kubectl", [
|
|
40
|
+
"--kubeconfig",
|
|
41
|
+
config.path,
|
|
42
|
+
"port-forward",
|
|
43
|
+
`service/${name}`,
|
|
44
|
+
"-n",
|
|
45
|
+
namespace,
|
|
46
|
+
`${localPort}:${endpoint.port}`
|
|
47
|
+
]);
|
|
48
|
+
subprocess.catch((err) => {
|
|
49
|
+
if (err instanceof SubprocessError && err.signalName === "SIGTERM") {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
throw err;
|
|
53
|
+
});
|
|
54
|
+
const nodeProcess = await subprocess.nodeChildProcess;
|
|
55
|
+
await new Promise((resolve, reject) => {
|
|
56
|
+
nodeProcess.stdout?.once("data", (data) => {
|
|
57
|
+
const output = data.toString();
|
|
58
|
+
if (output.includes("Forwarding from")) {
|
|
59
|
+
resolve();
|
|
60
|
+
} else {
|
|
61
|
+
reject(new Error(`Failed to start port-forward: ${output}`));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
nodeProcess.stderr?.once("data", (data) => {
|
|
65
|
+
reject(new Error(`Failed to start port-forward: ${data.toString()}`));
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
console.log(`[port-forward] port-forward is ready for service "${name}" in namespace "${namespace}" on local port ${localPort}`);
|
|
69
|
+
} catch (_catch) {
|
|
70
|
+
var _err = _catch, _hasErr = 1;
|
|
71
|
+
} finally {
|
|
72
|
+
var _promise = __callDispose(__stack, _err, _hasErr);
|
|
73
|
+
_promise && await _promise;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
dispose: async () => {
|
|
77
|
+
console.log(`[port-forward] stopping port-forward for service "${name}" in namespace "${namespace}" on local port ${localPort}`);
|
|
78
|
+
const nodeProcess = await subprocess.nodeChildProcess;
|
|
79
|
+
nodeProcess.kill();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
function getStablePort(id) {
|
|
84
|
+
const hash = crc32(`${getUnitStateId()}:${id}`);
|
|
85
|
+
const minPort = 30000;
|
|
86
|
+
const maxPort = 60000;
|
|
87
|
+
return Math.abs(hash) % (maxPort - minPort) + minPort;
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
resolveDynamicEndpoint
|
|
91
|
+
};
|