@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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
var __using = (stack, value, async) => {
|
|
4
|
+
if (value != null) {
|
|
5
|
+
if (typeof value !== "object" && typeof value !== "function")
|
|
6
|
+
throw TypeError('Object expected to be assigned to "using" declaration');
|
|
7
|
+
let dispose;
|
|
8
|
+
if (async)
|
|
9
|
+
dispose = value[Symbol.asyncDispose];
|
|
10
|
+
if (dispose === undefined)
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (typeof dispose !== "function")
|
|
13
|
+
throw TypeError("Object not disposable");
|
|
14
|
+
stack.push([async, dispose, value]);
|
|
15
|
+
} else if (async) {
|
|
16
|
+
stack.push([async]);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
20
|
+
var __callDispose = (stack, error, hasError) => {
|
|
21
|
+
let fail = (e) => error = hasError ? new SuppressedError(e, error, "An error was suppressed during disposal") : (hasError = true, e), next = (it) => {
|
|
22
|
+
while (it = stack.pop()) {
|
|
23
|
+
try {
|
|
24
|
+
var result = it[1] && it[1].call(it[2]);
|
|
25
|
+
if (it[0])
|
|
26
|
+
return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
27
|
+
} catch (e) {
|
|
28
|
+
fail(e);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (hasError)
|
|
32
|
+
throw error;
|
|
33
|
+
};
|
|
34
|
+
return next();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { __require, __using, __callDispose };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/dns01-solver.ts
|
|
3
|
+
import { ImplementationMediator } from "@highstate/common";
|
|
4
|
+
import { z } from "@highstate/contract";
|
|
5
|
+
var dns01SolverMediator = new ImplementationMediator("dns01-solver", z.object({ namespace: z.custom() }), z.custom());
|
|
6
|
+
|
|
7
|
+
export { dns01SolverMediator };
|
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// assets/images.json
|
|
3
|
+
var images_default = {
|
|
4
|
+
"terminal-kubectl": {
|
|
5
|
+
name: "ghcr.io/highstate-io/highstate/terminal.kubectl",
|
|
6
|
+
tag: "latest",
|
|
7
|
+
image: "ghcr.io/highstate-io/highstate/terminal.kubectl:latest@sha256:cc0a15d9960422d77f4a8e2c8bff1161d171565e0fe81b5827f02a9bdac7bcd8"
|
|
8
|
+
},
|
|
9
|
+
"worker.k8s-monitor": {
|
|
10
|
+
name: "ghcr.io/highstate-io/highstate/worker.k8s-monitor",
|
|
11
|
+
tag: "latest",
|
|
12
|
+
image: "ghcr.io/highstate-io/highstate/worker.k8s-monitor:latest@sha256:5acae35c3163a75b83ee574e7274eb7692dfd3c7f615deceede9b44bc1e475f9"
|
|
13
|
+
},
|
|
14
|
+
alpine: {
|
|
15
|
+
name: "alpine",
|
|
16
|
+
tag: "latest",
|
|
17
|
+
image: "alpine:latest@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11"
|
|
18
|
+
},
|
|
19
|
+
ubuntu: {
|
|
20
|
+
name: "ubuntu",
|
|
21
|
+
tag: "latest",
|
|
22
|
+
image: "ubuntu:latest@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b"
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// src/secret.ts
|
|
27
|
+
import { getOrCreate as getOrCreate2 } from "@highstate/contract";
|
|
28
|
+
import { k8s as k8s2 } from "@highstate/library";
|
|
29
|
+
import {
|
|
30
|
+
interpolate as interpolate2,
|
|
31
|
+
makeEntityOutput as makeEntityOutput2,
|
|
32
|
+
output as output4,
|
|
33
|
+
toPromise as toPromise4
|
|
34
|
+
} from "@highstate/pulumi";
|
|
35
|
+
import { core as core4 } from "@pulumi/kubernetes";
|
|
36
|
+
|
|
37
|
+
// src/namespace.ts
|
|
38
|
+
import { getOrCreate } from "@highstate/contract";
|
|
39
|
+
import { k8s } from "@highstate/library";
|
|
40
|
+
import { makeEntityOutput, toPromise as toPromise3 } from "@highstate/pulumi";
|
|
41
|
+
import { core as core3 } from "@pulumi/kubernetes";
|
|
42
|
+
import {
|
|
43
|
+
output as output3
|
|
44
|
+
} from "@pulumi/pulumi";
|
|
45
|
+
|
|
46
|
+
// src/rbac.ts
|
|
47
|
+
import { common } from "@highstate/library";
|
|
48
|
+
import {
|
|
49
|
+
ComponentResource as ComponentResource2,
|
|
50
|
+
interpolate,
|
|
51
|
+
makeEntity,
|
|
52
|
+
normalizeInputs,
|
|
53
|
+
output as output2,
|
|
54
|
+
toPromise as toPromise2
|
|
55
|
+
} from "@highstate/pulumi";
|
|
56
|
+
import { KubeConfig } from "@kubernetes/client-node";
|
|
57
|
+
import { core as core2, rbac } from "@pulumi/kubernetes";
|
|
58
|
+
import { map, unique } from "remeda";
|
|
59
|
+
|
|
60
|
+
// src/shared.ts
|
|
61
|
+
import {
|
|
62
|
+
ComponentResource,
|
|
63
|
+
output,
|
|
64
|
+
secret,
|
|
65
|
+
toPromise
|
|
66
|
+
} from "@highstate/pulumi";
|
|
67
|
+
import { core, Provider } from "@pulumi/kubernetes";
|
|
68
|
+
var providers = new Map;
|
|
69
|
+
function getProvider(cluster) {
|
|
70
|
+
const name = `${cluster.name}.${cluster.connectionId}`;
|
|
71
|
+
const existing = providers.get(name);
|
|
72
|
+
if (existing) {
|
|
73
|
+
return existing;
|
|
74
|
+
}
|
|
75
|
+
if (cluster.kubeconfig.content.type !== "embedded-secret") {
|
|
76
|
+
throw new Error("Only embedded secrets are supported for cluster kubeconfig for now");
|
|
77
|
+
}
|
|
78
|
+
const provider = new Provider(name, {
|
|
79
|
+
kubeconfig: secret(cluster.kubeconfig.content.value.value)
|
|
80
|
+
});
|
|
81
|
+
providers.set(name, provider);
|
|
82
|
+
return provider;
|
|
83
|
+
}
|
|
84
|
+
async function getProviderAsync(cluster) {
|
|
85
|
+
const resolvedCluster = await toPromise(cluster);
|
|
86
|
+
return getProvider(resolvedCluster);
|
|
87
|
+
}
|
|
88
|
+
function getEmbeddedSecretFileContent(file) {
|
|
89
|
+
return output(file).apply((file2) => {
|
|
90
|
+
if (file2.content.type !== "embedded-secret") {
|
|
91
|
+
throw new Error("Only embedded-secret file contents are supported for kubeconfig for now");
|
|
92
|
+
}
|
|
93
|
+
return file2.content.value.value;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function getClusterKubeconfigContent(cluster) {
|
|
97
|
+
return output(cluster).apply((cluster2) => {
|
|
98
|
+
if (cluster2.kubeconfig.content.type !== "embedded-secret") {
|
|
99
|
+
throw new Error("Only embedded-secret file contents are supported for cluster kubeconfig for now");
|
|
100
|
+
}
|
|
101
|
+
return cluster2.kubeconfig.content.value.value;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
var commonExtraArgs = ["name", "namespace", "metadata"];
|
|
105
|
+
function mapMetadata(args, fallbackName) {
|
|
106
|
+
return output(args.metadata).apply((metadata) => output({
|
|
107
|
+
...metadata,
|
|
108
|
+
name: args.name ?? metadata?.name ?? fallbackName,
|
|
109
|
+
namespace: metadata?.namespace ?? (args.namespace ? output(args.namespace).metadata.name : undefined)
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
function mapSelectorLikeToSelector(selector) {
|
|
113
|
+
if ("matchLabels" in selector || "matchExpressions" in selector) {
|
|
114
|
+
return selector;
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
matchLabels: selector
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function getNamespaceName(namespace) {
|
|
121
|
+
if (Namespace.isInstance(namespace)) {
|
|
122
|
+
return namespace.metadata.name;
|
|
123
|
+
}
|
|
124
|
+
if (core.v1.Namespace.isInstance(namespace)) {
|
|
125
|
+
return namespace.metadata.name;
|
|
126
|
+
}
|
|
127
|
+
return output(namespace);
|
|
128
|
+
}
|
|
129
|
+
function mapNamespaceNameToSelector(namespace) {
|
|
130
|
+
return {
|
|
131
|
+
matchLabels: {
|
|
132
|
+
"kubernetes.io/metadata.name": namespace
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function validateCluster(entity, cluster) {
|
|
137
|
+
return output({ entity, cluster }).apply(({ entity: entity2, cluster: cluster2 }) => {
|
|
138
|
+
if (entity2.clusterId !== cluster2.id) {
|
|
139
|
+
throw new Error(`Cluster mismatch for ${entity2.kind} "${entity2.metadata.name}": "${entity2.clusterId}" != "${cluster2.id}"`);
|
|
140
|
+
}
|
|
141
|
+
return cluster2;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
class Resource extends ComponentResource {
|
|
145
|
+
cluster;
|
|
146
|
+
metadata;
|
|
147
|
+
static apiVersion;
|
|
148
|
+
static kind;
|
|
149
|
+
static isNamespaced = false;
|
|
150
|
+
constructor(type, name, args, opts, cluster, metadata) {
|
|
151
|
+
super(type, name, args, opts);
|
|
152
|
+
this.cluster = cluster;
|
|
153
|
+
this.metadata = metadata;
|
|
154
|
+
}
|
|
155
|
+
get apiVersion() {
|
|
156
|
+
return this.constructor.apiVersion;
|
|
157
|
+
}
|
|
158
|
+
get kind() {
|
|
159
|
+
return this.constructor.kind;
|
|
160
|
+
}
|
|
161
|
+
get isNamespaced() {
|
|
162
|
+
return this.constructor.isNamespaced;
|
|
163
|
+
}
|
|
164
|
+
get entityBase() {
|
|
165
|
+
return {
|
|
166
|
+
clusterId: this.cluster.id,
|
|
167
|
+
clusterName: this.cluster.name,
|
|
168
|
+
apiVersion: this.apiVersion,
|
|
169
|
+
kind: this.kind,
|
|
170
|
+
isNamespaced: false,
|
|
171
|
+
metadata: this.metadata
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
class NamespacedResource extends Resource {
|
|
177
|
+
namespace;
|
|
178
|
+
static isNamespaced = true;
|
|
179
|
+
constructor(type, name, args, opts, metadata, namespace) {
|
|
180
|
+
super(type, name, args, opts, namespace.cluster, metadata);
|
|
181
|
+
this.namespace = namespace;
|
|
182
|
+
}
|
|
183
|
+
get entityBase() {
|
|
184
|
+
return {
|
|
185
|
+
clusterId: this.cluster.id,
|
|
186
|
+
clusterName: this.cluster.name,
|
|
187
|
+
apiVersion: this.apiVersion,
|
|
188
|
+
kind: this.kind,
|
|
189
|
+
isNamespaced: true,
|
|
190
|
+
metadata: this.metadata
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/rbac.ts
|
|
196
|
+
class ClusterAccessScope extends ComponentResource2 {
|
|
197
|
+
cluster;
|
|
198
|
+
constructor(name, args, opts) {
|
|
199
|
+
super("highstate:k8s:ClusterAccessScope", name, args, opts);
|
|
200
|
+
const { serviceAccount, kubeconfig } = output2(args.namespace).cluster.apply((cluster) => {
|
|
201
|
+
const provider = getProvider(cluster);
|
|
202
|
+
const namespaceName = output2(args.namespace).metadata.name;
|
|
203
|
+
const serviceAccount2 = new core2.v1.ServiceAccount(name, {
|
|
204
|
+
metadata: {
|
|
205
|
+
name,
|
|
206
|
+
namespace: namespaceName
|
|
207
|
+
}
|
|
208
|
+
}, { provider });
|
|
209
|
+
const clusterRole = new rbac.v1.ClusterRole(name, {
|
|
210
|
+
metadata: {
|
|
211
|
+
name: interpolate`hs.${namespaceName}.${name}`,
|
|
212
|
+
annotations: {
|
|
213
|
+
"kubernetes.io/description": interpolate`Created by Highstate for the ServiceAccount "${name}" in the namespace "${namespaceName}".`
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
rules: output2({
|
|
217
|
+
rules: normalizeInputs(args.rule, args.rules),
|
|
218
|
+
resources: args.resources ?? []
|
|
219
|
+
}).apply(({ rules, resources }) => mergeResources(rules, resources))
|
|
220
|
+
}, { provider });
|
|
221
|
+
const createRoleBinding = (namespace) => {
|
|
222
|
+
return new rbac.v1.RoleBinding(name, {
|
|
223
|
+
metadata: { name, namespace },
|
|
224
|
+
roleRef: {
|
|
225
|
+
kind: "ClusterRole",
|
|
226
|
+
name: clusterRole.metadata.name,
|
|
227
|
+
apiGroup: "rbac.authorization.k8s.io"
|
|
228
|
+
},
|
|
229
|
+
subjects: [
|
|
230
|
+
{
|
|
231
|
+
kind: "ServiceAccount",
|
|
232
|
+
name: serviceAccount2.metadata.name,
|
|
233
|
+
namespace: namespaceName
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}, { provider });
|
|
237
|
+
};
|
|
238
|
+
if (args.clusterWide) {
|
|
239
|
+
new rbac.v1.ClusterRoleBinding(name, {
|
|
240
|
+
metadata: { name },
|
|
241
|
+
roleRef: {
|
|
242
|
+
kind: "ClusterRole",
|
|
243
|
+
name: clusterRole.metadata.name,
|
|
244
|
+
apiGroup: "rbac.authorization.k8s.io"
|
|
245
|
+
},
|
|
246
|
+
subjects: [
|
|
247
|
+
{
|
|
248
|
+
kind: "ServiceAccount",
|
|
249
|
+
name: serviceAccount2.metadata.name,
|
|
250
|
+
namespace: namespaceName
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
}, { provider });
|
|
254
|
+
} else {
|
|
255
|
+
if (args.allowOriginNamespace !== false) {
|
|
256
|
+
createRoleBinding(namespaceName);
|
|
257
|
+
}
|
|
258
|
+
output2(args.extraNamespaces ?? []).apply(map(getNamespaceName)).apply(map(createRoleBinding));
|
|
259
|
+
}
|
|
260
|
+
return { serviceAccount: serviceAccount2, kubeconfig: cluster.kubeconfig };
|
|
261
|
+
});
|
|
262
|
+
const accessTokenSecret = Secret.create(`${name}-token`, {
|
|
263
|
+
namespace: args.namespace,
|
|
264
|
+
type: "kubernetes.io/service-account-token",
|
|
265
|
+
metadata: {
|
|
266
|
+
annotations: {
|
|
267
|
+
"kubernetes.io/service-account.name": serviceAccount.metadata.name
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
this.cluster = output2({
|
|
272
|
+
cluster: output2(args.namespace).cluster,
|
|
273
|
+
kubeconfig,
|
|
274
|
+
newToken: accessTokenSecret.getValue("token"),
|
|
275
|
+
serviceAccount: serviceAccount.metadata.name,
|
|
276
|
+
serviceAccountId: serviceAccount.metadata.uid
|
|
277
|
+
}).apply(({ cluster, kubeconfig: kubeconfig2, newToken, serviceAccount: serviceAccount2, serviceAccountId }) => {
|
|
278
|
+
if (kubeconfig2.content.type !== "embedded-secret") {
|
|
279
|
+
throw new Error("Only embedded secrets are supported for cluster kubeconfig for now");
|
|
280
|
+
}
|
|
281
|
+
const config = new KubeConfig;
|
|
282
|
+
config.loadFromString(kubeconfig2.content.value.value);
|
|
283
|
+
config.users = [];
|
|
284
|
+
config.contexts = [];
|
|
285
|
+
config.addUser({ name: serviceAccount2, token: newToken });
|
|
286
|
+
config.addContext({
|
|
287
|
+
name: config.clusters[0].name,
|
|
288
|
+
cluster: config.clusters[0].name,
|
|
289
|
+
user: serviceAccount2
|
|
290
|
+
});
|
|
291
|
+
config.setCurrentContext(config.clusters[0].name);
|
|
292
|
+
return {
|
|
293
|
+
...cluster,
|
|
294
|
+
connectionId: serviceAccountId,
|
|
295
|
+
kubeconfig: makeEntity({
|
|
296
|
+
entity: common.fileEntity,
|
|
297
|
+
identity: `${serviceAccountId}:kubeconfig`,
|
|
298
|
+
meta: {
|
|
299
|
+
title: `kubeconfig for SA ${serviceAccount2}`
|
|
300
|
+
},
|
|
301
|
+
value: {
|
|
302
|
+
content: {
|
|
303
|
+
type: "embedded-secret",
|
|
304
|
+
value: config.exportConfig()
|
|
305
|
+
},
|
|
306
|
+
meta: {
|
|
307
|
+
name: "kubeconfig",
|
|
308
|
+
contentType: "text/yaml",
|
|
309
|
+
mode: 384
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
async function mergeResources(rules, resources) {
|
|
318
|
+
for (const resource of resources) {
|
|
319
|
+
const entity = await toPromise2(resource instanceof NamespacedResource ? resource.entity : resource);
|
|
320
|
+
const apiGroup = entity.apiVersion.includes("/") ? entity.apiVersion.split("/")[0] : "";
|
|
321
|
+
const resourceCollection = `${entity.kind.toLowerCase()}s`;
|
|
322
|
+
const matchingRule = rules.find((rule) => {
|
|
323
|
+
const apiGroupsMatch = rule.apiGroups?.length === 1 && rule.apiGroups[0] === apiGroup;
|
|
324
|
+
const resourcesMatch = rule.resources?.length === 1 && rule.resources[0] === resourceCollection;
|
|
325
|
+
return apiGroupsMatch && resourcesMatch;
|
|
326
|
+
});
|
|
327
|
+
if (!matchingRule) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
matchingRule.resourceNames = await toPromise2(unique([
|
|
331
|
+
...matchingRule.resourceNames ?? [],
|
|
332
|
+
entity.metadata.name
|
|
333
|
+
]));
|
|
334
|
+
}
|
|
335
|
+
return rules;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/namespace.ts
|
|
339
|
+
class Namespace extends Resource {
|
|
340
|
+
spec;
|
|
341
|
+
status;
|
|
342
|
+
static apiVersion = "v1";
|
|
343
|
+
static kind = "Namespace";
|
|
344
|
+
portForwardCluster;
|
|
345
|
+
constructor(type, name, args, opts, cluster, metadata, spec, status) {
|
|
346
|
+
super(type, name, args, opts, cluster, metadata);
|
|
347
|
+
this.spec = spec;
|
|
348
|
+
this.status = status;
|
|
349
|
+
}
|
|
350
|
+
get entity() {
|
|
351
|
+
return makeEntityOutput({
|
|
352
|
+
entity: k8s.namespaceEntity,
|
|
353
|
+
identity: this.metadata.uid,
|
|
354
|
+
meta: {
|
|
355
|
+
title: this.metadata.name
|
|
356
|
+
},
|
|
357
|
+
value: {
|
|
358
|
+
...this.entityBase
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
static create(name, args, opts) {
|
|
363
|
+
return new CreatedNamespace(name, args, opts);
|
|
364
|
+
}
|
|
365
|
+
static wrap(name, args, opts) {
|
|
366
|
+
return new WrappedNamespace(name, args, opts);
|
|
367
|
+
}
|
|
368
|
+
static async createOrGet(name, args, opts) {
|
|
369
|
+
if (args.resource) {
|
|
370
|
+
return await Namespace.forResourceAsync(args.resource, args.cluster);
|
|
371
|
+
}
|
|
372
|
+
if (args.existing) {
|
|
373
|
+
return await Namespace.forAsync(args.existing, args.cluster);
|
|
374
|
+
}
|
|
375
|
+
return new CreatedNamespace(name, args, opts);
|
|
376
|
+
}
|
|
377
|
+
static createOrPatch(name, args, opts) {
|
|
378
|
+
if (args.resource) {
|
|
379
|
+
return new NamespacePatch(name, {
|
|
380
|
+
...args,
|
|
381
|
+
name: output3(args.resource).metadata.namespace,
|
|
382
|
+
cluster: validateCluster(args.resource, args.cluster)
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (args.existing) {
|
|
386
|
+
return new NamespacePatch(name, {
|
|
387
|
+
...args,
|
|
388
|
+
name: output3(args.existing).metadata.name,
|
|
389
|
+
cluster: validateCluster(args.existing, args.cluster)
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
return new CreatedNamespace(name, args, opts);
|
|
393
|
+
}
|
|
394
|
+
static patch(name, args, opts) {
|
|
395
|
+
return new NamespacePatch(name, args, opts);
|
|
396
|
+
}
|
|
397
|
+
static get(name, args, opts) {
|
|
398
|
+
return new ExternalNamespace(name, args, opts);
|
|
399
|
+
}
|
|
400
|
+
static namespaceCache = new Map;
|
|
401
|
+
static for(entity, cluster) {
|
|
402
|
+
return getOrCreate(Namespace.namespaceCache, `${entity.clusterName}.${entity.metadata.name}.${entity.clusterId}`, (name) => {
|
|
403
|
+
return Namespace.get(name, {
|
|
404
|
+
name: entity.metadata.name,
|
|
405
|
+
cluster: validateCluster(entity, cluster)
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
static async forAsync(entity, cluster) {
|
|
410
|
+
const resolvedEntity = await toPromise3(entity);
|
|
411
|
+
return Namespace.for(resolvedEntity, cluster);
|
|
412
|
+
}
|
|
413
|
+
static forResource(resource, cluster) {
|
|
414
|
+
return getOrCreate(Namespace.namespaceCache, `${resource.clusterName}.${resource.metadata.namespace}.${resource.clusterId}`, (name) => {
|
|
415
|
+
return Namespace.get(name, {
|
|
416
|
+
name: resource.metadata.namespace,
|
|
417
|
+
cluster: validateCluster(resource, cluster)
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
static async forResourceAsync(resource, cluster) {
|
|
422
|
+
const resolvedResource = await toPromise3(resource);
|
|
423
|
+
return Namespace.forResource(resolvedResource, cluster);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function mapNamespaceMetadata(args, fallbackName) {
|
|
427
|
+
return mapMetadata(args, fallbackName).apply((metadata) => {
|
|
428
|
+
if (args.privileged) {
|
|
429
|
+
metadata.labels = {
|
|
430
|
+
...metadata.labels,
|
|
431
|
+
"pod-security.kubernetes.io/enforce": "privileged"
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return metadata;
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
class CreatedNamespace extends Namespace {
|
|
439
|
+
constructor(name, args, opts) {
|
|
440
|
+
const namespace = output3(args.cluster).apply((cluster) => {
|
|
441
|
+
return new core3.v1.Namespace(name, { metadata: mapNamespaceMetadata(args, name) }, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
442
|
+
});
|
|
443
|
+
super("highstate:k8s:Namespace", name, args, opts, output3(args.cluster), namespace.metadata, namespace.spec, namespace.status);
|
|
444
|
+
const scope = new ClusterAccessScope(`${name}-port-forward`, {
|
|
445
|
+
namespace: this,
|
|
446
|
+
rules: [
|
|
447
|
+
{
|
|
448
|
+
apiGroups: [""],
|
|
449
|
+
resources: ["services"],
|
|
450
|
+
verbs: ["get"]
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
apiGroups: [""],
|
|
454
|
+
resources: ["pods"],
|
|
455
|
+
verbs: ["get", "list"]
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
apiGroups: [""],
|
|
459
|
+
resources: ["pods/portforward"],
|
|
460
|
+
verbs: ["create"]
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
}, { parent: this });
|
|
464
|
+
this.portForwardCluster = scope.cluster;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
class NamespacePatch extends Namespace {
|
|
469
|
+
constructor(name, args, opts) {
|
|
470
|
+
const namespace = output3(args.cluster).apply((cluster) => {
|
|
471
|
+
return new core3.v1.NamespacePatch(name, { metadata: mapNamespaceMetadata(args, name) }, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
472
|
+
});
|
|
473
|
+
super("highstate:k8s:NamespacePatch", name, args, opts, output3(args.cluster), namespace.metadata, namespace.spec, namespace.status);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
class ExternalNamespace extends Namespace {
|
|
478
|
+
constructor(name, args, opts) {
|
|
479
|
+
const namespace = output3(args.cluster).apply((cluster) => {
|
|
480
|
+
return core3.v1.Namespace.get(name, args.name, {
|
|
481
|
+
...opts,
|
|
482
|
+
parent: this,
|
|
483
|
+
provider: getProvider(cluster)
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
super("highstate:k8s:ExternalNamespace", name, args, opts, output3(args.cluster), namespace.metadata, namespace.spec, namespace.status);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
class WrappedNamespace extends Namespace {
|
|
491
|
+
constructor(name, args, opts) {
|
|
492
|
+
super("highstate:k8s:WrappedNamespace", name, args, opts, output3(args.cluster), output3(args.namespace).metadata, output3(args.namespace).spec, output3(args.namespace).status);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// src/secret.ts
|
|
497
|
+
class Secret extends NamespacedResource {
|
|
498
|
+
data;
|
|
499
|
+
stringData;
|
|
500
|
+
static apiVersion = "v1";
|
|
501
|
+
static kind = "Secret";
|
|
502
|
+
constructor(type, name, args, opts, metadata, namespace, data, stringData) {
|
|
503
|
+
super(type, name, args, opts, metadata, namespace);
|
|
504
|
+
this.data = data;
|
|
505
|
+
this.stringData = stringData;
|
|
506
|
+
}
|
|
507
|
+
get entity() {
|
|
508
|
+
return makeEntityOutput2({
|
|
509
|
+
entity: k8s2.secretEntity,
|
|
510
|
+
identity: this.metadata.uid,
|
|
511
|
+
meta: {
|
|
512
|
+
title: this.metadata.name
|
|
513
|
+
},
|
|
514
|
+
value: {
|
|
515
|
+
...this.entityBase
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
getValue(key) {
|
|
520
|
+
return this.data[key].apply((value) => Buffer.from(value, "base64").toString());
|
|
521
|
+
}
|
|
522
|
+
static create(name, args, opts) {
|
|
523
|
+
return new CreatedSecret(name, args, opts);
|
|
524
|
+
}
|
|
525
|
+
static createOrPatch(name, args, opts) {
|
|
526
|
+
if (args.existing) {
|
|
527
|
+
return new SecretPatch(name, {
|
|
528
|
+
...args,
|
|
529
|
+
name: output4(args.existing).metadata.name
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
return new CreatedSecret(name, args, opts);
|
|
533
|
+
}
|
|
534
|
+
static async createOrGet(name, args, opts) {
|
|
535
|
+
if (args.existing) {
|
|
536
|
+
return await Secret.forAsync(args.existing, output4(args.namespace).cluster);
|
|
537
|
+
}
|
|
538
|
+
return new CreatedSecret(name, args, opts);
|
|
539
|
+
}
|
|
540
|
+
static patch(name, args, opts) {
|
|
541
|
+
return new SecretPatch(name, args, opts);
|
|
542
|
+
}
|
|
543
|
+
static wrap(name, args, opts) {
|
|
544
|
+
return new WrappedSecret(name, args, opts);
|
|
545
|
+
}
|
|
546
|
+
static get(name, args, opts) {
|
|
547
|
+
return new ExternalSecret(name, args, opts);
|
|
548
|
+
}
|
|
549
|
+
static secretCache = new Map;
|
|
550
|
+
static for(entity, cluster) {
|
|
551
|
+
return getOrCreate2(Secret.secretCache, `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`, (name) => {
|
|
552
|
+
return Secret.get(name, {
|
|
553
|
+
name: entity.metadata.name,
|
|
554
|
+
namespace: Namespace.forResource(entity, cluster)
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
static async forAsync(entity, cluster) {
|
|
559
|
+
const resolvedEntity = await toPromise4(entity);
|
|
560
|
+
return Secret.for(resolvedEntity, cluster);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
class CreatedSecret extends Secret {
|
|
565
|
+
constructor(name, args, opts) {
|
|
566
|
+
const secret2 = output4(args.namespace).cluster.apply((cluster) => {
|
|
567
|
+
return new core4.v1.Secret(name, {
|
|
568
|
+
metadata: mapMetadata(args, name),
|
|
569
|
+
data: args.data,
|
|
570
|
+
stringData: args.stringData,
|
|
571
|
+
type: args.type,
|
|
572
|
+
immutable: args.immutable
|
|
573
|
+
}, {
|
|
574
|
+
...opts,
|
|
575
|
+
parent: this,
|
|
576
|
+
provider: getProvider(cluster)
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
super("highstate:k8s:Secret", name, args, opts, secret2.metadata, output4(args.namespace), secret2.data, secret2.stringData);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
class SecretPatch extends Secret {
|
|
584
|
+
constructor(name, args, opts) {
|
|
585
|
+
const secret2 = output4(args.namespace).cluster.apply((cluster) => {
|
|
586
|
+
return new core4.v1.SecretPatch(name, {
|
|
587
|
+
metadata: mapMetadata(args, name),
|
|
588
|
+
data: args.data,
|
|
589
|
+
stringData: args.stringData,
|
|
590
|
+
type: args.type,
|
|
591
|
+
immutable: args.immutable
|
|
592
|
+
}, {
|
|
593
|
+
...opts,
|
|
594
|
+
parent: this,
|
|
595
|
+
provider: getProvider(cluster)
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
super("highstate:k8s:SecretPatch", name, args, opts, secret2.metadata, output4(args.namespace), secret2.data, secret2.stringData);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
class WrappedSecret extends Secret {
|
|
603
|
+
constructor(name, args, opts) {
|
|
604
|
+
super("highstate:k8s:WrappedSecret", name, args, opts, output4(args.secret).metadata, output4(args.namespace), output4(args.secret).data, output4(args.secret).stringData);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
class ExternalSecret extends Secret {
|
|
609
|
+
constructor(name, args, opts) {
|
|
610
|
+
const secret2 = output4(args.namespace).cluster.apply(async (cluster) => {
|
|
611
|
+
const secret3 = core4.v1.Secret.get(name, interpolate2`${output4(args.namespace).metadata.name}/${args.name}`, { ...opts, parent: this, provider: getProvider(cluster) });
|
|
612
|
+
const namespace = await toPromise4(output4(args.namespace).metadata.name);
|
|
613
|
+
const resolvedName = await toPromise4(args.name);
|
|
614
|
+
const metadata = await toPromise4(secret3.metadata);
|
|
615
|
+
if (!metadata) {
|
|
616
|
+
throw new Error(`Secret ${resolvedName} in namespace ${namespace} not found`);
|
|
617
|
+
}
|
|
618
|
+
return secret3;
|
|
619
|
+
});
|
|
620
|
+
super("highstate:k8s:ExternalSecret", name, args, opts, secret2.metadata, output4(args.namespace), secret2.data, secret2.stringData);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export { images_default, Secret, ClusterAccessScope, Namespace, getProvider, getProviderAsync, getEmbeddedSecretFileContent, getClusterKubeconfigContent, commonExtraArgs, mapMetadata, mapSelectorLikeToSelector, getNamespaceName, mapNamespaceNameToSelector, validateCluster, Resource, NamespacedResource };
|