@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
@@ -2,6 +2,12 @@ import { k8s } from "@highstate/library"
|
|
2
2
|
import { forUnit, secret, toPromise } from "@highstate/pulumi"
|
3
3
|
import { core, Provider } from "@pulumi/kubernetes"
|
4
4
|
import { KubeConfig, AppsV1Api } from "@kubernetes/client-node"
|
5
|
+
import {
|
6
|
+
l3EndpointToString,
|
7
|
+
l4EndpointToString,
|
8
|
+
parseL3Endpoint,
|
9
|
+
parseL4Endpoint,
|
10
|
+
} from "@highstate/common"
|
5
11
|
import { createK8sTerminal, detectExternalIps } from "../../cluster"
|
6
12
|
|
7
13
|
const { name, args, secrets, outputs } = forUnit(k8s.existingCluster)
|
@@ -10,7 +16,7 @@ const kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringif
|
|
10
16
|
|
11
17
|
const provider = new Provider(name, { kubeconfig: kubeconfigContent })
|
12
18
|
|
13
|
-
let cni:
|
19
|
+
let cni: k8s.CNI = "other"
|
14
20
|
|
15
21
|
const kubeConfig = new KubeConfig()
|
16
22
|
kubeConfig.loadFromString(kubeconfigContent)
|
@@ -26,30 +32,35 @@ if (isCilium) {
|
|
26
32
|
cni = "cilium"
|
27
33
|
}
|
28
34
|
|
29
|
-
const externalIps =
|
35
|
+
const externalIps =
|
36
|
+
args.externalIps ?? (await detectExternalIps(kubeConfig, args.internalIpsPolicy))
|
37
|
+
|
38
|
+
const endpoints = externalIps.map(parseL3Endpoint)
|
39
|
+
const apiEndpoints = [parseL4Endpoint(kubeConfig.clusters[0].server.replace("https://", ""))]
|
30
40
|
|
31
41
|
const kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provider })
|
32
42
|
|
33
43
|
export default outputs({
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
44
|
+
k8sCluster: {
|
45
|
+
id: kubeSystem.metadata.uid,
|
46
|
+
name,
|
47
|
+
cni,
|
48
|
+
externalIps,
|
49
|
+
endpoints,
|
50
|
+
apiEndpoints,
|
51
|
+
quirks: args.quirks,
|
42
52
|
kubeconfig: secret(kubeconfigContent),
|
43
53
|
},
|
44
54
|
|
55
|
+
endpoints,
|
56
|
+
apiEndpoints,
|
57
|
+
|
45
58
|
$terminals: [createK8sTerminal(kubeconfigContent)],
|
46
59
|
|
47
60
|
$status: {
|
48
61
|
clusterId: kubeSystem.metadata.uid,
|
49
|
-
cni
|
50
|
-
|
51
|
-
|
52
|
-
complementaryTo: "externalIps",
|
53
|
-
},
|
62
|
+
cni,
|
63
|
+
endpoints: endpoints.map(l3EndpointToString),
|
64
|
+
apiEndpoints: apiEndpoints.map(l4EndpointToString),
|
54
65
|
},
|
55
66
|
})
|
package/src/workload.ts
CHANGED
@@ -1,9 +1,24 @@
|
|
1
|
-
import type { types } from "@pulumi/kubernetes"
|
2
1
|
import type { k8s } from "@highstate/library"
|
3
|
-
import
|
4
|
-
import
|
2
|
+
import type { DeploymentArgs } from "./deployment"
|
3
|
+
import type { StatefulSetArgs } from "./stateful-set"
|
4
|
+
import type { types } from "@pulumi/kubernetes"
|
5
|
+
import {
|
6
|
+
normalize,
|
7
|
+
type ComponentResourceOptions,
|
8
|
+
type InputArray,
|
9
|
+
type InstanceTerminal,
|
10
|
+
} from "@highstate/pulumi"
|
11
|
+
import {
|
12
|
+
ComponentResource,
|
13
|
+
interpolate,
|
14
|
+
Output,
|
15
|
+
output,
|
16
|
+
type CustomResourceOptions,
|
17
|
+
type Input,
|
18
|
+
} from "@pulumi/pulumi"
|
5
19
|
import { uniqueBy } from "remeda"
|
6
|
-
import {
|
20
|
+
import { deepmerge } from "deepmerge-ts"
|
21
|
+
import { commonExtraArgs, getProvider, type CommonArgs } from "./shared"
|
7
22
|
import { mapContainerPortToServicePort, Service, type ServiceArgs } from "./service"
|
8
23
|
import { HttpRoute, type HttpRouteArgs } from "./gateway"
|
9
24
|
import {
|
@@ -12,54 +27,77 @@ import {
|
|
12
27
|
type Container,
|
13
28
|
type WorkloadVolume,
|
14
29
|
} from "./container"
|
30
|
+
import { NetworkPolicy } from "./network-policy"
|
31
|
+
import { podSpecDefaults } from "./pod"
|
15
32
|
|
16
33
|
export type WorkloadArgs = CommonArgs & {
|
17
34
|
container?: Input<Container>
|
18
35
|
containers?: InputArray<Container>
|
19
36
|
|
20
37
|
/**
|
21
|
-
* The
|
38
|
+
* The shell to use in the terminal.
|
39
|
+
*
|
40
|
+
* By default, `bash` is used.
|
22
41
|
*/
|
23
|
-
|
42
|
+
terminalShell?: string
|
24
43
|
}
|
25
44
|
|
26
45
|
export const workloadExtraArgs = [...commonExtraArgs, "container", "containers"] as const
|
27
46
|
|
28
|
-
export
|
29
|
-
|
30
|
-
|
47
|
+
export type ExposableWorkloadArgs = WorkloadArgs & {
|
48
|
+
service?: Input<Omit<ServiceArgs, "cluster" | "namespace">>
|
49
|
+
httpRoute?: Input<Omit<HttpRouteArgs, "cluster" | "namespace">>
|
31
50
|
|
32
|
-
|
33
|
-
|
51
|
+
/**
|
52
|
+
* The existing workload to patch.
|
53
|
+
*/
|
54
|
+
existing?: Input<k8s.ExposableWorkload>
|
55
|
+
}
|
34
56
|
|
35
|
-
|
57
|
+
export const exposableWorkloadExtraArgs = [...workloadExtraArgs, "service", "httpRoute"] as const
|
36
58
|
|
37
|
-
|
38
|
-
containers.map(container => mapContainerToRaw(container, name)),
|
39
|
-
)
|
59
|
+
export type ExposableWorkloadType = "Deployment" | "StatefulSet"
|
40
60
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
61
|
+
export type GenericExposableWorkloadArgs = Omit<ExposableWorkloadArgs, "existing"> & {
|
62
|
+
/**
|
63
|
+
* The type of workload to create.
|
64
|
+
*
|
65
|
+
* Will be ignored if the `existing` argument is provided.
|
66
|
+
*/
|
67
|
+
type: ExposableWorkloadType
|
48
68
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
69
|
+
/**
|
70
|
+
* The existing workload to patch.
|
71
|
+
*/
|
72
|
+
existing: Input<k8s.ExposableWorkload | undefined>
|
73
|
+
|
74
|
+
/**
|
75
|
+
* The args specific to the "Deployment" workload type.
|
76
|
+
*
|
77
|
+
* Will be ignored for other workload types.
|
78
|
+
*/
|
79
|
+
deployment?: Input<DeploymentArgs>
|
54
80
|
|
55
|
-
|
81
|
+
/**
|
82
|
+
* The args specific to the "StatefulSet" workload type.
|
83
|
+
*
|
84
|
+
* Will be ignored for other workload types.
|
85
|
+
*/
|
86
|
+
statefulSet?: Input<StatefulSetArgs>
|
87
|
+
}
|
56
88
|
|
57
|
-
export function getWorkloadComponents(
|
89
|
+
export function getWorkloadComponents(
|
90
|
+
name: string,
|
91
|
+
args: WorkloadArgs,
|
92
|
+
parent: () => ComponentResource,
|
93
|
+
opts: ComponentResourceOptions | undefined,
|
94
|
+
) {
|
58
95
|
const labels = {
|
59
96
|
"app.kubernetes.io/name": name,
|
60
97
|
}
|
61
98
|
|
62
99
|
const containers = output(args).apply(args => normalize(args.container, args.containers))
|
100
|
+
|
63
101
|
const volumes = containers.apply(containers => {
|
64
102
|
const containerVolumes = containers
|
65
103
|
.flatMap(container => normalize(container.volume, container.volumes))
|
@@ -75,30 +113,87 @@ export function getWorkloadComponents(name: string, args: WorkloadArgs) {
|
|
75
113
|
})
|
76
114
|
.map(mapWorkloadVolume)
|
77
115
|
|
78
|
-
return
|
116
|
+
return output([...containerVolumes, ...containerVolumeMounts]).apply(
|
117
|
+
uniqueBy(volume => volume.name),
|
118
|
+
)
|
119
|
+
})
|
120
|
+
|
121
|
+
const podSpec = output({ args, containers, volumes }).apply(({ args, containers, volumes }) => {
|
122
|
+
const spec = {
|
123
|
+
volumes,
|
124
|
+
containers: containers.map(container => mapContainerToRaw(container, args.cluster, name)),
|
125
|
+
...podSpecDefaults,
|
126
|
+
} satisfies types.input.core.v1.PodSpec
|
127
|
+
|
128
|
+
if (
|
129
|
+
containers.some(container => container.enableTun) &&
|
130
|
+
args.cluster.quirks?.tunDevicePolicy?.type !== "plugin"
|
131
|
+
) {
|
132
|
+
spec.volumes = output(spec.volumes).apply(volumes => [
|
133
|
+
...(volumes ?? []),
|
134
|
+
{
|
135
|
+
name: "tun-device",
|
136
|
+
hostPath: {
|
137
|
+
path: "/dev/net/tun",
|
138
|
+
},
|
139
|
+
},
|
140
|
+
])
|
141
|
+
}
|
142
|
+
|
143
|
+
return spec
|
79
144
|
})
|
80
145
|
|
81
|
-
|
146
|
+
const podTemplate = podSpec.apply(podSpec => {
|
147
|
+
return {
|
148
|
+
metadata: { labels },
|
149
|
+
spec: podSpec,
|
150
|
+
} satisfies types.input.core.v1.PodTemplateSpec
|
151
|
+
})
|
152
|
+
|
153
|
+
const networkPolicy = containers.apply(containers => {
|
154
|
+
const allowedEndpoints = containers.flatMap(container => container.allowedEndpoints ?? [])
|
155
|
+
|
156
|
+
if (allowedEndpoints.length === 0) {
|
157
|
+
return undefined
|
158
|
+
}
|
159
|
+
|
160
|
+
return NetworkPolicy.create(
|
161
|
+
name,
|
162
|
+
{
|
163
|
+
cluster: args.cluster,
|
164
|
+
namespace: args.namespace,
|
165
|
+
selector: labels,
|
166
|
+
|
167
|
+
egressRule: {
|
168
|
+
toEndpoints: allowedEndpoints,
|
169
|
+
},
|
170
|
+
},
|
171
|
+
{ ...opts, parent: parent() },
|
172
|
+
)
|
173
|
+
}) as Output<NetworkPolicy | undefined>
|
174
|
+
|
175
|
+
return { labels, containers, volumes, podSpec, podTemplate, networkPolicy }
|
82
176
|
}
|
83
177
|
|
84
|
-
export function
|
178
|
+
export function getExposableWorkloadComponents(
|
85
179
|
name: string,
|
86
|
-
args:
|
180
|
+
args: ExposableWorkloadArgs,
|
87
181
|
parent: () => ComponentResource,
|
88
|
-
opts: ComponentResourceOptions,
|
182
|
+
opts: ComponentResourceOptions | undefined,
|
89
183
|
) {
|
90
|
-
const { labels, containers, volumes } =
|
184
|
+
const { labels, containers, volumes, podSpec, podTemplate, networkPolicy } =
|
185
|
+
getWorkloadComponents(name, args, parent, opts)
|
91
186
|
|
92
|
-
const service = output({ args, containers }).apply(({ args, containers }) => {
|
187
|
+
const service = output({ args, containers }).apply(async ({ args, containers }) => {
|
93
188
|
if (!args.service && !args.httpRoute) {
|
94
189
|
return undefined
|
95
190
|
}
|
96
191
|
|
97
|
-
if (args.
|
98
|
-
return Service.of(name, args.
|
192
|
+
if (args.existing?.service) {
|
193
|
+
return Service.of(name, args.existing.service, args.cluster, { ...opts, parent: parent() })
|
99
194
|
}
|
100
195
|
|
101
|
-
if (args.
|
196
|
+
if (args.existing) {
|
102
197
|
return undefined
|
103
198
|
}
|
104
199
|
|
@@ -118,19 +213,23 @@ export function getPublicWorkloadComponents(
|
|
118
213
|
? ports.map(mapContainerPortToServicePort)
|
119
214
|
: args.service?.ports,
|
120
215
|
},
|
121
|
-
{
|
216
|
+
{
|
217
|
+
...opts,
|
218
|
+
parent: parent(),
|
219
|
+
provider: await getProvider(args.cluster),
|
220
|
+
},
|
122
221
|
)
|
123
222
|
})
|
124
223
|
|
125
224
|
const httpRoute = output({
|
126
225
|
args,
|
127
226
|
service,
|
128
|
-
}).apply(({ args, service }) => {
|
227
|
+
}).apply(async ({ args, service }) => {
|
129
228
|
if (!args.httpRoute || !service) {
|
130
229
|
return undefined
|
131
230
|
}
|
132
231
|
|
133
|
-
if (args.
|
232
|
+
if (args.existing) {
|
134
233
|
return undefined
|
135
234
|
}
|
136
235
|
|
@@ -138,13 +237,212 @@ export function getPublicWorkloadComponents(
|
|
138
237
|
name,
|
139
238
|
{
|
140
239
|
...args.httpRoute,
|
240
|
+
cluster: args.cluster,
|
141
241
|
rule: {
|
142
242
|
backend: service,
|
143
243
|
},
|
144
244
|
},
|
145
|
-
{
|
245
|
+
{
|
246
|
+
...opts,
|
247
|
+
parent: parent(),
|
248
|
+
provider: await getProvider(args.cluster),
|
249
|
+
},
|
146
250
|
)
|
147
251
|
})
|
148
252
|
|
149
|
-
return { labels, containers, volumes, service, httpRoute }
|
253
|
+
return { labels, containers, volumes, podSpec, podTemplate, networkPolicy, service, httpRoute }
|
254
|
+
}
|
255
|
+
|
256
|
+
export abstract class Workload extends ComponentResource {
|
257
|
+
protected constructor(
|
258
|
+
type: string,
|
259
|
+
protected readonly name: string,
|
260
|
+
private readonly args: WorkloadArgs,
|
261
|
+
opts: ComponentResourceOptions | undefined,
|
262
|
+
|
263
|
+
protected readonly resourceType: string,
|
264
|
+
|
265
|
+
/**
|
266
|
+
* The cluster where the workload is created.
|
267
|
+
*/
|
268
|
+
readonly cluster: Output<k8s.Cluster>,
|
269
|
+
|
270
|
+
/**
|
271
|
+
* The metadata of the underlying Kubernetes workload.
|
272
|
+
*/
|
273
|
+
readonly metadata: Output<types.output.meta.v1.ObjectMeta>,
|
274
|
+
|
275
|
+
/**
|
276
|
+
* The network policy associated with the workload.
|
277
|
+
*
|
278
|
+
* Will be created if one or more containers have `allowedEndpoints` defined.
|
279
|
+
*/
|
280
|
+
readonly networkPolicy: Output<NetworkPolicy | undefined>,
|
281
|
+
) {
|
282
|
+
super(type, name, args, opts)
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* The instance terminal to interact with the deployment.
|
287
|
+
*/
|
288
|
+
get terminal(): Output<InstanceTerminal> {
|
289
|
+
const containerName = output(this.args).apply(args => {
|
290
|
+
const containers = normalize(args.container, args.containers)
|
291
|
+
|
292
|
+
return containers[0]?.name ?? this.name
|
293
|
+
})
|
294
|
+
|
295
|
+
return output({
|
296
|
+
name: this.metadata.name,
|
297
|
+
title: this.metadata.name,
|
298
|
+
image: "ghcr.io/exeteres/highstate/terminal-kubectl",
|
299
|
+
command: [
|
300
|
+
"exec",
|
301
|
+
"kubectl",
|
302
|
+
"exec",
|
303
|
+
"-it",
|
304
|
+
"-n",
|
305
|
+
this.metadata.namespace,
|
306
|
+
interpolate`${this.resourceType}/${this.metadata.name}`,
|
307
|
+
"-c",
|
308
|
+
containerName,
|
309
|
+
"--",
|
310
|
+
this.args.terminalShell ?? "bash",
|
311
|
+
],
|
312
|
+
files: {
|
313
|
+
"/kubeconfig": this.cluster.kubeconfig,
|
314
|
+
},
|
315
|
+
env: {
|
316
|
+
KUBECONFIG: "/kubeconfig",
|
317
|
+
},
|
318
|
+
})
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
export abstract class ExposableWorkload extends Workload {
|
323
|
+
protected constructor(
|
324
|
+
type: string,
|
325
|
+
protected readonly name: string,
|
326
|
+
args: ExposableWorkloadArgs,
|
327
|
+
opts: ComponentResourceOptions | undefined,
|
328
|
+
|
329
|
+
resourceType: string,
|
330
|
+
cluster: Output<k8s.Cluster>,
|
331
|
+
metadata: Output<types.output.meta.v1.ObjectMeta>,
|
332
|
+
networkPolicy: Output<NetworkPolicy | undefined>,
|
333
|
+
|
334
|
+
protected readonly _service: Output<Service | undefined>,
|
335
|
+
protected readonly _httpRoute: Output<HttpRoute | undefined>,
|
336
|
+
) {
|
337
|
+
super(type, name, args, opts, resourceType, cluster, metadata, networkPolicy)
|
338
|
+
}
|
339
|
+
|
340
|
+
/**
|
341
|
+
* The service associated with the workload.
|
342
|
+
*/
|
343
|
+
get optionalService(): Output<Service | undefined> {
|
344
|
+
return this._service
|
345
|
+
}
|
346
|
+
|
347
|
+
/**
|
348
|
+
* The HTTP route associated with the workload.
|
349
|
+
*/
|
350
|
+
get optionalHttpRoute(): Output<HttpRoute | undefined> {
|
351
|
+
return this._httpRoute
|
352
|
+
}
|
353
|
+
|
354
|
+
/**
|
355
|
+
* The service associated with the workload.
|
356
|
+
*
|
357
|
+
* Will throw an error if the service is not available.
|
358
|
+
*/
|
359
|
+
get service(): Output<Service> {
|
360
|
+
return this._service.apply(service => {
|
361
|
+
if (!service) {
|
362
|
+
throw new Error(`The service of the workload "${this.name}" is not available.`)
|
363
|
+
}
|
364
|
+
|
365
|
+
return service
|
366
|
+
})
|
367
|
+
}
|
368
|
+
|
369
|
+
/**
|
370
|
+
* The HTTP route associated with the workload.
|
371
|
+
*
|
372
|
+
* Will throw an error if the HTTP route is not available.
|
373
|
+
*/
|
374
|
+
get httpRoute(): Output<HttpRoute> {
|
375
|
+
return this._httpRoute.apply(httpRoute => {
|
376
|
+
if (!httpRoute) {
|
377
|
+
throw new Error(`The HTTP route of the workload "${this.name}" is not available.`)
|
378
|
+
}
|
379
|
+
|
380
|
+
return httpRoute
|
381
|
+
})
|
382
|
+
}
|
383
|
+
|
384
|
+
/**
|
385
|
+
* The entity of the workload.
|
386
|
+
*/
|
387
|
+
abstract get entity(): Output<k8s.ExposableWorkload>
|
388
|
+
|
389
|
+
/**
|
390
|
+
* The sped of the underlying Kubernetes workload.
|
391
|
+
*/
|
392
|
+
abstract get spec(): Output<
|
393
|
+
types.output.apps.v1.DeploymentSpec | types.output.apps.v1.StatefulSetSpec
|
394
|
+
>
|
395
|
+
|
396
|
+
/**
|
397
|
+
* Creates a generic workload or patches the existing one.
|
398
|
+
*/
|
399
|
+
static createOrPatchGeneric(
|
400
|
+
name: string,
|
401
|
+
args: GenericExposableWorkloadArgs,
|
402
|
+
opts?: CustomResourceOptions,
|
403
|
+
): Output<ExposableWorkload> {
|
404
|
+
return output(args).apply(async args => {
|
405
|
+
if (args.existing?.type === "k8s.deployment") {
|
406
|
+
const { Deployment } = await import("./deployment")
|
407
|
+
|
408
|
+
return Deployment.patch(
|
409
|
+
name,
|
410
|
+
{
|
411
|
+
...deepmerge(args, args.deployment),
|
412
|
+
name: args.existing.metadata.name,
|
413
|
+
namespace: args.existing.metadata.namespace,
|
414
|
+
},
|
415
|
+
opts,
|
416
|
+
)
|
417
|
+
}
|
418
|
+
|
419
|
+
if (args.existing?.type === "k8s.stateful-set") {
|
420
|
+
const { StatefulSet } = await import("./stateful-set")
|
421
|
+
|
422
|
+
return StatefulSet.patch(
|
423
|
+
name,
|
424
|
+
{
|
425
|
+
...deepmerge(args, args.statefulSet),
|
426
|
+
name: args.existing.metadata.name,
|
427
|
+
namespace: args.existing.metadata.namespace,
|
428
|
+
},
|
429
|
+
opts,
|
430
|
+
)
|
431
|
+
}
|
432
|
+
|
433
|
+
if (args.type === "Deployment") {
|
434
|
+
const { Deployment } = await import("./deployment")
|
435
|
+
|
436
|
+
return Deployment.create(name, deepmerge(args, args.deployment), opts)
|
437
|
+
}
|
438
|
+
|
439
|
+
if (args.type === "StatefulSet") {
|
440
|
+
const { StatefulSet } = await import("./stateful-set")
|
441
|
+
|
442
|
+
return StatefulSet.create(name, deepmerge(args, args.statefulSet), opts)
|
443
|
+
}
|
444
|
+
|
445
|
+
throw new Error(`Unknown workload type: ${args.type as string}`)
|
446
|
+
})
|
447
|
+
}
|
150
448
|
}
|