@highstate/library 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/highstate.library.msgpack +0 -0
- package/dist/index.js +1721 -953
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/abbreviations.ts +1 -0
- package/src/common/access-point.ts +2 -2
- package/src/common/files.ts +10 -0
- package/src/common/server.ts +15 -57
- package/src/databases/etcd.ts +97 -0
- package/src/databases/index.ts +1 -0
- package/src/databases/mariadb.ts +48 -2
- package/src/databases/mongodb.ts +48 -2
- package/src/databases/postgresql.ts +51 -2
- package/src/databases/redis.ts +48 -2
- package/src/databases/s3.ts +65 -6
- package/src/databases/shared.ts +12 -6
- package/src/dns.ts +59 -49
- package/src/k8s/apps/etcd.ts +46 -0
- package/src/k8s/apps/index.ts +2 -0
- package/src/k8s/apps/mariadb.ts +0 -5
- package/src/k8s/apps/minio.ts +0 -5
- package/src/k8s/apps/mongodb.ts +0 -5
- package/src/k8s/apps/postgresql.ts +0 -5
- package/src/k8s/apps/shared.ts +10 -1
- package/src/k8s/apps/traefik.ts +16 -1
- package/src/k8s/apps/valkey.ts +0 -5
- package/src/k8s/apps/wg-feed-server.ts +34 -0
- package/src/k8s/reduced-access.ts +23 -53
- package/src/k8s/resources.ts +78 -35
- package/src/k8s/service.ts +21 -10
- package/src/k8s/shared.ts +60 -90
- package/src/k8s/workload.ts +87 -26
- package/src/network/address-space.ts +94 -0
- package/src/network/address.ts +33 -0
- package/src/network/dynamic-endpoint.ts +39 -0
- package/src/network/endpoint-schema.ts +116 -0
- package/src/network/endpoint.ts +347 -0
- package/src/network/index.ts +6 -0
- package/src/network/subnet.ts +31 -0
- package/src/ssh.ts +66 -10
- package/src/third-party/cloudflare.ts +1 -0
- package/src/utils.ts +41 -11
- package/src/wireguard.ts +340 -150
- package/src/network.ts +0 -391
package/src/wireguard.ts
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
$args,
|
|
3
|
+
$inputs,
|
|
4
|
+
$outputs,
|
|
5
|
+
defineEntity,
|
|
6
|
+
defineUnit,
|
|
7
|
+
genericNameSchema,
|
|
8
|
+
z,
|
|
9
|
+
} from "@highstate/contract"
|
|
10
|
+
import { pick } from "remeda"
|
|
11
|
+
import { fileEntity } from "./common"
|
|
3
12
|
import { serverEntity } from "./common/server"
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
13
|
+
import { etcdEntity } from "./databases"
|
|
14
|
+
import { clusterEntity, networkInterfaceEntity, workloadEntity } from "./k8s"
|
|
15
|
+
import {
|
|
16
|
+
addressEntity,
|
|
17
|
+
l3EndpointEntity,
|
|
18
|
+
l4EndpointEntity,
|
|
19
|
+
l7EndpointEntity,
|
|
20
|
+
subnetEntity,
|
|
21
|
+
} from "./network"
|
|
22
|
+
import { toPatchArgs } from "./utils"
|
|
7
23
|
|
|
8
24
|
export const backendSchema = z.enum(["wireguard", "amneziawg"])
|
|
9
25
|
|
|
@@ -15,12 +31,13 @@ const networkArgs = {
|
|
|
15
31
|
*
|
|
16
32
|
* Possible values are:
|
|
17
33
|
* - `wireguard` - the default backend;
|
|
18
|
-
* - `amneziawg` - the censorship-resistant fork of WireGuard.
|
|
34
|
+
* - `amneziawg` - the censorship-resistant fork of WireGuard (NOT SUPPORTED YET).
|
|
19
35
|
*/
|
|
20
36
|
backend: backendSchema.default("wireguard"),
|
|
21
37
|
|
|
22
38
|
/**
|
|
23
39
|
* Whether to enable IPv4 support in the network.
|
|
40
|
+
* Affects addresses inside network, not the endpoints of peers.
|
|
24
41
|
*
|
|
25
42
|
* By default, IPv4 support is enabled.
|
|
26
43
|
*/
|
|
@@ -28,6 +45,7 @@ const networkArgs = {
|
|
|
28
45
|
|
|
29
46
|
/**
|
|
30
47
|
* Whether to enable IPv6 support in the network.
|
|
48
|
+
* Affects addresses inside network, not the endpoints of peers.
|
|
31
49
|
*
|
|
32
50
|
* By default, IPv6 support is disabled.
|
|
33
51
|
*/
|
|
@@ -50,14 +68,45 @@ export const nodeExposePolicySchema = z.enum(["always", "when-has-endpoint", "ne
|
|
|
50
68
|
export const peerEntity = defineEntity({
|
|
51
69
|
type: "wireguard.peer.v1",
|
|
52
70
|
|
|
71
|
+
includes: {
|
|
72
|
+
/**
|
|
73
|
+
* The endpoints where the WireGuard peer can be reached.
|
|
74
|
+
*/
|
|
75
|
+
endpoints: {
|
|
76
|
+
entity: l4EndpointEntity,
|
|
77
|
+
multiple: true,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
|
|
53
81
|
schema: z.object({
|
|
54
|
-
|
|
82
|
+
/**
|
|
83
|
+
* The name of the WireGuard peer.
|
|
84
|
+
*/
|
|
85
|
+
name: genericNameSchema,
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The network to which the WireGuard peer belongs.
|
|
89
|
+
*
|
|
90
|
+
* Holds shared configuration for all identities, peers, and nodes.
|
|
91
|
+
*/
|
|
55
92
|
network: networkEntity.schema.optional(),
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The addresses of the WireGuard interface.
|
|
96
|
+
*/
|
|
97
|
+
addresses: addressEntity.schema.array(),
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The allowed subnets of the WireGuard peer.
|
|
101
|
+
*
|
|
102
|
+
* Will be used to configure the `AllowedIPs` of the peer.
|
|
103
|
+
*/
|
|
104
|
+
allowedSubnets: subnetEntity.schema.array(),
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The public key of the WireGuard peer.
|
|
108
|
+
*/
|
|
56
109
|
publicKey: z.string(),
|
|
57
|
-
address: z.string().optional(),
|
|
58
|
-
allowedIps: z.string().array(),
|
|
59
|
-
endpoints: l4EndpointEntity.schema.array(),
|
|
60
|
-
allowedEndpoints: z.union([l3EndpointEntity.schema, l4EndpointEntity.schema]).array(),
|
|
61
110
|
|
|
62
111
|
/**
|
|
63
112
|
* The pre-shared key of the WireGuard peer.
|
|
@@ -71,13 +120,23 @@ export const peerEntity = defineEntity({
|
|
|
71
120
|
/**
|
|
72
121
|
* The pre-shared key part of the WireGuard peer.
|
|
73
122
|
*
|
|
74
|
-
* If both peers have `presharedKeyPart` set, their `presharedKey` will be calculated as
|
|
123
|
+
* If both peers have `presharedKeyPart` set, their `presharedKey` will be calculated as sha256 of the two parts.
|
|
75
124
|
*/
|
|
76
125
|
presharedKeyPart: z.string().optional(),
|
|
77
126
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
127
|
+
/**
|
|
128
|
+
* The list of DNS servers to setup for the interface connected to the WireGuard peer.
|
|
129
|
+
*/
|
|
130
|
+
dns: addressEntity.schema.array(),
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The port where the WireGuard peer is listening.
|
|
134
|
+
*
|
|
135
|
+
* Will be used:
|
|
136
|
+
* 1. For implementations if the listen port is not set elsewhere.
|
|
137
|
+
* 2. To map L3 endpoints to L4 endpoints with this port.
|
|
138
|
+
*/
|
|
139
|
+
listenPort: z.number().default(51820),
|
|
81
140
|
|
|
82
141
|
/**
|
|
83
142
|
* The keepalive interval in seconds that will be used by all nodes connecting to this peer.
|
|
@@ -85,6 +144,16 @@ export const peerEntity = defineEntity({
|
|
|
85
144
|
* If set to 0, keepalive is disabled.
|
|
86
145
|
*/
|
|
87
146
|
persistentKeepalive: z.number().int().nonnegative().default(0),
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The peers which are relayed through this peer.
|
|
150
|
+
*
|
|
151
|
+
* All their allowed IPs will be added to this peer's allowed IPs
|
|
152
|
+
* and will be used to setup routing for all other peers except the relayed ones.
|
|
153
|
+
*/
|
|
154
|
+
get relayedPeers() {
|
|
155
|
+
return peerEntity.schema.array().optional()
|
|
156
|
+
},
|
|
88
157
|
}),
|
|
89
158
|
|
|
90
159
|
meta: {
|
|
@@ -95,8 +164,17 @@ export const peerEntity = defineEntity({
|
|
|
95
164
|
export const identityEntity = defineEntity({
|
|
96
165
|
type: "wireguard.identity.v1",
|
|
97
166
|
|
|
167
|
+
includes: {
|
|
168
|
+
/**
|
|
169
|
+
* The WireGuard peer representing this identity.
|
|
170
|
+
*/
|
|
171
|
+
peer: peerEntity,
|
|
172
|
+
},
|
|
173
|
+
|
|
98
174
|
schema: z.object({
|
|
99
|
-
|
|
175
|
+
/**
|
|
176
|
+
* The private key of the WireGuard identity.
|
|
177
|
+
*/
|
|
100
178
|
privateKey: z.string(),
|
|
101
179
|
}),
|
|
102
180
|
|
|
@@ -105,10 +183,67 @@ export const identityEntity = defineEntity({
|
|
|
105
183
|
},
|
|
106
184
|
})
|
|
107
185
|
|
|
186
|
+
export const feedDisplayInfoSchema = z.object({
|
|
187
|
+
/**
|
|
188
|
+
* The display title of the tunnel.
|
|
189
|
+
*/
|
|
190
|
+
title: z.string(),
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The display description of the tunnel.
|
|
194
|
+
*/
|
|
195
|
+
description: z.string().optional(),
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The display icon URL of the tunnel.
|
|
199
|
+
*
|
|
200
|
+
* Must only be `data:` URL with SVG image.
|
|
201
|
+
*/
|
|
202
|
+
iconUrl: z.url().optional(),
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
export const feedMetadataSchema = z.object({
|
|
206
|
+
/**
|
|
207
|
+
* The ID of the tunnel in the feed.
|
|
208
|
+
*/
|
|
209
|
+
id: z.string(),
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The suggested name of the interface for the tunnel.
|
|
213
|
+
*/
|
|
214
|
+
name: genericNameSchema,
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* The display information of the tunnel.
|
|
218
|
+
*/
|
|
219
|
+
displayInfo: feedDisplayInfoSchema,
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
export const configEntity = defineEntity({
|
|
223
|
+
type: "wireguard.config.v1",
|
|
224
|
+
|
|
225
|
+
includes: {
|
|
226
|
+
/**
|
|
227
|
+
* The file containing the wg-quick configuration.
|
|
228
|
+
*/
|
|
229
|
+
file: fileEntity,
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
schema: z.object({
|
|
233
|
+
/**
|
|
234
|
+
* The metadata to include in the wg-feed for this config.
|
|
235
|
+
*
|
|
236
|
+
* Must be provided for the configs uploaded to wg-feed.
|
|
237
|
+
*/
|
|
238
|
+
feedMetadata: feedMetadataSchema.optional(),
|
|
239
|
+
}),
|
|
240
|
+
})
|
|
241
|
+
|
|
108
242
|
export type Network = z.infer<typeof networkEntity.schema>
|
|
109
243
|
export type Identity = z.infer<typeof identityEntity.schema>
|
|
110
244
|
export type Peer = z.infer<typeof peerEntity.schema>
|
|
111
245
|
export type NodeExposePolicy = z.infer<typeof nodeExposePolicySchema>
|
|
246
|
+
export type Config = z.infer<typeof configEntity.schema>
|
|
112
247
|
|
|
113
248
|
/**
|
|
114
249
|
* Holds the shared configuration for WireGuard identities, peers, and nodes.
|
|
@@ -135,7 +270,7 @@ export const network = defineUnit({
|
|
|
135
270
|
},
|
|
136
271
|
})
|
|
137
272
|
|
|
138
|
-
const sharedPeerArgs = {
|
|
273
|
+
const sharedPeerArgs = $args({
|
|
139
274
|
/**
|
|
140
275
|
* The name of the WireGuard peer.
|
|
141
276
|
*
|
|
@@ -144,11 +279,11 @@ const sharedPeerArgs = {
|
|
|
144
279
|
peerName: z.string().optional(),
|
|
145
280
|
|
|
146
281
|
/**
|
|
147
|
-
* The
|
|
282
|
+
* The addresses of the WireGuard interface.
|
|
148
283
|
*
|
|
149
284
|
* The address may be any IPv4 or IPv6 address. CIDR notation is also supported.
|
|
150
285
|
*/
|
|
151
|
-
|
|
286
|
+
addresses: z.string().array().default([]),
|
|
152
287
|
|
|
153
288
|
/**
|
|
154
289
|
* The convenience option to set `allowedIps` to `0.0.0.0/0, ::/0`.
|
|
@@ -157,16 +292,15 @@ const sharedPeerArgs = {
|
|
|
157
292
|
*/
|
|
158
293
|
exitNode: z.boolean().default(false),
|
|
159
294
|
|
|
295
|
+
/**
|
|
296
|
+
* The list of IP ranges to include in the allowed IPs of the peer.
|
|
297
|
+
*/
|
|
298
|
+
allowedSubnets: z.string().array().default([]),
|
|
299
|
+
|
|
160
300
|
/**
|
|
161
301
|
* The list of IP ranges to exclude from the tunnel.
|
|
162
|
-
*
|
|
163
|
-
* Implementation notes:
|
|
164
|
-
*
|
|
165
|
-
* - this list will not be used to generate the allowed IPs for the peer;
|
|
166
|
-
* - instead, the node will setup extra direct routes to these IPs via default gateway;
|
|
167
|
-
* - this allows to use `0.0.0.0/0, ::/0` in the `allowedIps` (and corresponding fwmark magic) and still have some IPs excluded from the tunnel.
|
|
168
302
|
*/
|
|
169
|
-
|
|
303
|
+
excludedSubnets: z.string().array().default([]),
|
|
170
304
|
|
|
171
305
|
/**
|
|
172
306
|
* The convenience option to exclude private IPs from the tunnel.
|
|
@@ -184,7 +318,7 @@ const sharedPeerArgs = {
|
|
|
184
318
|
*
|
|
185
319
|
* Will be merged with `excludedIps` if provided.
|
|
186
320
|
*/
|
|
187
|
-
|
|
321
|
+
excludePrivateSubnets: z.boolean().default(false),
|
|
188
322
|
|
|
189
323
|
/**
|
|
190
324
|
* The endpoints of the WireGuard peer.
|
|
@@ -192,18 +326,18 @@ const sharedPeerArgs = {
|
|
|
192
326
|
endpoints: z.string().array().default([]),
|
|
193
327
|
|
|
194
328
|
/**
|
|
195
|
-
* The
|
|
329
|
+
* The DNS servers that should be used by the interface connected to the WireGuard peer.
|
|
196
330
|
*
|
|
197
|
-
*
|
|
331
|
+
* If multiple peers define DNS servers, the node will merge them into a single list (but this is discouraged).
|
|
198
332
|
*/
|
|
199
|
-
|
|
333
|
+
dns: z.string().array().default([]),
|
|
200
334
|
|
|
201
335
|
/**
|
|
202
|
-
* The
|
|
336
|
+
* The convenience option to include the addresses to the allowed IPs.
|
|
203
337
|
*
|
|
204
|
-
*
|
|
338
|
+
* By default, is `true`.
|
|
205
339
|
*/
|
|
206
|
-
|
|
340
|
+
includeAddresses: z.boolean().default(true),
|
|
207
341
|
|
|
208
342
|
/**
|
|
209
343
|
* The convenience option to include the DNS servers to the allowed IPs.
|
|
@@ -215,7 +349,7 @@ const sharedPeerArgs = {
|
|
|
215
349
|
/**
|
|
216
350
|
* The port to listen on.
|
|
217
351
|
*/
|
|
218
|
-
listenPort: z.number().
|
|
352
|
+
listenPort: z.number().default(51820),
|
|
219
353
|
|
|
220
354
|
/**
|
|
221
355
|
* The keepalive interval in seconds that will be used by all nodes connecting to this peer.
|
|
@@ -223,9 +357,9 @@ const sharedPeerArgs = {
|
|
|
223
357
|
* If set to 0, keepalive is disabled.
|
|
224
358
|
*/
|
|
225
359
|
persistentKeepalive: z.number().int().nonnegative().default(0),
|
|
226
|
-
}
|
|
360
|
+
})
|
|
227
361
|
|
|
228
|
-
const sharedPeerInputs = {
|
|
362
|
+
const sharedPeerInputs = $inputs({
|
|
229
363
|
/**
|
|
230
364
|
* The network to use for the WireGuard identity.
|
|
231
365
|
*
|
|
@@ -237,65 +371,54 @@ const sharedPeerInputs = {
|
|
|
237
371
|
},
|
|
238
372
|
|
|
239
373
|
/**
|
|
240
|
-
* The L3 endpoints of the identity.
|
|
374
|
+
* The L3/L4 endpoints of the identity.
|
|
241
375
|
*
|
|
242
|
-
*
|
|
376
|
+
* All L3 endpoints will be adjusted to L4 endpoints with listen port of the identity.
|
|
243
377
|
*/
|
|
244
|
-
|
|
378
|
+
endpoints: {
|
|
245
379
|
entity: l3EndpointEntity,
|
|
246
380
|
multiple: true,
|
|
247
381
|
required: false,
|
|
248
382
|
},
|
|
249
383
|
|
|
250
384
|
/**
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* Will take priority over all calculated endpoints if provided.
|
|
385
|
+
* the endpoints to add to the allowed IPs of the identity.
|
|
254
386
|
*/
|
|
255
|
-
|
|
256
|
-
entity:
|
|
257
|
-
required: false,
|
|
387
|
+
allowedEndpoints: {
|
|
388
|
+
entity: l3EndpointEntity,
|
|
258
389
|
multiple: true,
|
|
390
|
+
required: false,
|
|
259
391
|
},
|
|
260
392
|
|
|
261
393
|
/**
|
|
262
|
-
* The
|
|
263
|
-
*
|
|
264
|
-
* `hostname` endpoints will be ignored.
|
|
265
|
-
*
|
|
266
|
-
* If the endpoint contains k8s service metadata of the cluster where the identity node is deployed,
|
|
267
|
-
* the corresponding network policy will be created.
|
|
394
|
+
* The subnets to add to the allowed IPs of the identity.
|
|
268
395
|
*/
|
|
269
|
-
|
|
270
|
-
entity:
|
|
396
|
+
allowedSubnets: {
|
|
397
|
+
entity: subnetEntity,
|
|
271
398
|
multiple: true,
|
|
272
399
|
required: false,
|
|
273
400
|
},
|
|
274
401
|
|
|
275
402
|
/**
|
|
276
|
-
* The
|
|
277
|
-
*
|
|
278
|
-
* If the endpoint contains k8s service metadata of the cluster where the identity node is deployed,
|
|
279
|
-
* the corresponding network policy will be created.
|
|
403
|
+
* The peers which are relayed through this peer.
|
|
280
404
|
*/
|
|
281
|
-
|
|
282
|
-
entity:
|
|
405
|
+
relayedPeers: {
|
|
406
|
+
entity: peerEntity,
|
|
283
407
|
multiple: true,
|
|
284
408
|
required: false,
|
|
285
409
|
},
|
|
286
|
-
}
|
|
410
|
+
})
|
|
287
411
|
|
|
288
|
-
const sharedPeerOutputs = {
|
|
412
|
+
const sharedPeerOutputs = $outputs({
|
|
289
413
|
peer: peerEntity,
|
|
414
|
+
})
|
|
290
415
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
export type SharedPeerArgs = z.infer<z.ZodObject<typeof sharedPeerArgs>>
|
|
416
|
+
export type SharedPeerArgs = z.infer<
|
|
417
|
+
z.ZodObject<{
|
|
418
|
+
// @ts-expect-error idk why
|
|
419
|
+
[K in keyof typeof sharedPeerArgs]: (typeof sharedPeerArgs)[K]["schema"]
|
|
420
|
+
}>
|
|
421
|
+
>
|
|
299
422
|
|
|
300
423
|
/**
|
|
301
424
|
* The WireGuard peer with the public key.
|
|
@@ -341,52 +464,14 @@ export const peer = defineUnit({
|
|
|
341
464
|
export const peerPatch = defineUnit({
|
|
342
465
|
type: "wireguard.peer-patch.v1",
|
|
343
466
|
|
|
344
|
-
args:
|
|
345
|
-
/**
|
|
346
|
-
* The endpoints of the WireGuard peer.
|
|
347
|
-
*/
|
|
348
|
-
endpoints: z.string().array().default([]),
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* The mode to use for patching the endpoints.
|
|
352
|
-
*
|
|
353
|
-
* - `prepend`: prepend the new endpoints to the existing ones (default);
|
|
354
|
-
* - `replace`: replace the existing endpoints with the new ones.
|
|
355
|
-
*/
|
|
356
|
-
endpointsPatchMode: arrayPatchModeSchema.default("prepend"),
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* The allowed endpoints of the WireGuard peer.
|
|
360
|
-
*
|
|
361
|
-
* The non `hostname` endpoints will be added to the `allowedIps` of the peer.
|
|
362
|
-
*/
|
|
363
|
-
allowedEndpoints: z.string().array().default([]),
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* The mode to use for patching the allowed endpoints.
|
|
367
|
-
*
|
|
368
|
-
* - `prepend`: prepend the new endpoints to the existing ones (default);
|
|
369
|
-
* - `replace`: replace the existing endpoints with the new ones.
|
|
370
|
-
*/
|
|
371
|
-
allowedEndpointsPatchMode: arrayPatchModeSchema.default("prepend"),
|
|
372
|
-
|
|
373
|
-
...omit(sharedPeerArgs, ["endpoints", "allowedEndpoints"]),
|
|
374
|
-
},
|
|
467
|
+
args: toPatchArgs(sharedPeerArgs),
|
|
375
468
|
|
|
376
469
|
inputs: {
|
|
377
470
|
peer: peerEntity,
|
|
378
471
|
...sharedPeerInputs,
|
|
379
472
|
},
|
|
380
473
|
|
|
381
|
-
outputs:
|
|
382
|
-
peer: peerEntity,
|
|
383
|
-
|
|
384
|
-
endpoints: {
|
|
385
|
-
entity: l4EndpointEntity,
|
|
386
|
-
required: false,
|
|
387
|
-
multiple: true,
|
|
388
|
-
},
|
|
389
|
-
},
|
|
474
|
+
outputs: sharedPeerOutputs,
|
|
390
475
|
|
|
391
476
|
meta: {
|
|
392
477
|
title: "WireGuard Peer Patch",
|
|
@@ -408,25 +493,7 @@ export const peerPatch = defineUnit({
|
|
|
408
493
|
export const identity = defineUnit({
|
|
409
494
|
type: "wireguard.identity.v1",
|
|
410
495
|
|
|
411
|
-
args:
|
|
412
|
-
...sharedPeerArgs,
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* The port to listen on.
|
|
416
|
-
*
|
|
417
|
-
* Used by the implementation of the identity and to calculate the endpoint of the peer.
|
|
418
|
-
*/
|
|
419
|
-
listenPort: z.number().optional(),
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* The endpoint of the WireGuard peer.
|
|
423
|
-
*
|
|
424
|
-
* If overridden, does not affect node which implements the identity, but is used in the peer configuration of other nodes.
|
|
425
|
-
*
|
|
426
|
-
* Will take priority over all calculated endpoints and `l4Endpoint` input.
|
|
427
|
-
*/
|
|
428
|
-
endpoints: z.string().array().default([]),
|
|
429
|
-
},
|
|
496
|
+
args: sharedPeerArgs,
|
|
430
497
|
|
|
431
498
|
secrets: {
|
|
432
499
|
/**
|
|
@@ -448,7 +515,6 @@ export const identity = defineUnit({
|
|
|
448
515
|
|
|
449
516
|
outputs: {
|
|
450
517
|
identity: identityEntity,
|
|
451
|
-
...sharedPeerOutputs,
|
|
452
518
|
},
|
|
453
519
|
|
|
454
520
|
meta: {
|
|
@@ -509,7 +575,7 @@ export const nodeK8s = defineUnit({
|
|
|
509
575
|
*
|
|
510
576
|
* Useful for peer isolation where you want to prevent cross-peer communication.
|
|
511
577
|
*/
|
|
512
|
-
|
|
578
|
+
forwardRestrictedSubnets: z.string().array().default([]),
|
|
513
579
|
},
|
|
514
580
|
|
|
515
581
|
inputs: {
|
|
@@ -517,7 +583,7 @@ export const nodeK8s = defineUnit({
|
|
|
517
583
|
k8sCluster: clusterEntity,
|
|
518
584
|
|
|
519
585
|
workload: {
|
|
520
|
-
entity:
|
|
586
|
+
entity: workloadEntity,
|
|
521
587
|
required: false,
|
|
522
588
|
},
|
|
523
589
|
|
|
@@ -534,20 +600,16 @@ export const nodeK8s = defineUnit({
|
|
|
534
600
|
},
|
|
535
601
|
|
|
536
602
|
outputs: {
|
|
603
|
+
workload: {
|
|
604
|
+
entity: workloadEntity,
|
|
605
|
+
},
|
|
606
|
+
|
|
537
607
|
interface: {
|
|
538
608
|
entity: networkInterfaceEntity,
|
|
539
|
-
required: false,
|
|
540
609
|
},
|
|
541
610
|
|
|
542
611
|
peer: {
|
|
543
612
|
entity: peerEntity,
|
|
544
|
-
required: false,
|
|
545
|
-
},
|
|
546
|
-
|
|
547
|
-
endpoints: {
|
|
548
|
-
entity: l4EndpointEntity,
|
|
549
|
-
required: false,
|
|
550
|
-
multiple: true,
|
|
551
613
|
},
|
|
552
614
|
},
|
|
553
615
|
|
|
@@ -579,13 +641,6 @@ export const node = defineUnit({
|
|
|
579
641
|
*/
|
|
580
642
|
interfaceName: z.string().optional(),
|
|
581
643
|
|
|
582
|
-
/**
|
|
583
|
-
* The name of the default interface for excluded routes.
|
|
584
|
-
*
|
|
585
|
-
* This is used to route excluded IPs through the default interface instead of the WireGuard tunnel.
|
|
586
|
-
*/
|
|
587
|
-
defaultInterface: z.string().default("eth0"),
|
|
588
|
-
|
|
589
644
|
/**
|
|
590
645
|
* List of CIDR blocks that should be blocked from forwarding through this WireGuard node.
|
|
591
646
|
*
|
|
@@ -665,6 +720,17 @@ export const node = defineUnit({
|
|
|
665
720
|
},
|
|
666
721
|
})
|
|
667
722
|
|
|
723
|
+
const sharedArgs = $args({
|
|
724
|
+
/**
|
|
725
|
+
* The filter to use when selecting endpoints for each peer.
|
|
726
|
+
*
|
|
727
|
+
* The first matching endpoint will be used.
|
|
728
|
+
*
|
|
729
|
+
* If not provided, all endpoints will be considered.
|
|
730
|
+
*/
|
|
731
|
+
peerEndpointFilter: z.string().optional().meta({ language: "javascript" }),
|
|
732
|
+
})
|
|
733
|
+
|
|
668
734
|
/**
|
|
669
735
|
* Just the WireGuard configuration for the identity and peers.
|
|
670
736
|
*/
|
|
@@ -672,12 +738,34 @@ export const config = defineUnit({
|
|
|
672
738
|
type: "wireguard.config.v1",
|
|
673
739
|
|
|
674
740
|
args: {
|
|
741
|
+
...sharedArgs,
|
|
742
|
+
|
|
675
743
|
/**
|
|
676
|
-
* The
|
|
677
|
-
*
|
|
678
|
-
* If not provided, the config will not respect `excludedIps`.
|
|
744
|
+
* The metadata to include in the wg-feed for this config.
|
|
679
745
|
*/
|
|
680
|
-
|
|
746
|
+
feedMetadata: z
|
|
747
|
+
.discriminatedUnion("enabled", [
|
|
748
|
+
z.object({
|
|
749
|
+
/**
|
|
750
|
+
* Whether this config is enabled for upload to wg-feed.
|
|
751
|
+
*
|
|
752
|
+
* You must fill the metadata fields.
|
|
753
|
+
*/
|
|
754
|
+
enabled: z.literal("true"),
|
|
755
|
+
|
|
756
|
+
...pick(feedMetadataSchema.shape, ["id", "name"]),
|
|
757
|
+
|
|
758
|
+
// Highstate does not support nested objects in UI
|
|
759
|
+
...feedDisplayInfoSchema.shape,
|
|
760
|
+
}),
|
|
761
|
+
z.object({
|
|
762
|
+
/**
|
|
763
|
+
* Whether this config is enabled for upload to wg-feed.
|
|
764
|
+
*/
|
|
765
|
+
enabled: z.literal("false"),
|
|
766
|
+
}),
|
|
767
|
+
])
|
|
768
|
+
.prefault({ enabled: "false" }),
|
|
681
769
|
},
|
|
682
770
|
|
|
683
771
|
inputs: {
|
|
@@ -689,6 +777,10 @@ export const config = defineUnit({
|
|
|
689
777
|
},
|
|
690
778
|
},
|
|
691
779
|
|
|
780
|
+
outputs: {
|
|
781
|
+
config: configEntity,
|
|
782
|
+
},
|
|
783
|
+
|
|
692
784
|
meta: {
|
|
693
785
|
title: "WireGuard Config",
|
|
694
786
|
icon: "simple-icons:wireguard",
|
|
@@ -709,6 +801,10 @@ export const config = defineUnit({
|
|
|
709
801
|
export const configBundle = defineUnit({
|
|
710
802
|
type: "wireguard.config-bundle.v1",
|
|
711
803
|
|
|
804
|
+
args: {
|
|
805
|
+
...sharedArgs,
|
|
806
|
+
},
|
|
807
|
+
|
|
712
808
|
inputs: {
|
|
713
809
|
identity: identityEntity,
|
|
714
810
|
peers: {
|
|
@@ -722,6 +818,13 @@ export const configBundle = defineUnit({
|
|
|
722
818
|
},
|
|
723
819
|
},
|
|
724
820
|
|
|
821
|
+
outputs: {
|
|
822
|
+
configs: {
|
|
823
|
+
entity: configEntity,
|
|
824
|
+
multiple: true,
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
|
|
725
828
|
meta: {
|
|
726
829
|
title: "WireGuard Config Bundle",
|
|
727
830
|
icon: "simple-icons:wireguard",
|
|
@@ -735,3 +838,90 @@ export const configBundle = defineUnit({
|
|
|
735
838
|
path: "config-bundle",
|
|
736
839
|
},
|
|
737
840
|
})
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Uploads WireGuard configs to the etcd to be consumed by wg-feed clients.
|
|
844
|
+
*/
|
|
845
|
+
export const feed = defineUnit({
|
|
846
|
+
type: "wireguard.feed.v1",
|
|
847
|
+
|
|
848
|
+
args: {
|
|
849
|
+
/**
|
|
850
|
+
* The TTL seconds to suggest to wg-feed clients.
|
|
851
|
+
*
|
|
852
|
+
* By default, is 900 seconds (15 minutes).
|
|
853
|
+
*/
|
|
854
|
+
ttlSeconds: z.number().int().positive().default(900),
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* The endpoints of the wg-feed servers to use for generating the subscription URLs.
|
|
858
|
+
*
|
|
859
|
+
* At least one endpoint must be provided either here or via `serverEndpoints` input.
|
|
860
|
+
*
|
|
861
|
+
* The resulting subscription URL will be inferred as: `https://{firstEndpoint}/{feedId}#{privateKey}`.
|
|
862
|
+
*/
|
|
863
|
+
serverEndpoints: z.string().array().default([]),
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* The AGE public key (x25519 recipient) to encrypt the configs with.
|
|
867
|
+
*
|
|
868
|
+
* Note: If you provide this, you must provide the corresponding private key to the clients.
|
|
869
|
+
* Resulting subscription URL will not contain the private key.
|
|
870
|
+
*/
|
|
871
|
+
publicKey: z.string().optional(),
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* The display information of the feed.
|
|
875
|
+
*/
|
|
876
|
+
displayInfo: feedDisplayInfoSchema,
|
|
877
|
+
},
|
|
878
|
+
|
|
879
|
+
secrets: {
|
|
880
|
+
/**
|
|
881
|
+
* The cuidv2 of the feed.
|
|
882
|
+
* Will be used as path of the feed in etcd/subscription URL.
|
|
883
|
+
*
|
|
884
|
+
* In most cases, you don't want to provide this and let it be generated automatically.
|
|
885
|
+
*
|
|
886
|
+
* The `id` field of the feed document will be inferred from this value as `uuidv5(feedId, "2b5e358c-3510-48fb-b1cf-a8aee788925a")`.
|
|
887
|
+
*/
|
|
888
|
+
feedId: z.string().optional(),
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* The AGE private key (x25519 identity) to embed in the subscription URL.
|
|
892
|
+
*
|
|
893
|
+
* If not provided and `publicKey` is not provided, a new key pair will be generated.
|
|
894
|
+
*/
|
|
895
|
+
privateKey: z.string().optional(),
|
|
896
|
+
},
|
|
897
|
+
|
|
898
|
+
inputs: {
|
|
899
|
+
etcd: etcdEntity,
|
|
900
|
+
serverEndpoints: {
|
|
901
|
+
entity: l4EndpointEntity,
|
|
902
|
+
required: false,
|
|
903
|
+
multiple: true,
|
|
904
|
+
},
|
|
905
|
+
configs: {
|
|
906
|
+
entity: configEntity,
|
|
907
|
+
multiple: true,
|
|
908
|
+
},
|
|
909
|
+
},
|
|
910
|
+
|
|
911
|
+
outputs: {
|
|
912
|
+
endpoint: l7EndpointEntity,
|
|
913
|
+
},
|
|
914
|
+
|
|
915
|
+
source: {
|
|
916
|
+
package: "@highstate/wireguard",
|
|
917
|
+
path: "feed",
|
|
918
|
+
},
|
|
919
|
+
|
|
920
|
+
meta: {
|
|
921
|
+
title: "WireGuard Feed",
|
|
922
|
+
icon: "simple-icons:wireguard",
|
|
923
|
+
iconColor: "#88171a",
|
|
924
|
+
secondaryIcon: "mdi:rss",
|
|
925
|
+
category: "VPN",
|
|
926
|
+
},
|
|
927
|
+
})
|