@highstate/k8s 0.20.0 → 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-ADHZK6V2.js → chunk-9hs97f1q.js} +13 -11
- 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 -3
- package/dist/impl/dynamic-endpoint-resolver.js +82 -81
- package/dist/impl/gateway-route.js +131 -168
- package/dist/impl/tls-certificate.js +31 -32
- package/dist/index.js +245 -201
- package/dist/units/cert-manager/index.js +19 -13
- package/dist/units/cluster-patch/index.js +9 -8
- package/dist/units/dns01-issuer/index.js +44 -41
- package/dist/units/existing-cluster/index.js +25 -13
- package/dist/units/gateway-api/index.js +15 -16
- package/dist/units/reduced-access-cluster/index.js +28 -32
- package/package.json +21 -21
- package/src/cron-job.ts +26 -1
- package/src/deployment.ts +17 -1
- package/src/job.ts +15 -1
- package/src/scripting/bundle.ts +21 -98
- package/src/scripting/environment.ts +2 -9
- package/src/shared.ts +1 -1
- package/src/stateful-set.ts +17 -1
- package/src/workload.ts +31 -14
- package/LICENSE +0 -21
- package/dist/chunk-23X5SXQG.js +0 -301
- package/dist/chunk-23X5SXQG.js.map +0 -1
- package/dist/chunk-ADHZK6V2.js.map +0 -1
- package/dist/chunk-BTAEFJ5N.js +0 -291
- package/dist/chunk-BTAEFJ5N.js.map +0 -1
- package/dist/chunk-HH2JJELM.js +0 -13
- package/dist/chunk-HH2JJELM.js.map +0 -1
- package/dist/chunk-IXE3OKB4.js +0 -249
- package/dist/chunk-IXE3OKB4.js.map +0 -1
- package/dist/chunk-OG2OPX7B.js +0 -333
- package/dist/chunk-OG2OPX7B.js.map +0 -1
- package/dist/chunk-P26SQ2ZB.js +0 -393
- package/dist/chunk-P26SQ2ZB.js.map +0 -1
- package/dist/chunk-PG27ZY2H.js +0 -319
- package/dist/chunk-PG27ZY2H.js.map +0 -1
- package/dist/chunk-PZYGZSN5.js +0 -54
- package/dist/chunk-PZYGZSN5.js.map +0 -1
- package/dist/chunk-S77TE7UC.js +0 -309
- package/dist/chunk-S77TE7UC.js.map +0 -1
- package/dist/chunk-SZKOAHNX.js +0 -1804
- package/dist/chunk-SZKOAHNX.js.map +0 -1
- package/dist/chunk-TOLFVF4S.js +0 -889
- package/dist/chunk-TOLFVF4S.js.map +0 -1
- package/dist/chunk-TVKT3ZYX.js +0 -423
- package/dist/chunk-TVKT3ZYX.js.map +0 -1
- package/dist/cron-job-RKB2HYTO.js +0 -7
- package/dist/cron-job-RKB2HYTO.js.map +0 -1
- package/dist/deployment-T35TUOL2.js +0 -7
- package/dist/deployment-T35TUOL2.js.map +0 -1
- package/dist/impl/dynamic-endpoint-resolver.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-PE4AKOHB.js +0 -7
- package/dist/job-PE4AKOHB.js.map +0 -1
- package/dist/stateful-set-LUIRHQJY.js +0 -7
- package/dist/stateful-set-LUIRHQJY.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
|
@@ -1,90 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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}`));
|
|
44
62
|
}
|
|
45
|
-
throw err;
|
|
46
63
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
nodeProcess.stdout?.once("data", (data) => {
|
|
50
|
-
const output = data.toString();
|
|
51
|
-
if (output.includes("Forwarding from")) {
|
|
52
|
-
resolve();
|
|
53
|
-
} else {
|
|
54
|
-
reject(new Error(`Failed to start port-forward: ${output}`));
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
nodeProcess.stderr?.once("data", (data) => {
|
|
58
|
-
reject(new Error(`Failed to start port-forward: ${data.toString()}`));
|
|
59
|
-
});
|
|
64
|
+
nodeProcess.stderr?.once("data", (data) => {
|
|
65
|
+
reject(new Error(`Failed to start port-forward: ${data.toString()}`));
|
|
60
66
|
});
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
_promise && await _promise;
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
dispose: async () => {
|
|
72
|
-
console.log(
|
|
73
|
-
`[port-forward] stopping port-forward for service "${name}" in namespace "${namespace}" on local port ${localPort}`
|
|
74
|
-
);
|
|
75
|
-
const nodeProcess = await subprocess.nodeChildProcess;
|
|
76
|
-
nodeProcess.kill();
|
|
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;
|
|
77
74
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
);
|
|
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
|
+
});
|
|
81
83
|
function getStablePort(id) {
|
|
82
84
|
const hash = crc32(`${getUnitStateId()}:${id}`);
|
|
83
|
-
const minPort =
|
|
84
|
-
const maxPort =
|
|
85
|
+
const minPort = 30000;
|
|
86
|
+
const maxPort = 60000;
|
|
85
87
|
return Math.abs(hash) % (maxPort - minPort) + minPort;
|
|
86
88
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
//# sourceMappingURL=dynamic-endpoint-resolver.js.map
|
|
89
|
+
export {
|
|
90
|
+
resolveDynamicEndpoint
|
|
91
|
+
};
|
|
@@ -1,44 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Gateway,
|
|
4
|
+
HttpRoute,
|
|
5
|
+
TcpRoute,
|
|
6
|
+
UdpRoute
|
|
7
|
+
} from "../chunk-46ntav0c.js";
|
|
8
|
+
import {
|
|
9
|
+
Certificate
|
|
10
|
+
} from "../chunk-556pc9e6.js";
|
|
11
|
+
import {
|
|
12
|
+
Service,
|
|
13
|
+
isEndpointFromCluster,
|
|
14
|
+
l4EndpointToServicePort
|
|
15
|
+
} from "../chunk-k4w9zpn5.js";
|
|
16
|
+
import {
|
|
17
|
+
Namespace,
|
|
18
|
+
getProvider,
|
|
19
|
+
mapMetadata
|
|
20
|
+
} from "../chunk-facs31cb.js";
|
|
21
|
+
import"../chunk-b05q6fm2.js";
|
|
10
22
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
data,
|
|
28
|
-
namespace,
|
|
29
|
-
certificateRef
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
return await createL4GatewayRoute({
|
|
23
|
+
// src/impl/gateway-route.ts
|
|
24
|
+
import { gatewayRouteMediator } from "@highstate/common";
|
|
25
|
+
import { k8s } from "@highstate/library";
|
|
26
|
+
import { toPromise } from "@highstate/pulumi";
|
|
27
|
+
import { core } from "@pulumi/kubernetes";
|
|
28
|
+
var createGatewayRoute = gatewayRouteMediator.implement(k8s.gatewayDataSchema, async ({ name, args: spec, opts }, data) => {
|
|
29
|
+
const namespace = resolveRouteNamespace(spec, data);
|
|
30
|
+
const certSecret = await getCertificateSecret(name, namespace, spec.certificate);
|
|
31
|
+
const certificateRef = certSecret ? {
|
|
32
|
+
kind: "Secret",
|
|
33
|
+
group: "",
|
|
34
|
+
name: certSecret.metadata.name
|
|
35
|
+
} : undefined;
|
|
36
|
+
const routeProtocol = resolveRouteProtocol(spec);
|
|
37
|
+
if (routeProtocol === "http") {
|
|
38
|
+
return await createHttpGatewayRoute({
|
|
33
39
|
name,
|
|
34
40
|
spec,
|
|
35
41
|
opts,
|
|
36
42
|
data,
|
|
37
43
|
namespace,
|
|
38
|
-
|
|
44
|
+
certificateRef
|
|
39
45
|
});
|
|
40
46
|
}
|
|
41
|
-
|
|
47
|
+
return await createL4GatewayRoute({
|
|
48
|
+
name,
|
|
49
|
+
spec,
|
|
50
|
+
opts,
|
|
51
|
+
data,
|
|
52
|
+
namespace,
|
|
53
|
+
protocol: routeProtocol === "tcp" ? "TCP" : "UDP"
|
|
54
|
+
});
|
|
55
|
+
});
|
|
42
56
|
function resolveRouteNamespace(spec, data) {
|
|
43
57
|
const metadataNamespace = spec.metadata["k8s.namespace"];
|
|
44
58
|
if (metadataNamespace instanceof Namespace) {
|
|
@@ -65,61 +79,49 @@ async function createHttpGatewayRoute({
|
|
|
65
79
|
hostname: listenerHostname,
|
|
66
80
|
tls: {
|
|
67
81
|
mode: "Terminate",
|
|
68
|
-
certificateRefs: certificateRef ? [certificateRef] :
|
|
82
|
+
certificateRefs: certificateRef ? [certificateRef] : undefined
|
|
69
83
|
}
|
|
70
84
|
}
|
|
71
85
|
];
|
|
72
|
-
const gateway = Gateway.create(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
listeners
|
|
78
|
-
},
|
|
79
|
-
opts
|
|
80
|
-
);
|
|
86
|
+
const gateway = Gateway.create(name, {
|
|
87
|
+
namespace,
|
|
88
|
+
gatewayClassName: data.className,
|
|
89
|
+
listeners
|
|
90
|
+
}, opts);
|
|
81
91
|
const ruleSpecs = Object.values(spec.rules);
|
|
82
|
-
const rules = await Promise.all(
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
routeName: name
|
|
100
|
-
});
|
|
101
|
-
return {
|
|
102
|
-
name: backendData.serviceName,
|
|
103
|
-
namespace: backendData.serviceNamespace,
|
|
104
|
-
port: backendPort.port
|
|
105
|
-
};
|
|
106
|
-
})
|
|
107
|
-
);
|
|
92
|
+
const rules = await Promise.all(ruleSpecs.map(async (ruleSpec, ruleIndex) => {
|
|
93
|
+
const backendRefs = await Promise.all(ruleSpec.backends.map(async (backend, backendIndex) => {
|
|
94
|
+
const backendData = await resolveBackendFromEndpoints({
|
|
95
|
+
routeName: name,
|
|
96
|
+
backendName: `${ruleIndex}-${backendIndex}`,
|
|
97
|
+
endpoints: backend.endpoints,
|
|
98
|
+
namespace,
|
|
99
|
+
cluster: data.cluster,
|
|
100
|
+
opts
|
|
101
|
+
});
|
|
102
|
+
const backendPort = await selectBackendPort({
|
|
103
|
+
ports: backendData.ports,
|
|
104
|
+
protocol: "TCP",
|
|
105
|
+
targetPort: backendData.preferredTargetPort,
|
|
106
|
+
serviceName: backendData.serviceName,
|
|
107
|
+
routeName: name
|
|
108
|
+
});
|
|
108
109
|
return {
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
name: backendData.serviceName,
|
|
111
|
+
namespace: backendData.serviceNamespace,
|
|
112
|
+
port: backendPort.port
|
|
111
113
|
};
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
114
|
+
}));
|
|
115
|
+
return {
|
|
116
|
+
matches: ruleSpec.paths,
|
|
117
|
+
backends: backendRefs
|
|
118
|
+
};
|
|
119
|
+
}));
|
|
120
|
+
const httpRoute = new HttpRoute(name, {
|
|
121
|
+
gateway,
|
|
122
|
+
hostnames: spec.fqdns,
|
|
123
|
+
rules
|
|
124
|
+
}, opts);
|
|
123
125
|
return {
|
|
124
126
|
resource: httpRoute,
|
|
125
127
|
endpoints: await toPromise(gateway.endpoints)
|
|
@@ -162,45 +164,33 @@ async function createL4GatewayRoute({
|
|
|
162
164
|
const listenerName = `${protocol.toLowerCase()}-${listenerPort}`;
|
|
163
165
|
const gatewayName = name;
|
|
164
166
|
const gatewayResourceName = name;
|
|
165
|
-
const gateway = Gateway.create(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
]
|
|
178
|
-
},
|
|
179
|
-
opts
|
|
180
|
-
);
|
|
167
|
+
const gateway = Gateway.create(gatewayResourceName, {
|
|
168
|
+
name: gatewayName,
|
|
169
|
+
namespace,
|
|
170
|
+
gatewayClassName: data.className,
|
|
171
|
+
listeners: [
|
|
172
|
+
{
|
|
173
|
+
name: listenerName,
|
|
174
|
+
port: listenerPort,
|
|
175
|
+
protocol
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
}, opts);
|
|
181
179
|
const backendRef = {
|
|
182
180
|
name: backendData.serviceName,
|
|
183
181
|
namespace: backendData.serviceNamespace,
|
|
184
182
|
port: backendPort.port
|
|
185
183
|
};
|
|
186
184
|
const routeOpts = { ...opts, parent: gateway };
|
|
187
|
-
const route = protocol === "TCP" ? new TcpRoute(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
)
|
|
196
|
-
name,
|
|
197
|
-
{
|
|
198
|
-
gateway,
|
|
199
|
-
listenerName,
|
|
200
|
-
backend: backendRef
|
|
201
|
-
},
|
|
202
|
-
routeOpts
|
|
203
|
-
);
|
|
185
|
+
const route = protocol === "TCP" ? new TcpRoute(name, {
|
|
186
|
+
gateway,
|
|
187
|
+
listenerName,
|
|
188
|
+
backend: backendRef
|
|
189
|
+
}, routeOpts) : new UdpRoute(name, {
|
|
190
|
+
gateway,
|
|
191
|
+
listenerName,
|
|
192
|
+
backend: backendRef
|
|
193
|
+
}, routeOpts);
|
|
204
194
|
return {
|
|
205
195
|
resource: route,
|
|
206
196
|
endpoints: await toPromise(gateway.endpoints)
|
|
@@ -209,7 +199,7 @@ async function createL4GatewayRoute({
|
|
|
209
199
|
async function getCertificateSecret(_name, namespace, tlsCertificate) {
|
|
210
200
|
const resolvedCertificate = await toPromise(tlsCertificate);
|
|
211
201
|
if (!resolvedCertificate) {
|
|
212
|
-
return
|
|
202
|
+
return;
|
|
213
203
|
}
|
|
214
204
|
const resource = await toPromise(resolvedCertificate.resource);
|
|
215
205
|
if (resource instanceof Certificate) {
|
|
@@ -221,9 +211,7 @@ async function getCertificateSecret(_name, namespace, tlsCertificate) {
|
|
|
221
211
|
return await toPromise(resource.secret);
|
|
222
212
|
}
|
|
223
213
|
}
|
|
224
|
-
throw new Error(
|
|
225
|
-
"Not implemented: copying certificate secret across namespaces/clusters/different systems"
|
|
226
|
-
);
|
|
214
|
+
throw new Error("Not implemented: copying certificate secret across namespaces/clusters/different systems");
|
|
227
215
|
}
|
|
228
216
|
function resolveRouteProtocol(spec) {
|
|
229
217
|
const rules = Object.values(spec.rules);
|
|
@@ -247,7 +235,7 @@ async function resolveBackendFromEndpoints({
|
|
|
247
235
|
const serviceMeta = getServiceMetadataFromEndpoints(endpoints, cluster);
|
|
248
236
|
if (serviceMeta) {
|
|
249
237
|
const metadataPorts = endpoints.map((endpoint) => ({
|
|
250
|
-
name: typeof serviceMeta.targetPort === "string" ? serviceMeta.targetPort :
|
|
238
|
+
name: typeof serviceMeta.targetPort === "string" ? serviceMeta.targetPort : undefined,
|
|
251
239
|
port: endpoint.port,
|
|
252
240
|
protocol: endpoint.protocol.toUpperCase(),
|
|
253
241
|
targetPort: serviceMeta.targetPort
|
|
@@ -259,19 +247,11 @@ async function resolveBackendFromEndpoints({
|
|
|
259
247
|
preferredTargetPort: serviceMeta.targetPort
|
|
260
248
|
};
|
|
261
249
|
}
|
|
262
|
-
const syntheticService = await createServiceFromEndpoints(
|
|
263
|
-
`${routeName}-${backendName}`,
|
|
264
|
-
namespace,
|
|
265
|
-
endpoints,
|
|
266
|
-
cluster,
|
|
267
|
-
opts
|
|
268
|
-
);
|
|
250
|
+
const syntheticService = await createServiceFromEndpoints(`${routeName}-${backendName}`, namespace, endpoints, cluster, opts);
|
|
269
251
|
const syntheticServiceName = await toPromise(syntheticService.service.metadata.name);
|
|
270
252
|
const syntheticServiceNamespace = await toPromise(syntheticService.service.metadata.namespace);
|
|
271
253
|
if (!syntheticServiceNamespace) {
|
|
272
|
-
throw new Error(
|
|
273
|
-
`Synthetic backend service "${syntheticServiceName}" for gateway route "${routeName}" has no namespace.`
|
|
274
|
-
);
|
|
254
|
+
throw new Error(`Synthetic backend service "${syntheticServiceName}" for gateway route "${routeName}" has no namespace.`);
|
|
275
255
|
}
|
|
276
256
|
return {
|
|
277
257
|
serviceName: syntheticServiceName,
|
|
@@ -282,13 +262,11 @@ async function resolveBackendFromEndpoints({
|
|
|
282
262
|
function getServiceMetadataFromEndpoints(endpoints, cluster) {
|
|
283
263
|
const serviceEndpoints = endpoints.filter((endpoint) => isEndpointFromCluster(endpoint, cluster));
|
|
284
264
|
if (serviceEndpoints.length === 0 || serviceEndpoints.length !== endpoints.length) {
|
|
285
|
-
return
|
|
265
|
+
return;
|
|
286
266
|
}
|
|
287
267
|
const first = serviceEndpoints[0].metadata["k8s.service"];
|
|
288
|
-
if (serviceEndpoints.some(
|
|
289
|
-
|
|
290
|
-
)) {
|
|
291
|
-
return void 0;
|
|
268
|
+
if (serviceEndpoints.some((endpoint) => endpoint.metadata["k8s.service"].name !== first.name || endpoint.metadata["k8s.service"].namespace !== first.namespace)) {
|
|
269
|
+
return;
|
|
292
270
|
}
|
|
293
271
|
return {
|
|
294
272
|
name: first.name,
|
|
@@ -332,17 +310,13 @@ async function createServiceFromEndpoints(name, namespace, endpointsInput, clust
|
|
|
332
310
|
ports: ipEndpoints.map(l4EndpointToServicePort)
|
|
333
311
|
});
|
|
334
312
|
const endpointsName = `hs-backend-${name}`;
|
|
335
|
-
new core.v1.Endpoints(
|
|
336
|
-
endpointsName,
|
|
337
|
-
{
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}))
|
|
343
|
-
},
|
|
344
|
-
{ ...opts, provider: getProvider(cluster), parent: service }
|
|
345
|
-
);
|
|
313
|
+
new core.v1.Endpoints(endpointsName, {
|
|
314
|
+
metadata: mapMetadata({ namespace }, endpointsName),
|
|
315
|
+
subsets: ipEndpoints.map((endpoint) => ({
|
|
316
|
+
addresses: [{ ip: endpoint.address.value }],
|
|
317
|
+
ports: [l4EndpointToServicePort(endpoint)]
|
|
318
|
+
}))
|
|
319
|
+
}, { ...opts, provider: getProvider(cluster), parent: service });
|
|
346
320
|
return {
|
|
347
321
|
service,
|
|
348
322
|
ports: ipPortInfos
|
|
@@ -350,7 +324,7 @@ async function createServiceFromEndpoints(name, namespace, endpointsInput, clust
|
|
|
350
324
|
}
|
|
351
325
|
function toServicePortInfoFromEndpoint(endpoint) {
|
|
352
326
|
return {
|
|
353
|
-
name:
|
|
327
|
+
name: undefined,
|
|
354
328
|
port: endpoint.port,
|
|
355
329
|
protocol: endpoint.protocol.toUpperCase(),
|
|
356
330
|
targetPort: endpoint.port
|
|
@@ -365,15 +339,13 @@ async function selectBackendPort({
|
|
|
365
339
|
}) {
|
|
366
340
|
const candidates = ports.filter((port) => port.protocol === protocol);
|
|
367
341
|
if (candidates.length === 0) {
|
|
368
|
-
throw new Error(
|
|
369
|
-
`Service "${serviceName}" does not expose any ${protocol} ports required by gateway route "${routeName}".`
|
|
370
|
-
);
|
|
342
|
+
throw new Error(`Service "${serviceName}" does not expose any ${protocol} ports required by gateway route "${routeName}".`);
|
|
371
343
|
}
|
|
372
344
|
if (!targetPort) {
|
|
373
345
|
return candidates[0];
|
|
374
346
|
}
|
|
375
347
|
const resolvedTarget = await toPromise(targetPort);
|
|
376
|
-
if (resolvedTarget ===
|
|
348
|
+
if (resolvedTarget === undefined || resolvedTarget === null) {
|
|
377
349
|
return candidates[0];
|
|
378
350
|
}
|
|
379
351
|
if (typeof resolvedTarget === "number") {
|
|
@@ -389,9 +361,7 @@ async function selectBackendPort({
|
|
|
389
361
|
if (match2) {
|
|
390
362
|
return match2;
|
|
391
363
|
}
|
|
392
|
-
throw new Error(
|
|
393
|
-
`Gateway route "${routeName}" requested target port ${resolvedTarget}, but service "${serviceName}" does not expose it for ${protocol} backends.`
|
|
394
|
-
);
|
|
364
|
+
throw new Error(`Gateway route "${routeName}" requested target port ${resolvedTarget}, but service "${serviceName}" does not expose it for ${protocol} backends.`);
|
|
395
365
|
}
|
|
396
366
|
const targetString = String(resolvedTarget);
|
|
397
367
|
const match = candidates.find((candidate) => {
|
|
@@ -406,9 +376,7 @@ async function selectBackendPort({
|
|
|
406
376
|
if (match) {
|
|
407
377
|
return match;
|
|
408
378
|
}
|
|
409
|
-
throw new Error(
|
|
410
|
-
`Gateway route "${routeName}" requested target port "${targetString}", but service "${serviceName}" does not expose it for ${protocol} backends.`
|
|
411
|
-
);
|
|
379
|
+
throw new Error(`Gateway route "${routeName}" requested target port "${targetString}", but service "${serviceName}" does not expose it for ${protocol} backends.`);
|
|
412
380
|
}
|
|
413
381
|
async function resolveListenerPort({
|
|
414
382
|
requestedPort,
|
|
@@ -420,23 +388,18 @@ async function resolveListenerPort({
|
|
|
420
388
|
return backendPort.port;
|
|
421
389
|
}
|
|
422
390
|
const resolved = await toPromise(requestedPort);
|
|
423
|
-
if (resolved ===
|
|
391
|
+
if (resolved === undefined || resolved === null) {
|
|
424
392
|
return backendPort.port;
|
|
425
393
|
}
|
|
426
394
|
if (!Number.isInteger(resolved)) {
|
|
427
|
-
throw new Error(
|
|
428
|
-
`Gateway route "${routeName}" must use integer listener ports for ${protocol.toLowerCase()} traffic.`
|
|
429
|
-
);
|
|
395
|
+
throw new Error(`Gateway route "${routeName}" must use integer listener ports for ${protocol.toLowerCase()} traffic.`);
|
|
430
396
|
}
|
|
431
397
|
const port = Number(resolved);
|
|
432
398
|
if (port < 1 || port > 65535) {
|
|
433
|
-
throw new Error(
|
|
434
|
-
`Gateway route "${routeName}" specified listener port ${port}, which is outside the valid range 1-65535.`
|
|
435
|
-
);
|
|
399
|
+
throw new Error(`Gateway route "${routeName}" specified listener port ${port}, which is outside the valid range 1-65535.`);
|
|
436
400
|
}
|
|
437
401
|
return port;
|
|
438
402
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
//# sourceMappingURL=gateway-route.js.map
|
|
403
|
+
export {
|
|
404
|
+
createGatewayRoute
|
|
405
|
+
};
|
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Certificate
|
|
4
|
+
} from "../chunk-556pc9e6.js";
|
|
5
|
+
import {
|
|
6
|
+
Namespace,
|
|
7
|
+
getProvider
|
|
8
|
+
} from "../chunk-facs31cb.js";
|
|
9
|
+
import"../chunk-b05q6fm2.js";
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
export { createCertificate };
|
|
32
|
-
//# sourceMappingURL=tls-certificate.js.map
|
|
33
|
-
//# sourceMappingURL=tls-certificate.js.map
|
|
11
|
+
// src/impl/tls-certificate.ts
|
|
12
|
+
import { tlsCertificateMediator } from "@highstate/common";
|
|
13
|
+
import { k8s } from "@highstate/library";
|
|
14
|
+
var createCertificate = tlsCertificateMediator.implement(k8s.tlsIssuerDataSchema, ({ name, spec, opts }, data) => {
|
|
15
|
+
const provider = getProvider(data.cluster);
|
|
16
|
+
const metadata = spec.metadata;
|
|
17
|
+
const metadataNamespace = metadata?.["k8s.namespace"];
|
|
18
|
+
const namespace = metadataNamespace instanceof Namespace ? metadataNamespace : metadataNamespace ? Namespace.for(metadataNamespace, data.cluster) : Namespace.get("cert-manager", { name: "cert-manager", cluster: data.cluster });
|
|
19
|
+
return Certificate.create(name, {
|
|
20
|
+
namespace,
|
|
21
|
+
commonName: spec.commonName,
|
|
22
|
+
dnsNames: spec.dnsNames,
|
|
23
|
+
issuerRef: {
|
|
24
|
+
name: data.clusterIssuerName,
|
|
25
|
+
kind: "ClusterIssuer"
|
|
26
|
+
},
|
|
27
|
+
secretName: `hs-certificate-${name}`
|
|
28
|
+
}, { ...opts, provider });
|
|
29
|
+
});
|
|
30
|
+
export {
|
|
31
|
+
createCertificate
|
|
32
|
+
};
|