@highstate/library 0.9.15 → 0.9.18

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.
Files changed (46) hide show
  1. package/dist/highstate.library.msgpack +0 -0
  2. package/dist/highstate.manifest.json +5 -0
  3. package/dist/index.js +1716 -1166
  4. package/dist/index.js.map +1 -1
  5. package/package.json +8 -6
  6. package/src/abbreviations.ts +35 -0
  7. package/src/apps/code-server.ts +5 -5
  8. package/src/apps/deployment.ts +20 -20
  9. package/src/apps/dns.ts +12 -14
  10. package/src/apps/gitea.ts +2 -2
  11. package/src/apps/grocy.ts +2 -2
  12. package/src/apps/hubble.ts +2 -2
  13. package/src/apps/kubernetes-dashboard.ts +2 -2
  14. package/src/apps/mariadb.ts +10 -10
  15. package/src/apps/maybe.ts +5 -5
  16. package/src/apps/mongodb.ts +10 -10
  17. package/src/apps/network.ts +6 -6
  18. package/src/apps/postgresql.ts +10 -10
  19. package/src/apps/shared.ts +18 -19
  20. package/src/apps/syncthing.ts +6 -6
  21. package/src/apps/traefik.ts +4 -4
  22. package/src/apps/vaultwarden.ts +4 -4
  23. package/src/apps/zitadel.ts +2 -2
  24. package/src/cloudflare.ts +4 -4
  25. package/src/common.ts +25 -78
  26. package/src/distributions/index.ts +1 -0
  27. package/src/distributions/ubuntu.ts +32 -0
  28. package/src/dns.ts +10 -18
  29. package/src/files.ts +135 -0
  30. package/src/git.ts +58 -0
  31. package/src/index.ts +5 -0
  32. package/src/k3s.ts +9 -17
  33. package/src/k8s.ts +130 -146
  34. package/src/mullvad.ts +5 -9
  35. package/src/network.ts +69 -44
  36. package/src/nixos.ts +51 -86
  37. package/src/obfuscators/phantun.ts +4 -4
  38. package/src/obfuscators/shared.ts +23 -43
  39. package/src/proxmox.ts +301 -60
  40. package/src/restic.ts +17 -19
  41. package/src/sops.ts +7 -6
  42. package/src/ssh.ts +21 -19
  43. package/src/talos.ts +15 -27
  44. package/src/timeweb.ts +13 -13
  45. package/src/utils.ts +3 -3
  46. package/src/wireguard.ts +90 -127
package/src/wireguard.ts CHANGED
@@ -1,35 +1,35 @@
1
- import { defineEntity, defineUnit, Type, type Static, type TObject } from "@highstate/contract"
1
+ import { defineEntity, defineUnit, z } from "@highstate/contract"
2
2
  import { omit } from "remeda"
3
3
  import { clusterEntity, interfaceEntity, exposableWorkloadEntity } from "./k8s"
4
4
  import { l3EndpointEntity, l4EndpointEntity } from "./network"
5
5
  import { arrayPatchModeSchema } from "./utils"
6
6
 
7
- export const backendSchema = Type.StringEnum(["wireguard", "amneziawg"])
7
+ export const backendSchema = z.enum(["wireguard", "amneziawg"])
8
8
 
9
- export type Backend = Static<typeof backendSchema>
9
+ export type Backend = z.infer<typeof backendSchema>
10
10
 
11
11
  export const networkEntity = defineEntity({
12
12
  type: "wireguard.network",
13
13
 
14
- schema: Type.Object({
14
+ schema: z.object({
15
15
  backend: backendSchema,
16
- ipv6: Type.Boolean(),
16
+ ipv6: z.boolean(),
17
17
  }),
18
18
  })
19
19
 
20
- export const nodeExposePolicySchema = Type.StringEnum(["always", "when-has-endpoint", "never"])
20
+ export const nodeExposePolicySchema = z.enum(["always", "when-has-endpoint", "never"])
21
21
 
22
22
  export const peerEntity = defineEntity({
23
23
  type: "wireguard.peer",
24
24
 
25
- schema: Type.Object({
26
- name: Type.String(),
27
- network: Type.Optional(networkEntity.schema),
28
- publicKey: Type.String(),
29
- address: Type.Optional(Type.String()),
30
- allowedIps: Type.Array(Type.String()),
31
- endpoints: Type.Array(l4EndpointEntity.schema),
32
- allowedEndpoints: Type.Array(Type.Union([l3EndpointEntity.schema, l4EndpointEntity.schema])),
25
+ schema: z.object({
26
+ name: z.string(),
27
+ network: networkEntity.schema.optional(),
28
+ publicKey: z.string(),
29
+ address: z.string().optional(),
30
+ allowedIps: z.string().array(),
31
+ endpoints: l4EndpointEntity.schema.array(),
32
+ allowedEndpoints: z.union([l3EndpointEntity.schema, l4EndpointEntity.schema]).array(),
33
33
 
34
34
  /**
35
35
  * The pre-shared key of the WireGuard peer.
@@ -38,18 +38,18 @@ export const peerEntity = defineEntity({
38
38
  *
39
39
  * Will be ignored if both peers have `presharedKeyPart` set.
40
40
  */
41
- presharedKey: Type.Optional(Type.String()),
41
+ presharedKey: z.string().optional(),
42
42
 
43
43
  /**
44
44
  * The pre-shared key part of the WireGuard peer.
45
45
  *
46
46
  * If both peers have `presharedKeyPart` set, their `presharedKey` will be calculated as XOR of the two parts.
47
47
  */
48
- presharedKeyPart: Type.Optional(Type.String()),
48
+ presharedKeyPart: z.string().optional(),
49
49
 
50
- excludedIps: Type.Array(Type.String()),
51
- dns: Type.Array(Type.String()),
52
- listenPort: Type.Optional(Type.Number()),
50
+ excludedIps: z.string().array(),
51
+ dns: z.string().array(),
52
+ listenPort: z.number().optional(),
53
53
  }),
54
54
 
55
55
  meta: {
@@ -60,9 +60,9 @@ export const peerEntity = defineEntity({
60
60
  export const identityEntity = defineEntity({
61
61
  type: "wireguard.identity",
62
62
 
63
- schema: Type.Object({
63
+ schema: z.object({
64
64
  peer: peerEntity.schema,
65
- privateKey: Type.String(),
65
+ privateKey: z.string(),
66
66
  }),
67
67
 
68
68
  meta: {
@@ -70,10 +70,10 @@ export const identityEntity = defineEntity({
70
70
  },
71
71
  })
72
72
 
73
- export type Network = Static<typeof networkEntity.schema>
74
- export type Identity = Static<typeof identityEntity.schema>
75
- export type Peer = Static<typeof peerEntity.schema>
76
- export type NodeExposePolicy = Static<typeof nodeExposePolicySchema>
73
+ export type Network = z.infer<typeof networkEntity.schema>
74
+ export type Identity = z.infer<typeof identityEntity.schema>
75
+ export type Peer = z.infer<typeof peerEntity.schema>
76
+ export type NodeExposePolicy = z.infer<typeof nodeExposePolicySchema>
77
77
 
78
78
  /**
79
79
  * The network hols the shared configuration for the WireGuard identities, peers and nodes.
@@ -90,19 +90,15 @@ export const network = defineUnit({
90
90
  * 2. `amneziawg` - The censorship-resistant fork of WireGuard.
91
91
  *
92
92
  * By default, the `wireguard` backend is used.
93
- *
94
- * @schema
95
93
  */
96
- backend: Type.Default(backendSchema, "wireguard"),
94
+ backend: backendSchema.default("wireguard"),
97
95
 
98
96
  /**
99
97
  * The option to enable IPv6 support in the network.
100
98
  *
101
99
  * By default, IPv6 support is disabled.
102
- *
103
- * @schema
104
100
  */
105
- ipv6: Type.Default(Type.Boolean(), false),
101
+ ipv6: z.boolean().default(false),
106
102
  },
107
103
 
108
104
  outputs: {
@@ -111,8 +107,8 @@ export const network = defineUnit({
111
107
 
112
108
  meta: {
113
109
  description: "The WireGuard network with some shared configuration.",
114
- primaryIcon: "simple-icons:wireguard",
115
- primaryIconColor: "#88171a",
110
+ icon: "simple-icons:wireguard",
111
+ iconColor: "#88171a",
116
112
  secondaryIcon: "mdi:local-area-network-connect",
117
113
  category: "VPN",
118
114
  },
@@ -128,28 +124,22 @@ const sharedPeerArgs = {
128
124
  * The name of the WireGuard peer.
129
125
  *
130
126
  * If not provided, the peer will be named after the unit.
131
- *
132
- * @schema
133
127
  */
134
- peerName: Type.Optional(Type.String()),
128
+ peerName: z.string().optional(),
135
129
 
136
130
  /**
137
131
  * The address of the WireGuard interface.
138
132
  *
139
133
  * The address may be any IPv4 or IPv6 address. CIDR notation is also supported.
140
- *
141
- * @schema
142
134
  */
143
- address: Type.Optional(Type.String()),
135
+ address: z.string().optional(),
144
136
 
145
137
  /**
146
138
  * The convenience option to set `allowedIps` to `0.0.0.0/0, ::/0`.
147
139
  *
148
140
  * Will be merged with the `allowedIps` if provided.
149
- *
150
- * @schema
151
141
  */
152
- exitNode: Type.Default(Type.Boolean(), false),
142
+ exitNode: z.boolean().default(false),
153
143
 
154
144
  /**
155
145
  * The list of IP ranges to exclude from the tunnel.
@@ -159,10 +149,8 @@ const sharedPeerArgs = {
159
149
  * - This list will not be used to generate the allowed IPs for the peer.
160
150
  * - Instead, the node will setup extra direct routes to these IPs via default gateway.
161
151
  * - 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.
162
- *
163
- * @schema
164
152
  */
165
- excludedIps: Type.Default(Type.Array(Type.String()), []),
153
+ excludedIps: z.string().array().default([]),
166
154
 
167
155
  /**
168
156
  * The convenience option to exclude private IPs from the tunnel.
@@ -179,51 +167,39 @@ const sharedPeerArgs = {
179
167
  * - `fe80::/10`
180
168
  *
181
169
  * Will be merged with `excludedIps` if provided.
182
- *
183
- * @schema
184
170
  */
185
- excludePrivateIps: Type.Default(Type.Boolean(), false),
171
+ excludePrivateIps: z.boolean().default(false),
186
172
 
187
173
  /**
188
174
  * The endpoints of the WireGuard peer.
189
- *
190
- * @schema
191
175
  */
192
- endpoints: Type.Default(Type.Array(Type.String()), []),
176
+ endpoints: z.string().array().default([]),
193
177
 
194
178
  /**
195
179
  * The allowed endpoints of the WireGuard peer.
196
180
  *
197
181
  * The non `hostname` endpoints will be added to the `allowedIps` of the peer.
198
- *
199
- * @schema
200
182
  */
201
- allowedEndpoints: Type.Default(Type.Array(Type.String()), []),
183
+ allowedEndpoints: z.string().array().default([]),
202
184
 
203
185
  /**
204
186
  * The DNS servers that should be used by the interface connected to the WireGuard peer.
205
187
  *
206
188
  * If multiple peers define DNS servers, the node will merge them into a single list (but this is discouraged).
207
- *
208
- * @schema
209
189
  */
210
- dns: Type.Default(Type.Array(Type.String()), []),
190
+ dns: z.string().array().default([]),
211
191
 
212
192
  /**
213
193
  * The convenience option to include the DNS servers to the allowed IPs.
214
194
  *
215
195
  * By default, is `true`.
216
- *
217
- * @schema
218
196
  */
219
- includeDns: Type.Default(Type.Boolean(), true),
197
+ includeDns: z.boolean().default(true),
220
198
 
221
199
  /**
222
200
  * The port to listen on.
223
- *
224
- * @schema
225
201
  */
226
- listenPort: Type.Optional(Type.Number()),
202
+ listenPort: z.number().optional(),
227
203
  }
228
204
 
229
205
  const sharedPeerInputs = {
@@ -231,8 +207,6 @@ const sharedPeerInputs = {
231
207
  * The network to use for the WireGuard identity.
232
208
  *
233
209
  * If not provided, the identity will use default network configuration.
234
- *
235
- * @schema
236
210
  */
237
211
  network: {
238
212
  entity: networkEntity,
@@ -243,8 +217,6 @@ const sharedPeerInputs = {
243
217
  * The L3 endpoints of the identity.
244
218
  *
245
219
  * Will produce L4 endpoints for each of the provided L3 endpoints.
246
- *
247
- * @schema
248
220
  */
249
221
  l3Endpoints: {
250
222
  entity: l3EndpointEntity,
@@ -256,8 +228,6 @@ const sharedPeerInputs = {
256
228
  * The L4 endpoints of the identity.
257
229
  *
258
230
  * Will take priority over all calculated endpoints if provided.
259
- *
260
- * @schema
261
231
  */
262
232
  l4Endpoints: {
263
233
  entity: l4EndpointEntity,
@@ -272,8 +242,6 @@ const sharedPeerInputs = {
272
242
  *
273
243
  * If the endpoint contains k8s service metadata of the cluster where the identity node is deployed,
274
244
  * the corresponding network policy will be created.
275
- *
276
- * @schema
277
245
  */
278
246
  allowedL3Endpoints: {
279
247
  entity: l3EndpointEntity,
@@ -286,8 +254,6 @@ const sharedPeerInputs = {
286
254
  *
287
255
  * If the endpoint contains k8s service metadata of the cluster where the identity node is deployed,
288
256
  * the corresponding network policy will be created.
289
- *
290
- * @schema
291
257
  */
292
258
  allowedL4Endpoints: {
293
259
  entity: l4EndpointEntity,
@@ -306,7 +272,18 @@ const sharedPeerOutputs = {
306
272
  },
307
273
  } as const
308
274
 
309
- export type SharedPeerArgs = Static<TObject<typeof sharedPeerArgs>>
275
+ export type SharedPeerArgs = {
276
+ peerName?: string
277
+ address?: string
278
+ exitNode: boolean
279
+ excludedIps: string[]
280
+ excludePrivateIps: boolean
281
+ endpoints: string[]
282
+ allowedEndpoints: string[]
283
+ dns: string[]
284
+ includeDns: boolean
285
+ listenPort?: number
286
+ }
310
287
 
311
288
  export const peer = defineUnit({
312
289
  type: "wireguard.peer",
@@ -316,19 +293,15 @@ export const peer = defineUnit({
316
293
 
317
294
  /**
318
295
  * The public key of the WireGuard peer.
319
- *
320
- * @schema
321
296
  */
322
- publicKey: Type.String(),
297
+ publicKey: z.string(),
323
298
  },
324
299
 
325
300
  secrets: {
326
301
  /**
327
302
  * The pre-shared key which should be used for the peer.
328
- *
329
- * @schema
330
303
  */
331
- presharedKey: Type.Optional(Type.String()),
304
+ presharedKey: z.string().optional(),
332
305
  },
333
306
 
334
307
  inputs: sharedPeerInputs,
@@ -336,8 +309,8 @@ export const peer = defineUnit({
336
309
 
337
310
  meta: {
338
311
  description: "The WireGuard peer with the public key.",
339
- primaryIcon: "simple-icons:wireguard",
340
- primaryIconColor: "#88171a",
312
+ icon: "simple-icons:wireguard",
313
+ iconColor: "#88171a",
341
314
  secondaryIcon: "mdi:badge-account-horizontal",
342
315
  category: "VPN",
343
316
  },
@@ -354,10 +327,8 @@ export const peerPatch = defineUnit({
354
327
  args: {
355
328
  /**
356
329
  * The endpoints of the WireGuard peer.
357
- *
358
- * @schema
359
330
  */
360
- endpoints: Type.Default(Type.Array(Type.String()), []),
331
+ endpoints: z.string().array().default([]),
361
332
 
362
333
  /**
363
334
  * The mode to use for patching the endpoints.
@@ -365,16 +336,14 @@ export const peerPatch = defineUnit({
365
336
  * - `prepend`: prepend the new endpoints to the existing ones (default);
366
337
  * - `replace`: replace the existing endpoints with the new ones.
367
338
  */
368
- endpointsPatchMode: Type.Default(arrayPatchModeSchema, "prepend"),
339
+ endpointsPatchMode: arrayPatchModeSchema.default("prepend"),
369
340
 
370
341
  /**
371
342
  * The allowed endpoints of the WireGuard peer.
372
343
  *
373
344
  * The non `hostname` endpoints will be added to the `allowedIps` of the peer.
374
- *
375
- * @schema
376
345
  */
377
- allowedEndpoints: Type.Default(Type.Array(Type.String()), []),
346
+ allowedEndpoints: z.string().array().default([]),
378
347
 
379
348
  /**
380
349
  * The mode to use for patching the allowed endpoints.
@@ -382,7 +351,7 @@ export const peerPatch = defineUnit({
382
351
  * - `prepend`: prepend the new endpoints to the existing ones (default);
383
352
  * - `replace`: replace the existing endpoints with the new ones.
384
353
  */
385
- allowedEndpointsPatchMode: Type.Default(arrayPatchModeSchema, "prepend"),
354
+ allowedEndpointsPatchMode: arrayPatchModeSchema.default("prepend"),
386
355
 
387
356
  ...omit(sharedPeerArgs, ["endpoints", "allowedEndpoints"]),
388
357
  },
@@ -403,10 +372,10 @@ export const peerPatch = defineUnit({
403
372
  },
404
373
 
405
374
  meta: {
406
- displayName: "WireGuard Peer Patch",
375
+ title: "WireGuard Peer Patch",
407
376
  description: "Patches some properties of the WireGuard peer.",
408
- primaryIcon: "simple-icons:wireguard",
409
- primaryIconColor: "#88171a",
377
+ icon: "simple-icons:wireguard",
378
+ iconColor: "#88171a",
410
379
  secondaryIcon: "mdi:badge-account-horizontal",
411
380
  category: "VPN",
412
381
  },
@@ -427,10 +396,8 @@ export const identity = defineUnit({
427
396
  * The port to listen on.
428
397
  *
429
398
  * Used by the implementation of the identity and to calculate the endpoint of the peer.
430
- *
431
- * @schema
432
399
  */
433
- listenPort: Type.Optional(Type.Number()),
400
+ listenPort: z.number().optional(),
434
401
 
435
402
  /**
436
403
  * The endpoint of the WireGuard peer.
@@ -438,10 +405,8 @@ export const identity = defineUnit({
438
405
  * If overridden, does not affect node which implements the identity, but is used in the peer configuration of other nodes.
439
406
  *
440
407
  * Will take priority over all calculated endpoints and `l4Endpoint` input.
441
- *
442
- * @schema
443
408
  */
444
- endpoints: Type.Default(Type.Array(Type.String()), []),
409
+ endpoints: z.string().array().default([]),
445
410
  },
446
411
 
447
412
  secrets: {
@@ -449,19 +414,15 @@ export const identity = defineUnit({
449
414
  * The private key of the WireGuard identity.
450
415
  *
451
416
  * If not provided, the key will be generated automatically.
452
- *
453
- * @schema
454
417
  */
455
- privateKey: Type.Optional(Type.String()),
418
+ privateKey: z.string().optional(),
456
419
 
457
420
  /**
458
421
  * The part of the pre-shared of the WireGuard identity.
459
422
  *
460
423
  * Will be generated automatically if not provided.
461
- *
462
- * @schema
463
424
  */
464
- presharedKeyPart: Type.Optional(Type.String()),
425
+ presharedKeyPart: z.string().optional(),
465
426
  },
466
427
 
467
428
  inputs: sharedPeerInputs,
@@ -473,8 +434,8 @@ export const identity = defineUnit({
473
434
 
474
435
  meta: {
475
436
  description: "The WireGuard identity with the public key.",
476
- primaryIcon: "simple-icons:wireguard",
477
- primaryIconColor: "#88171a",
437
+ icon: "simple-icons:wireguard",
438
+ iconColor: "#88171a",
478
439
  secondaryIcon: "mdi:account",
479
440
  category: "VPN",
480
441
  },
@@ -493,17 +454,13 @@ export const node = defineUnit({
493
454
  * The name of the namespace/deployment/statefulset where the WireGuard node will be deployed.
494
455
  *
495
456
  * By default, the name is `wg-${identity.name}`.
496
- *
497
- * @schema
498
457
  */
499
- appName: Type.Optional(Type.String()),
458
+ appName: z.string().optional(),
500
459
 
501
460
  /**
502
461
  * Whether to expose the WireGuard node to the outside world.
503
- *
504
- * @schema
505
462
  */
506
- external: Type.Default(Type.Boolean(), false),
463
+ external: z.boolean().default(false),
507
464
 
508
465
  /**
509
466
  * The policy to use for exposing the WireGuard node.
@@ -514,16 +471,24 @@ export const node = defineUnit({
514
471
  *
515
472
  * * By default, the `when-has-endpoint` policy is used.
516
473
  */
517
- exposePolicy: Type.Default(nodeExposePolicySchema, "when-has-endpoint"),
474
+ exposePolicy: nodeExposePolicySchema.default("when-has-endpoint"),
518
475
 
519
476
  /**
520
477
  * The extra specification of the container which runs the WireGuard node.
521
478
  *
522
479
  * Will override any overlapping fields.
480
+ */
481
+ containerSpec: z.record(z.string(), z.unknown()).optional(),
482
+
483
+ /**
484
+ * List of CIDR blocks that should be blocked from forwarding through this WireGuard node.
523
485
  *
524
- * @schema
486
+ * This prevents other peers from reaching these destination CIDRs while still allowing
487
+ * the peers in those CIDRs to access the internet and other allowed endpoints.
488
+ *
489
+ * Useful for peer isolation where you want to prevent cross-peer communication.
525
490
  */
526
- containerSpec: Type.Optional(Type.Record(Type.String(), Type.Any())),
491
+ forwardRestrictedIps: z.string().array().default([]),
527
492
  },
528
493
 
529
494
  inputs: {
@@ -567,8 +532,8 @@ export const node = defineUnit({
567
532
 
568
533
  meta: {
569
534
  description: "The WireGuard node running on the Kubernetes.",
570
- primaryIcon: "simple-icons:wireguard",
571
- primaryIconColor: "#88171a",
535
+ icon: "simple-icons:wireguard",
536
+ iconColor: "#88171a",
572
537
  secondaryIcon: "mdi:server",
573
538
  category: "VPN",
574
539
  },
@@ -587,10 +552,8 @@ export const config = defineUnit({
587
552
  * The name of the "default" interface where non-tunneled traffic should go.
588
553
  *
589
554
  * If not provided, the config will not respect `excludedIps`.
590
- *
591
- * @schema
592
555
  */
593
- defaultInterface: Type.Optional(Type.String()),
556
+ defaultInterface: z.string().optional(),
594
557
  },
595
558
 
596
559
  inputs: {
@@ -603,10 +566,10 @@ export const config = defineUnit({
603
566
  },
604
567
 
605
568
  meta: {
606
- displayName: "WireGuard Config",
569
+ title: "WireGuard Config",
607
570
  description: "Just the WireGuard configuration for the identity and peers.",
608
- primaryIcon: "simple-icons:wireguard",
609
- primaryIconColor: "#88171a",
571
+ icon: "simple-icons:wireguard",
572
+ iconColor: "#88171a",
610
573
  secondaryIcon: "mdi:settings",
611
574
  category: "VPN",
612
575
  },
@@ -634,10 +597,10 @@ export const configBundle = defineUnit({
634
597
  },
635
598
 
636
599
  meta: {
637
- displayName: "WireGuard Config Bundle",
600
+ title: "WireGuard Config Bundle",
638
601
  description: "The WireGuard configuration bundle for the identity and peers.",
639
- primaryIcon: "simple-icons:wireguard",
640
- primaryIconColor: "#88171a",
602
+ icon: "simple-icons:wireguard",
603
+ iconColor: "#88171a",
641
604
  secondaryIcon: "mdi:folder-settings-variant",
642
605
  category: "VPN",
643
606
  },