@highstate/k8s 0.15.0 → 0.16.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.
- package/dist/chunk-22GOWZQP.js +286 -0
- package/dist/chunk-22GOWZQP.js.map +1 -0
- package/dist/{chunk-VJL2BFKO.js → chunk-4G6LLC2X.js} +13 -24
- package/dist/chunk-4G6LLC2X.js.map +1 -0
- package/dist/{chunk-C6WHUOC3.js → chunk-BR2CLUUD.js} +15 -26
- package/dist/chunk-BR2CLUUD.js.map +1 -0
- package/dist/{chunk-EACAK6W4.js → chunk-DCUMJSO6.js} +17 -28
- package/dist/chunk-DCUMJSO6.js.map +1 -0
- package/dist/{chunk-NWXKLVBC.js → chunk-HJKJHTJM.js} +20 -30
- package/dist/chunk-HJKJHTJM.js.map +1 -0
- package/dist/{chunk-7H4L3DFC.js → chunk-KMLRI5UZ.js} +57 -70
- package/dist/chunk-KMLRI5UZ.js.map +1 -0
- package/dist/{chunk-6ACIPGW4.js → chunk-LGHFSXNT.js} +12 -13
- package/dist/chunk-LGHFSXNT.js.map +1 -0
- package/dist/{chunk-SEWB4FUB.js → chunk-OBDQONMV.js} +64 -23
- package/dist/chunk-OBDQONMV.js.map +1 -0
- package/dist/chunk-SL5CBM3A.js +301 -0
- package/dist/chunk-SL5CBM3A.js.map +1 -0
- package/dist/{chunk-3CKMDTYK.js → chunk-TWBMG6TD.js} +68 -91
- package/dist/chunk-TWBMG6TD.js.map +1 -0
- package/dist/{chunk-YTRQ6JRU.js → chunk-XRIC6EJ3.js} +159 -94
- package/dist/chunk-XRIC6EJ3.js.map +1 -0
- package/dist/{chunk-O64YZLA4.js → chunk-ZBFWQHE4.js} +21 -30
- package/dist/chunk-ZBFWQHE4.js.map +1 -0
- package/dist/{chunk-4VGISFL4.js → chunk-ZHVKK2U6.js} +12 -11
- package/dist/chunk-ZHVKK2U6.js.map +1 -0
- package/dist/cron-job-LX35I6HG.js +8 -0
- package/dist/cron-job-LX35I6HG.js.map +1 -0
- package/dist/deployment-HRJGAEJR.js +8 -0
- package/dist/{deployment-THUD5QUH.js.map → deployment-HRJGAEJR.js.map} +1 -1
- package/dist/highstate.manifest.json +2 -3
- package/dist/impl/gateway-route.js +10 -10
- package/dist/impl/gateway-route.js.map +1 -1
- package/dist/impl/tls-certificate.js +3 -3
- package/dist/index.js +39 -627
- package/dist/index.js.map +1 -1
- package/dist/job-J4BKBVQD.js +8 -0
- package/dist/job-J4BKBVQD.js.map +1 -0
- package/dist/stateful-set-LAJR5RL4.js +8 -0
- package/dist/{stateful-set-ABCZML4L.js.map → stateful-set-LAJR5RL4.js.map} +1 -1
- package/dist/units/cert-manager/index.js +7 -7
- package/dist/units/cluster-patch/index.js +9 -18
- package/dist/units/cluster-patch/index.js.map +1 -1
- package/dist/units/dns01-issuer/index.js +6 -6
- package/dist/units/dns01-issuer/index.js.map +1 -1
- package/dist/units/existing-cluster/index.js +19 -9
- package/dist/units/existing-cluster/index.js.map +1 -1
- package/dist/units/gateway-api/index.js +2 -2
- package/dist/units/gateway-api/index.js.map +1 -1
- package/dist/units/reduced-access-cluster/index.js +18 -25
- package/dist/units/reduced-access-cluster/index.js.map +1 -1
- package/package.json +6 -11
- package/src/cluster.ts +14 -14
- package/src/config-map.ts +16 -30
- package/src/container.ts +1 -1
- package/src/cron-job.ts +23 -41
- package/src/deployment.ts +23 -30
- package/src/gateway/gateway.ts +21 -29
- package/src/helm.ts +7 -8
- package/src/impl/gateway-route.ts +5 -13
- package/src/job.ts +20 -38
- package/src/namespace.ts +18 -22
- package/src/network-policy.ts +37 -36
- package/src/network.ts +18 -10
- package/src/pvc.ts +12 -28
- package/src/rbac.ts +75 -97
- package/src/scripting/bundle.ts +3 -3
- package/src/scripting/environment.ts +3 -3
- package/src/secret.ts +16 -30
- package/src/service.ts +86 -105
- package/src/shared.ts +82 -20
- package/src/stateful-set.ts +17 -28
- package/src/tls.ts +20 -31
- package/src/units/cluster-patch/index.ts +9 -19
- package/src/units/dns01-issuer/index.ts +6 -6
- package/src/units/existing-cluster/index.ts +28 -10
- package/src/units/gateway-api/index.ts +1 -1
- package/src/units/reduced-access-cluster/index.ts +16 -24
- package/src/worker.ts +7 -5
- package/src/workload.ts +172 -28
- package/dist/chunk-3CKMDTYK.js.map +0 -1
- package/dist/chunk-4VGISFL4.js.map +0 -1
- package/dist/chunk-6ACIPGW4.js.map +0 -1
- package/dist/chunk-7H4L3DFC.js.map +0 -1
- package/dist/chunk-C6WHUOC3.js.map +0 -1
- package/dist/chunk-EACAK6W4.js.map +0 -1
- package/dist/chunk-NWXKLVBC.js.map +0 -1
- package/dist/chunk-O64YZLA4.js.map +0 -1
- package/dist/chunk-SEWB4FUB.js.map +0 -1
- package/dist/chunk-VJL2BFKO.js.map +0 -1
- package/dist/chunk-YTRQ6JRU.js.map +0 -1
- package/dist/deployment-THUD5QUH.js +0 -8
- package/dist/stateful-set-ABCZML4L.js +0 -8
- package/dist/units/cluster-dns/index.js +0 -37
- package/dist/units/cluster-dns/index.js.map +0 -1
- package/src/units/cluster-dns/index.ts +0 -37
|
@@ -1,33 +1,23 @@
|
|
|
1
|
-
import { l3EndpointToString, l4EndpointToString,
|
|
1
|
+
import { l3EndpointToString, l4EndpointToString, parseEndpoints } from "@highstate/common"
|
|
2
2
|
import { k8s } from "@highstate/library"
|
|
3
|
-
import { forUnit } from "@highstate/pulumi"
|
|
3
|
+
import { forUnit, toPromise } from "@highstate/pulumi"
|
|
4
4
|
|
|
5
5
|
const { args, inputs, outputs } = forUnit(k8s.clusterPatch)
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
inputs.endpoints,
|
|
11
|
-
args.endpointsPatchMode,
|
|
12
|
-
)
|
|
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)
|
|
13
10
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
args.apiEndpoints,
|
|
17
|
-
inputs.apiEndpoints,
|
|
18
|
-
args.apiEndpointsPatchMode,
|
|
19
|
-
)
|
|
11
|
+
const newEndpoints = endpoints.length > 0 ? endpoints : cluster.endpoints
|
|
12
|
+
const newApiEndpoints = apiEndpoints.length > 0 ? apiEndpoints : cluster.apiEndpoints
|
|
20
13
|
|
|
21
14
|
export default outputs({
|
|
22
15
|
k8sCluster: inputs.k8sCluster.apply(k8sCluster => ({
|
|
23
16
|
...k8sCluster,
|
|
24
|
-
endpoints,
|
|
25
|
-
apiEndpoints,
|
|
17
|
+
endpoints: newEndpoints,
|
|
18
|
+
apiEndpoints: newApiEndpoints,
|
|
26
19
|
})),
|
|
27
20
|
|
|
28
|
-
endpoints,
|
|
29
|
-
apiEndpoints,
|
|
30
|
-
|
|
31
21
|
$statusFields: {
|
|
32
22
|
endpoints: endpoints.map(l3EndpointToString),
|
|
33
23
|
apiEndpoints: apiEndpoints.map(l4EndpointToString),
|
|
@@ -28,7 +28,7 @@ new cert_manager.v1.ClusterIssuer(
|
|
|
28
28
|
dns01: dns01SolverMediator.callOutput(inputs.dnsProvider.implRef, {
|
|
29
29
|
namespace: certManagerNs,
|
|
30
30
|
}),
|
|
31
|
-
selector: { dnsZones:
|
|
31
|
+
selector: { dnsZones: inputs.dnsProvider.zones },
|
|
32
32
|
},
|
|
33
33
|
],
|
|
34
34
|
privateKeySecretRef: {
|
|
@@ -41,12 +41,8 @@ new cert_manager.v1.ClusterIssuer(
|
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
export default outputs({
|
|
44
|
-
$statusFields: {
|
|
45
|
-
domain: inputs.dnsProvider.domain,
|
|
46
|
-
},
|
|
47
|
-
|
|
48
44
|
tlsIssuer: {
|
|
49
|
-
|
|
45
|
+
zones: inputs.dnsProvider.zones,
|
|
50
46
|
implRef: {
|
|
51
47
|
package: "@highstate/k8s",
|
|
52
48
|
data: {
|
|
@@ -55,4 +51,8 @@ export default outputs({
|
|
|
55
51
|
},
|
|
56
52
|
},
|
|
57
53
|
},
|
|
54
|
+
|
|
55
|
+
$statusFields: {
|
|
56
|
+
zones: inputs.dnsProvider.zones,
|
|
57
|
+
},
|
|
58
58
|
})
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
l3EndpointToString,
|
|
3
3
|
l4EndpointToString,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
mergeAddresses,
|
|
5
|
+
mergeEndpoints,
|
|
6
|
+
parseAddress,
|
|
7
|
+
parseEndpoint,
|
|
8
|
+
parseEndpoints,
|
|
6
9
|
} from "@highstate/common"
|
|
7
10
|
import { type ImplementationReference, k8s } from "@highstate/library"
|
|
8
11
|
import { forUnit, secret, toPromise } from "@highstate/pulumi"
|
|
@@ -10,7 +13,7 @@ import { AppsV1Api, KubeConfig } from "@kubernetes/client-node"
|
|
|
10
13
|
import { core, Provider } from "@pulumi/kubernetes"
|
|
11
14
|
import { createK8sTerminal, detectExternalIps } from "../../cluster"
|
|
12
15
|
|
|
13
|
-
const { name, args, secrets, outputs } = forUnit(k8s.existingCluster)
|
|
16
|
+
const { name, args, inputs, secrets, outputs } = forUnit(k8s.existingCluster)
|
|
14
17
|
|
|
15
18
|
const kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringify))
|
|
16
19
|
|
|
@@ -35,11 +38,29 @@ if (hasCilium) {
|
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
// calculate external IPs
|
|
42
|
+
let externalIps = args.externalIps.map(parseAddress)
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
const
|
|
44
|
+
if (args.autoDetectExternalIps) {
|
|
45
|
+
const detectedIps = await detectExternalIps(kubeConfig, args.internalIpsPolicy)
|
|
46
|
+
externalIps = mergeAddresses([...externalIps, ...detectedIps])
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// calculate endpoints
|
|
50
|
+
let endpoints = await parseEndpoints(args.endpoints, inputs.endpoints)
|
|
51
|
+
|
|
52
|
+
if (args.useExternalIpsAsEndpoints) {
|
|
53
|
+
const ipEndpoints = externalIps.map(ip => parseEndpoint(ip))
|
|
54
|
+
endpoints = mergeEndpoints([...endpoints, ...ipEndpoints])
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// calculate api endpoints
|
|
58
|
+
let apiEndpoints = await parseEndpoints(args.apiEndpoints, inputs.endpoints, 4)
|
|
59
|
+
|
|
60
|
+
if (args.useKubeconfigApiEndpoint) {
|
|
61
|
+
const configEndpoint = parseEndpoint(kubeConfig.clusters[0].server.replace("https://", ""), 4)
|
|
62
|
+
apiEndpoints = mergeEndpoints([configEndpoint, ...apiEndpoints])
|
|
63
|
+
}
|
|
43
64
|
|
|
44
65
|
const kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provider })
|
|
45
66
|
|
|
@@ -56,9 +77,6 @@ export default outputs({
|
|
|
56
77
|
kubeconfig: secret(kubeconfigContent),
|
|
57
78
|
},
|
|
58
79
|
|
|
59
|
-
endpoints,
|
|
60
|
-
apiEndpoints,
|
|
61
|
-
|
|
62
80
|
$terminals: [createK8sTerminal(kubeconfigContent)],
|
|
63
81
|
|
|
64
82
|
$statusFields: {
|
|
@@ -10,7 +10,7 @@ const provider = await getProviderAsync(inputs.k8sCluster)
|
|
|
10
10
|
new yaml.v2.ConfigFile(
|
|
11
11
|
"gateway-api",
|
|
12
12
|
{
|
|
13
|
-
file: "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.
|
|
13
|
+
file: "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yaml",
|
|
14
14
|
},
|
|
15
15
|
{ provider },
|
|
16
16
|
)
|
|
@@ -3,39 +3,31 @@ import { k8s } from "@highstate/library"
|
|
|
3
3
|
import { fileFromString, forUnit, interpolate, output, secret, toPromise } from "@highstate/pulumi"
|
|
4
4
|
import { join } from "remeda"
|
|
5
5
|
import { createK8sTerminal } from "../../cluster"
|
|
6
|
-
import { ConfigMap } from "../../config-map"
|
|
7
|
-
import { Deployment } from "../../deployment"
|
|
8
6
|
import { Namespace } from "../../namespace"
|
|
9
|
-
import { PersistentVolumeClaim } from "../../pvc"
|
|
10
7
|
import { ClusterAccessScope } from "../../rbac"
|
|
11
|
-
import { Secret } from "../../secret"
|
|
12
|
-
import { Service } from "../../service"
|
|
13
|
-
import { StatefulSet } from "../../stateful-set"
|
|
14
8
|
|
|
15
|
-
const {
|
|
9
|
+
const { args, inputs, outputs } = forUnit(k8s.reducedAccessCluster)
|
|
16
10
|
|
|
17
11
|
const resolvedInputs = await toPromise(inputs)
|
|
18
12
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const accessScope = await ClusterAccessScope.forResources(args.serviceAccountName ?? name, {
|
|
31
|
-
namespace: Namespace.for(resolvedInputs.namespace, inputs.k8sCluster),
|
|
32
|
-
verbs: args.verbs,
|
|
33
|
-
resources,
|
|
34
|
-
})
|
|
13
|
+
const accessScope = new ClusterAccessScope(
|
|
14
|
+
"scope",
|
|
15
|
+
{
|
|
16
|
+
namespace: Namespace.for(resolvedInputs.namespace, inputs.k8sCluster),
|
|
17
|
+
extraNamespaces: resolvedInputs.extraNamespaces.map(ns => Namespace.for(ns, inputs.k8sCluster)),
|
|
18
|
+
rules: args.rules,
|
|
19
|
+
resources: resolvedInputs.resources,
|
|
20
|
+
},
|
|
21
|
+
{},
|
|
22
|
+
)
|
|
35
23
|
|
|
36
24
|
const resourceLines = await toPromise(
|
|
37
25
|
output(
|
|
38
|
-
resources.map(r =>
|
|
26
|
+
resolvedInputs.resources.map(r =>
|
|
27
|
+
r.isNamespaced
|
|
28
|
+
? interpolate`- ${r.kind} "${r.metadata.namespace}/${r.metadata.name}"`
|
|
29
|
+
: interpolate`- ${r.kind} "${r.metadata.name}"`,
|
|
30
|
+
),
|
|
39
31
|
).apply(join("\n")),
|
|
40
32
|
)
|
|
41
33
|
|
package/src/worker.ts
CHANGED
|
@@ -4,17 +4,19 @@ 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
|
|
7
|
+
import { images, type NamespacedResource } from "./shared"
|
|
8
8
|
|
|
9
9
|
export async function createMonitorWorker(
|
|
10
10
|
namespace: Input<Namespace>,
|
|
11
|
-
resources: InputArray<
|
|
11
|
+
resources: InputArray<NamespacedResource>,
|
|
12
12
|
): Promise<Output<Unwrap<UnitWorker>>> {
|
|
13
|
-
const scope =
|
|
13
|
+
const scope = new ClusterAccessScope("monitor", {
|
|
14
|
+
rule: {
|
|
15
|
+
verbs: ["get", "list", "watch"],
|
|
16
|
+
},
|
|
17
|
+
|
|
14
18
|
namespace,
|
|
15
19
|
resources,
|
|
16
|
-
verbs: ["get", "list", "watch"],
|
|
17
|
-
collectionAccess: true,
|
|
18
20
|
})
|
|
19
21
|
|
|
20
22
|
return output({
|
package/src/workload.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { k8s } from "@highstate/library"
|
|
1
|
+
import type { k8s, network } from "@highstate/library"
|
|
2
2
|
import type { types } from "@pulumi/kubernetes"
|
|
3
3
|
import type { Except } from "type-fest"
|
|
4
4
|
import type { DeploymentArgs } from "./deployment"
|
|
5
|
+
import type { JobArgs } from "./job"
|
|
5
6
|
import type { StatefulSetArgs } from "./stateful-set"
|
|
6
|
-
import { AccessPointRoute, type AccessPointRouteArgs } from "@highstate/common"
|
|
7
|
+
import { AccessPointRoute, type AccessPointRouteArgs, mergeEndpoints } from "@highstate/common"
|
|
7
8
|
import { type TerminalSpec, trimIndentation, type UnitTerminal } from "@highstate/contract"
|
|
8
9
|
import {
|
|
9
10
|
type ComponentResourceOptions,
|
|
@@ -25,7 +26,7 @@ import {
|
|
|
25
26
|
} from "@pulumi/pulumi"
|
|
26
27
|
import { sha256 } from "crypto-hash"
|
|
27
28
|
import { deepmerge } from "deepmerge-ts"
|
|
28
|
-
import { filter, isNonNullish, unique, uniqueBy } from "remeda"
|
|
29
|
+
import { filter, flat, isNonNullish, unique, uniqueBy } from "remeda"
|
|
29
30
|
import {
|
|
30
31
|
type Container,
|
|
31
32
|
getFallbackContainerName,
|
|
@@ -38,7 +39,7 @@ import { Namespace } from "./namespace"
|
|
|
38
39
|
import { NetworkPolicy, type NetworkPolicyArgs } from "./network-policy"
|
|
39
40
|
import { podSpecDefaults } from "./pod"
|
|
40
41
|
import { mapContainerPortToServicePort, Service, type ServiceArgs } from "./service"
|
|
41
|
-
import { commonExtraArgs, images,
|
|
42
|
+
import { commonExtraArgs, images, NamespacedResource, type ScopedResourceArgs } from "./shared"
|
|
42
43
|
|
|
43
44
|
export type WorkloadTerminalArgs = {
|
|
44
45
|
/**
|
|
@@ -114,15 +115,58 @@ export const exposableWorkloadExtraArgs = [
|
|
|
114
115
|
"routes",
|
|
115
116
|
] as const
|
|
116
117
|
|
|
118
|
+
export type WorkloadType = "Deployment" | "StatefulSet" | "Job" | "CronJob"
|
|
117
119
|
export type ExposableWorkloadType = "Deployment" | "StatefulSet"
|
|
118
120
|
|
|
121
|
+
export type GenericWorkloadArgs = Omit<ExposableWorkloadArgs, "existing"> & {
|
|
122
|
+
/**
|
|
123
|
+
* The type of workload to create.
|
|
124
|
+
*
|
|
125
|
+
* Will be ignored if the `existing` argument is provided.
|
|
126
|
+
*/
|
|
127
|
+
defaultType: WorkloadType
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The existing workload to patch.
|
|
131
|
+
*/
|
|
132
|
+
existing: Input<k8s.Workload | undefined>
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The args specific to the "Deployment" workload type.
|
|
136
|
+
*
|
|
137
|
+
* Will be ignored for other workload types.
|
|
138
|
+
*/
|
|
139
|
+
deployment?: Input<DeploymentArgs>
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The args specific to the "StatefulSet" workload type.
|
|
143
|
+
*
|
|
144
|
+
* Will be ignored for other workload types.
|
|
145
|
+
*/
|
|
146
|
+
statefulSet?: Input<StatefulSetArgs>
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The args specific to the "Job" workload type.
|
|
150
|
+
*
|
|
151
|
+
* Will be ignored for other workload types.
|
|
152
|
+
*/
|
|
153
|
+
job?: Input<JobArgs>
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The args specific to the "CronJob" workload type.
|
|
157
|
+
*
|
|
158
|
+
* Will be ignored for other workload types.
|
|
159
|
+
*/
|
|
160
|
+
cronJob?: Input<JobArgs>
|
|
161
|
+
}
|
|
162
|
+
|
|
119
163
|
export type GenericExposableWorkloadArgs = Omit<ExposableWorkloadArgs, "existing"> & {
|
|
120
164
|
/**
|
|
121
165
|
* The type of workload to create.
|
|
122
166
|
*
|
|
123
167
|
* Will be ignored if the `existing` argument is provided.
|
|
124
168
|
*/
|
|
125
|
-
|
|
169
|
+
defaultType: ExposableWorkloadType
|
|
126
170
|
|
|
127
171
|
/**
|
|
128
172
|
* The existing workload to patch.
|
|
@@ -341,19 +385,18 @@ export function getExposableWorkloadComponents(
|
|
|
341
385
|
return { labels, containers, volumes, podSpec, podTemplate, networkPolicy, service, routes }
|
|
342
386
|
}
|
|
343
387
|
|
|
344
|
-
export abstract class Workload extends
|
|
388
|
+
export abstract class Workload extends NamespacedResource {
|
|
345
389
|
protected constructor(
|
|
346
390
|
type: string,
|
|
347
391
|
protected readonly name: string,
|
|
348
392
|
args: Inputs,
|
|
349
393
|
opts: ComponentResourceOptions | undefined,
|
|
350
394
|
|
|
351
|
-
|
|
352
|
-
|
|
395
|
+
metadata: Output<types.output.meta.v1.ObjectMeta>,
|
|
396
|
+
namespace: Output<Namespace>,
|
|
397
|
+
|
|
353
398
|
protected readonly terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,
|
|
354
399
|
protected readonly containers: Output<Container[]>,
|
|
355
|
-
namespace: Output<Namespace>,
|
|
356
|
-
metadata: Output<types.output.meta.v1.ObjectMeta>,
|
|
357
400
|
|
|
358
401
|
/**
|
|
359
402
|
* The rendered pod template of the workload.
|
|
@@ -367,7 +410,7 @@ export abstract class Workload extends ScopedResource {
|
|
|
367
410
|
*/
|
|
368
411
|
readonly networkPolicy: Output<NetworkPolicy | undefined>,
|
|
369
412
|
) {
|
|
370
|
-
super(type, name, args, opts,
|
|
413
|
+
super(type, name, args, opts, metadata, namespace)
|
|
371
414
|
}
|
|
372
415
|
|
|
373
416
|
protected abstract get templateMetadata(): Output<types.output.meta.v1.ObjectMeta>
|
|
@@ -378,7 +421,7 @@ export abstract class Workload extends ScopedResource {
|
|
|
378
421
|
private set terminal(_value: never) {}
|
|
379
422
|
|
|
380
423
|
/**
|
|
381
|
-
* The instance terminal to interact with the
|
|
424
|
+
* The instance terminal to interact with the workload's pods.
|
|
382
425
|
*/
|
|
383
426
|
get terminal(): Output<UnitTerminal> {
|
|
384
427
|
const containerName = this.podTemplate.spec.containers.apply(containers => containers[0].name)
|
|
@@ -411,7 +454,7 @@ export abstract class Workload extends ScopedResource {
|
|
|
411
454
|
set -euo pipefail
|
|
412
455
|
|
|
413
456
|
NAMESPACE="${this.metadata.namespace}"
|
|
414
|
-
RESOURCE_TYPE="${this.kind.
|
|
457
|
+
RESOURCE_TYPE="${this.kind.toLowerCase()}"
|
|
415
458
|
RESOURCE_NAME="${this.metadata.name}"
|
|
416
459
|
CONTAINER_NAME="${containerName}"
|
|
417
460
|
SHELL="${shell}"
|
|
@@ -496,7 +539,7 @@ export abstract class Workload extends ScopedResource {
|
|
|
496
539
|
"-it",
|
|
497
540
|
"-n",
|
|
498
541
|
this.metadata.namespace,
|
|
499
|
-
|
|
542
|
+
`${this.kind.toLowerCase()}/${this.metadata.name}`,
|
|
500
543
|
"-c",
|
|
501
544
|
containerName,
|
|
502
545
|
"--",
|
|
@@ -515,6 +558,99 @@ export abstract class Workload extends ScopedResource {
|
|
|
515
558
|
},
|
|
516
559
|
})
|
|
517
560
|
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Creates a generic workload or patches the existing one.
|
|
564
|
+
*/
|
|
565
|
+
static createOrPatchGeneric(
|
|
566
|
+
name: string,
|
|
567
|
+
args: GenericWorkloadArgs,
|
|
568
|
+
opts?: CustomResourceOptions,
|
|
569
|
+
): Output<Workload> {
|
|
570
|
+
return output(args).apply(async args => {
|
|
571
|
+
if (args.existing?.kind === "Deployment") {
|
|
572
|
+
const { Deployment } = await import("./deployment")
|
|
573
|
+
|
|
574
|
+
return Deployment.patch(
|
|
575
|
+
name,
|
|
576
|
+
{
|
|
577
|
+
...deepmerge(args, args.deployment),
|
|
578
|
+
name: args.existing.metadata.name,
|
|
579
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),
|
|
580
|
+
},
|
|
581
|
+
opts,
|
|
582
|
+
)
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
if (args.existing?.kind === "StatefulSet") {
|
|
586
|
+
const { StatefulSet } = await import("./stateful-set")
|
|
587
|
+
|
|
588
|
+
return StatefulSet.patch(
|
|
589
|
+
name,
|
|
590
|
+
{
|
|
591
|
+
...deepmerge(args, args.statefulSet),
|
|
592
|
+
name: args.existing.metadata.name,
|
|
593
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),
|
|
594
|
+
},
|
|
595
|
+
opts,
|
|
596
|
+
)
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (args.existing?.kind === "Job") {
|
|
600
|
+
const { Job } = await import("./job")
|
|
601
|
+
|
|
602
|
+
return Job.patch(
|
|
603
|
+
name,
|
|
604
|
+
{
|
|
605
|
+
...deepmerge(args, args.job),
|
|
606
|
+
name: args.existing.metadata.name,
|
|
607
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),
|
|
608
|
+
},
|
|
609
|
+
opts,
|
|
610
|
+
)
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (args.existing?.kind === "CronJob") {
|
|
614
|
+
const { CronJob } = await import("./cron-job")
|
|
615
|
+
|
|
616
|
+
return CronJob.patch(
|
|
617
|
+
name,
|
|
618
|
+
{
|
|
619
|
+
...deepmerge(args, args.cronJob),
|
|
620
|
+
name: args.existing.metadata.name,
|
|
621
|
+
namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),
|
|
622
|
+
},
|
|
623
|
+
opts,
|
|
624
|
+
)
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (args.defaultType === "Deployment") {
|
|
628
|
+
const { Deployment } = await import("./deployment")
|
|
629
|
+
|
|
630
|
+
return Deployment.create(name, deepmerge(args, args.deployment), opts)
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
if (args.defaultType === "StatefulSet") {
|
|
634
|
+
const { StatefulSet } = await import("./stateful-set")
|
|
635
|
+
|
|
636
|
+
return StatefulSet.create(name, deepmerge(args, args.statefulSet), opts)
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (args.defaultType === "Job") {
|
|
640
|
+
const { Job } = await import("./job")
|
|
641
|
+
|
|
642
|
+
return Job.create(name, deepmerge(args, args.job), opts)
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (args.defaultType === "CronJob") {
|
|
646
|
+
const { CronJob } = await import("./cron-job")
|
|
647
|
+
|
|
648
|
+
return CronJob.create(name, deepmerge(args, args.cronJob), opts)
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
throw new Error(`Unknown workload type: ${args.defaultType as string}`)
|
|
652
|
+
})
|
|
653
|
+
}
|
|
518
654
|
}
|
|
519
655
|
|
|
520
656
|
export abstract class ExposableWorkload extends Workload {
|
|
@@ -524,12 +660,11 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
524
660
|
args: Inputs,
|
|
525
661
|
opts: ComponentResourceOptions | undefined,
|
|
526
662
|
|
|
527
|
-
|
|
528
|
-
|
|
663
|
+
metadata: Output<types.output.meta.v1.ObjectMeta>,
|
|
664
|
+
namespace: Output<Namespace>,
|
|
665
|
+
|
|
529
666
|
terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,
|
|
530
667
|
containers: Output<Container[]>,
|
|
531
|
-
namespace: Output<Namespace>,
|
|
532
|
-
metadata: Output<types.output.meta.v1.ObjectMeta>,
|
|
533
668
|
podTemplate: Output<types.output.core.v1.PodTemplateSpec>,
|
|
534
669
|
networkPolicy: Output<NetworkPolicy | undefined>,
|
|
535
670
|
|
|
@@ -545,12 +680,10 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
545
680
|
name,
|
|
546
681
|
args,
|
|
547
682
|
opts,
|
|
548
|
-
|
|
549
|
-
|
|
683
|
+
metadata,
|
|
684
|
+
namespace,
|
|
550
685
|
terminalArgs,
|
|
551
686
|
containers,
|
|
552
|
-
namespace,
|
|
553
|
-
metadata,
|
|
554
687
|
podTemplate,
|
|
555
688
|
networkPolicy,
|
|
556
689
|
)
|
|
@@ -584,6 +717,17 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
584
717
|
})
|
|
585
718
|
}
|
|
586
719
|
|
|
720
|
+
/**
|
|
721
|
+
* The merged and deduplicated L3 endpoints of all routes.
|
|
722
|
+
*/
|
|
723
|
+
get endpoints(): Output<network.L3Endpoint[]> {
|
|
724
|
+
return this.routes.apply(routes =>
|
|
725
|
+
output(routes.map(route => route.route.endpoints))
|
|
726
|
+
.apply(endpoints => flat(endpoints))
|
|
727
|
+
.apply(mergeEndpoints),
|
|
728
|
+
)
|
|
729
|
+
}
|
|
730
|
+
|
|
587
731
|
/**
|
|
588
732
|
* The entity of the workload.
|
|
589
733
|
*/
|
|
@@ -597,7 +741,7 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
597
741
|
>
|
|
598
742
|
|
|
599
743
|
/**
|
|
600
|
-
* Creates a generic workload or patches the existing one.
|
|
744
|
+
* Creates a generic exposable workload or patches the existing one.
|
|
601
745
|
*/
|
|
602
746
|
static createOrPatchGeneric(
|
|
603
747
|
name: string,
|
|
@@ -605,7 +749,7 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
605
749
|
opts?: CustomResourceOptions,
|
|
606
750
|
): Output<ExposableWorkload> {
|
|
607
751
|
return output(args).apply(async args => {
|
|
608
|
-
if (args.existing?.
|
|
752
|
+
if (args.existing?.kind === "Deployment") {
|
|
609
753
|
const { Deployment } = await import("./deployment")
|
|
610
754
|
|
|
611
755
|
return Deployment.patch(
|
|
@@ -619,7 +763,7 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
619
763
|
)
|
|
620
764
|
}
|
|
621
765
|
|
|
622
|
-
if (args.existing?.
|
|
766
|
+
if (args.existing?.kind === "StatefulSet") {
|
|
623
767
|
const { StatefulSet } = await import("./stateful-set")
|
|
624
768
|
|
|
625
769
|
return StatefulSet.patch(
|
|
@@ -633,19 +777,19 @@ export abstract class ExposableWorkload extends Workload {
|
|
|
633
777
|
)
|
|
634
778
|
}
|
|
635
779
|
|
|
636
|
-
if (args.
|
|
780
|
+
if (args.defaultType === "Deployment") {
|
|
637
781
|
const { Deployment } = await import("./deployment")
|
|
638
782
|
|
|
639
783
|
return Deployment.create(name, deepmerge(args, args.deployment), opts)
|
|
640
784
|
}
|
|
641
785
|
|
|
642
|
-
if (args.
|
|
786
|
+
if (args.defaultType === "StatefulSet") {
|
|
643
787
|
const { StatefulSet } = await import("./stateful-set")
|
|
644
788
|
|
|
645
789
|
return StatefulSet.create(name, deepmerge(args, args.statefulSet), opts)
|
|
646
790
|
}
|
|
647
791
|
|
|
648
|
-
throw new Error(`Unknown workload type: ${args.
|
|
792
|
+
throw new Error(`Unknown workload type: ${args.defaultType as string}`)
|
|
649
793
|
})
|
|
650
794
|
}
|
|
651
795
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/service.ts"],"names":["args"],"mappings":"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","file":"chunk-3CKMDTYK.js","sourcesContent":["import { filterEndpoints, l4EndpointToString, parseL3Endpoint } from \"@highstate/common\"\nimport { check, getOrCreate } from \"@highstate/contract\"\nimport { k8s, type network } from \"@highstate/library\"\nimport {\n type ComponentResourceOptions,\n type Input,\n type Inputs,\n interpolate,\n normalize,\n type Output,\n output,\n toPromise,\n} from \"@highstate/pulumi\"\nimport { core, type types } from \"@pulumi/kubernetes\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { omit, uniqueBy } from \"remeda\"\nimport { Namespace } from \"./namespace\"\nimport {\n commonExtraArgs,\n getProvider,\n mapMetadata,\n ScopedResource,\n type ScopedResourceArgs,\n} from \"./shared\"\n\nexport type ServiceArgs = ScopedResourceArgs & {\n /**\n * The port to expose the service on.\n */\n port?: Input<types.input.core.v1.ServicePort>\n\n /**\n * Whether the service should be exposed by `NodePort` or `LoadBalancer`.\n *\n * The type of the service will be determined automatically based on the cluster.\n */\n external?: Input<boolean>\n} & types.input.core.v1.ServiceSpec\n\nexport type CreateOrGetServiceArgs = ServiceArgs & {\n /**\n * The service entity to patch/retrieve.\n */\n existing: Input<k8s.Service> | undefined\n}\n\nconst serviceExtraArgs = [...commonExtraArgs, \"port\", \"ports\", \"external\"] as const\n\n/**\n * Checks if the endpoint is from the given cluster.\n *\n * @param endpoint The endpoint to check.\n * @param cluster The cluster to check against.\n * @returns True if the endpoint is from the cluster, false otherwise.\n */\nexport function isEndpointFromCluster(\n endpoint: network.L3Endpoint,\n cluster: k8s.Cluster,\n): endpoint is k8s.ServiceEndpoint {\n return (\n check(k8s.serviceEndpointSchema, endpoint) &&\n endpoint.metadata[\"k8s.service\"].clusterId === cluster.id\n )\n}\n\n/**\n * Represents a Kubernetes Service resource with endpoints and metadata.\n */\nexport abstract class Service extends ScopedResource {\n protected constructor(\n type: string,\n name: string,\n args: Inputs,\n opts: ComponentResourceOptions | undefined,\n\n apiVersion: Output<string>,\n kind: Output<string>,\n namespace: Output<Namespace>,\n metadata: Output<types.output.meta.v1.ObjectMeta>,\n\n /**\n * The spec of the underlying Kubernetes service.\n */\n readonly spec: Output<types.output.core.v1.ServiceSpec>,\n\n /**\n * The status of the underlying Kubernetes service.\n */\n readonly status: Output<types.output.core.v1.ServiceStatus>,\n ) {\n super(type, name, args, opts, apiVersion, kind, namespace, metadata)\n }\n\n /**\n * The Highstate service entity.\n */\n get entity(): Output<k8s.Service> {\n return output({\n type: \"service\",\n clusterId: this.cluster.id,\n clusterName: this.cluster.name,\n metadata: this.metadata,\n endpoints: this.endpoints,\n })\n }\n\n /**\n * Creates a new service.\n */\n static create(name: string, args: ServiceArgs, opts?: ComponentResourceOptions): Service {\n return new CreatedService(name, args, opts)\n }\n\n /**\n * Creates a new service or patches an existing one.\n *\n * @param name The name of the resource. May not be the same as the service name.\n * @param args The arguments to create or patch the service with.\n * @param opts Optional resource options.\n */\n static createOrPatch(\n name: string,\n args: CreateOrGetServiceArgs,\n opts?: ComponentResourceOptions,\n ): Service {\n if (args.existing) {\n return new ServicePatch(name, {\n ...args,\n name: output(args.existing).metadata.name,\n namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),\n })\n }\n\n return new CreatedService(name, args, opts)\n }\n\n /**\n * Creates a new service or gets an existing one.\n *\n * @param name The name of the resource. May not be the same as the service name. Will not be used when existing service is retrieved.\n * @param args The arguments to create or get the service with.\n * @param opts Optional resource options.\n */\n static async createOrGet(\n name: string,\n args: CreateOrGetServiceArgs,\n opts?: ComponentResourceOptions,\n ): Promise<Service> {\n if (args.existing) {\n return await Service.forAsync(args.existing, output(args.namespace).cluster)\n }\n\n return new CreatedService(name, args, opts)\n }\n\n /**\n * Patches an existing service.\n *\n * Will throw an error if the service does not exist.\n *\n * @param name The name of the resource. May not be the same as the service name.\n * @param args The arguments to patch the service with.\n * @param opts Optional resource options.\n */\n static patch(name: string, args: ServiceArgs, opts?: ComponentResourceOptions): Service {\n return new ServicePatch(name, args, opts)\n }\n\n /**\n * Wraps an existing Kubernetes service.\n */\n static wrap(name: string, args: WrappedServiceArgs, opts?: ComponentResourceOptions): Service {\n return new WrappedService(name, args, opts)\n }\n\n /**\n * Gets an existing service.\n *\n * Will throw an error if the service does not exist.\n */\n static get(name: string, args: ExternalServiceArgs, opts?: ComponentResourceOptions): Service {\n return new ExternalService(name, args, opts)\n }\n\n private static readonly serviceCache = new Map<string, Service>()\n\n /**\n * Gets an existing service for a given entity.\n * Prefer this method over `get` when possible.\n *\n * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.\n *\n * This method is idempotent and will return the same instance for the same entity.\n *\n * @param entity The entity to get the service for.\n * @param cluster The cluster where the service is located.\n */\n static for(entity: k8s.Service, cluster: Input<k8s.Cluster>): Service {\n return getOrCreate(\n Service.serviceCache,\n `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,\n name => {\n return Service.get(name, {\n name: entity.metadata.name,\n namespace: Namespace.forResourceAsync(entity, cluster),\n })\n },\n )\n }\n\n /**\n * Gets an existing service for a given entity.\n * Prefer this method over `get` when possible.\n *\n * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.\n *\n * This method is idempotent and will return the same instance for the same entity.\n *\n * @param entity The entity to get the service for.\n * @param cluster The cluster where the service is located.\n */\n static async forAsync(entity: Input<k8s.Service>, cluster: Input<k8s.Cluster>): Promise<Service> {\n const resolvedEntity = await toPromise(entity)\n\n return Service.for(resolvedEntity, output(cluster))\n }\n\n /**\n * Returns the endpoints of the service applying the given filter.\n *\n * If no filter is specified, the default behavior of `filterEndpoints` is used.\n *\n * @param filter If specified, the endpoints are filtered based on the given filter.\n * @returns The endpoints of the service.\n */\n filterEndpoints(filter?: network.EndpointFilter): Output<k8s.ServiceEndpoint[]> {\n return output(this.endpoints).apply(endpoints => filterEndpoints(endpoints, filter))\n }\n\n /**\n * Returns the endpoints of the service including both internal and external endpoints.\n */\n get endpoints(): Output<k8s.ServiceEndpoint[]> {\n return output({\n cluster: this.cluster,\n metadata: this.metadata,\n spec: this.spec,\n status: this.status,\n }).apply(({ cluster, metadata, spec, status }) => {\n const endpointMetadata: k8s.EndpointServiceMetadata = {\n \"k8s.service\": {\n clusterId: cluster.id,\n clusterName: cluster.name,\n name: metadata.name,\n namespace: metadata.namespace,\n selector: spec.selector,\n targetPort: spec.ports[0].targetPort ?? spec.ports[0].port,\n },\n }\n\n const clusterIpEndpoints = spec.clusterIPs?.map(ip => ({\n ...parseL3Endpoint(ip),\n visibility: \"internal\" as network.EndpointVisibility,\n port: spec.ports[0].port,\n protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,\n metadata: endpointMetadata,\n }))\n\n if (clusterIpEndpoints.length > 0) {\n clusterIpEndpoints.unshift({\n type: \"hostname\",\n visibility: \"internal\",\n hostname: `${metadata.name}.${metadata.namespace}.svc.cluster.local`,\n port: spec.ports[0].port,\n protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,\n metadata: endpointMetadata,\n })\n }\n\n const nodePortEndpoints =\n spec.type === \"NodePort\"\n ? cluster.endpoints.map(endpoint => ({\n ...(endpoint as network.L3Endpoint),\n port: spec.ports[0].nodePort,\n protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,\n metadata: endpointMetadata,\n }))\n : []\n\n const loadBalancerEndpoints =\n spec.type === \"LoadBalancer\"\n ? status.loadBalancer?.ingress?.map(endpoint => ({\n ...parseL3Endpoint(endpoint.ip ?? endpoint.hostname),\n port: spec.ports[0].port,\n protocol: spec.ports[0].protocol?.toLowerCase() as network.L4Protocol,\n metadata: endpointMetadata,\n }))\n : []\n\n return uniqueBy(\n [\n ...(clusterIpEndpoints ?? []),\n ...(loadBalancerEndpoints ?? []),\n ...(nodePortEndpoints ?? []),\n ],\n l4EndpointToString,\n )\n })\n }\n}\n\n/**\n * Creates the service spec configuration based on arguments and cluster settings.\n *\n * @param args The service arguments containing port and external configuration.\n * @param cluster The cluster where the service will be created.\n * @returns The service spec configuration.\n */\nfunction createServiceSpec(args: ServiceArgs, cluster: k8s.Cluster) {\n return output(args).apply(args => {\n return deepmerge(\n {\n ports: normalize(args.port, args.ports),\n\n externalIPs: args.external\n ? args.externalIPs\n ? args.externalIPs\n : cluster.externalIps\n : normalize(undefined, args.externalIPs),\n\n type: getServiceType(args, cluster),\n },\n omit(args, serviceExtraArgs),\n )\n })\n}\n\nclass CreatedService extends Service {\n constructor(name: string, args: ServiceArgs, opts?: ComponentResourceOptions) {\n const service = output(args.namespace).cluster.apply(cluster => {\n return new core.v1.Service(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: createServiceSpec(args, cluster),\n },\n { ...opts, parent: this, provider: getProvider(cluster) },\n )\n })\n\n super(\n \"highstate:k8s:Service\",\n name,\n args,\n opts,\n\n service.apiVersion,\n service.kind,\n output(args.namespace),\n service.metadata,\n service.spec,\n service.status,\n )\n }\n}\n\nclass ServicePatch extends Service {\n constructor(name: string, args: ServiceArgs, opts?: ComponentResourceOptions) {\n const service = output(args.namespace).cluster.apply(cluster => {\n return new core.v1.ServicePatch(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: createServiceSpec(args, cluster),\n },\n { ...opts, parent: this, provider: getProvider(cluster) },\n )\n })\n\n super(\n \"highstate:k8s:ServicePatch\",\n name,\n args,\n opts,\n\n service.apiVersion,\n service.kind,\n output(args.namespace),\n service.metadata,\n service.spec,\n service.status,\n )\n }\n}\n\nexport type WrappedServiceArgs = {\n /**\n * The underlying Kubernetes service to wrap.\n */\n service: Input<core.v1.Service>\n\n /**\n * The namespace where the service is located.\n */\n namespace: Input<Namespace>\n}\n\nclass WrappedService extends Service {\n constructor(name: string, args: WrappedServiceArgs, opts?: ComponentResourceOptions) {\n super(\n \"highstate:k8s:WrappedService\",\n name,\n args,\n opts,\n\n output(args.service).apiVersion,\n output(args.service).kind,\n output(args.namespace),\n output(args.service).metadata,\n output(args.service).spec,\n output(args.service).status,\n )\n }\n}\n\nexport type ExternalServiceArgs = {\n /**\n * The name of the service to get.\n */\n name: Input<string>\n\n /**\n * The namespace of the service to get.\n */\n namespace: Input<Namespace>\n}\n\nclass ExternalService extends Service {\n constructor(name: string, args: ExternalServiceArgs, opts?: ComponentResourceOptions) {\n const service = output(args.namespace).cluster.apply(cluster => {\n return core.v1.Service.get(\n name,\n interpolate`${output(args.namespace).metadata.name}/${args.name}`,\n { ...opts, parent: this, provider: getProvider(cluster) },\n )\n })\n\n super(\n \"highstate:k8s:ExternalService\",\n name,\n args,\n opts,\n\n service.apiVersion,\n service.kind,\n output(args.namespace),\n service.metadata,\n service.spec,\n service.status,\n )\n }\n}\n\n/**\n * Maps a container port to a service port.\n *\n * @param port The container port to map.\n * @returns The corresponding service port configuration.\n */\nexport function mapContainerPortToServicePort(\n port: types.input.core.v1.ContainerPort,\n): types.input.core.v1.ServicePort {\n return {\n name: port.name,\n port: port.containerPort,\n targetPort: port.containerPort,\n protocol: port.protocol,\n }\n}\n\n/**\n * Maps a service to a label selector.\n *\n * @param service The service to extract the label selector from.\n * @returns The label selector based on the service's selector.\n */\nexport function mapServiceToLabelSelector(\n service: core.v1.Service,\n): types.input.meta.v1.LabelSelector {\n return {\n matchLabels: service.spec.selector,\n }\n}\n\n/**\n * Determines the appropriate service type based on the service arguments and cluster configuration.\n *\n * @param service The service configuration containing type and external properties.\n * @param cluster The cluster where the service will be created.\n * @returns The service type to use.\n */\nexport function getServiceType(\n service: Pick<ServiceArgs, \"type\" | \"external\"> | undefined,\n cluster: k8s.Cluster,\n): Input<string> {\n if (service?.type) {\n return service.type\n }\n\n if (!service?.external) {\n return \"ClusterIP\"\n }\n\n return cluster.quirks?.externalServiceType === \"LoadBalancer\" ? \"LoadBalancer\" : \"NodePort\"\n}\n\n/**\n * Converts a network L4 endpoint to a Kubernetes service port.\n *\n * @param endpoint The L4 endpoint to convert.\n * @returns The corresponding Kubernetes service port configuration.\n */\nexport function l4EndpointToServicePort(\n endpoint: network.L4Endpoint,\n): types.input.core.v1.ServicePort {\n return {\n port: endpoint.port,\n protocol: endpoint.protocol.toUpperCase(),\n }\n}\n"]}
|