@highstate/library 0.19.1 → 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.
Files changed (66) hide show
  1. package/dist/highstate.library.msgpack +0 -0
  2. package/dist/index.js +2836 -3440
  3. package/package.json +12 -12
  4. package/src/abbreviations.ts +3 -0
  5. package/src/common/access-point.ts +19 -4
  6. package/src/common/files.ts +24 -17
  7. package/src/common/server.ts +19 -6
  8. package/src/databases/etcd.ts +141 -39
  9. package/src/databases/index.ts +8 -7
  10. package/src/databases/influxdb3.ts +103 -0
  11. package/src/databases/minio.ts +157 -0
  12. package/src/databases/mongodb.ts +122 -41
  13. package/src/databases/mysql.ts +172 -0
  14. package/src/databases/postgresql.ts +133 -40
  15. package/src/databases/redis.ts +118 -44
  16. package/src/databases/s3.ts +48 -127
  17. package/src/dns.ts +11 -7
  18. package/src/index.ts +3 -1
  19. package/src/k3s.ts +7 -0
  20. package/src/k8s/apps/etcd.ts +3 -3
  21. package/src/k8s/apps/gitea.ts +1 -1
  22. package/src/k8s/apps/grafana.ts +48 -0
  23. package/src/k8s/apps/index.ts +4 -2
  24. package/src/k8s/apps/mariadb.ts +7 -38
  25. package/src/k8s/apps/matrix-stack.ts +62 -0
  26. package/src/k8s/apps/minio.ts +38 -45
  27. package/src/k8s/apps/mongodb.ts +6 -38
  28. package/src/k8s/apps/portal.ts +27 -0
  29. package/src/k8s/apps/postgresql.ts +7 -41
  30. package/src/k8s/apps/refluxdb.ts +49 -0
  31. package/src/k8s/apps/remnawave.ts +15 -2
  32. package/src/k8s/apps/shared.ts +16 -15
  33. package/src/k8s/apps/traefik.ts +5 -0
  34. package/src/k8s/apps/valkey.ts +5 -5
  35. package/src/k8s/apps/vaultwarden.ts +2 -6
  36. package/src/k8s/apps/workload.ts +14 -11
  37. package/src/k8s/cert-manager.ts +22 -0
  38. package/src/k8s/cilium.ts +17 -2
  39. package/src/k8s/resources.ts +41 -9
  40. package/src/k8s/service.ts +6 -2
  41. package/src/k8s/shared.ts +49 -18
  42. package/src/k8s/workload.ts +59 -43
  43. package/src/network/address-space.ts +30 -7
  44. package/src/network/address.ts +13 -2
  45. package/src/network/endpoint-container.ts +235 -0
  46. package/src/network/endpoint-schema.ts +8 -0
  47. package/src/network/endpoint.ts +20 -39
  48. package/src/network/index.ts +1 -1
  49. package/src/network/subnet.ts +4 -2
  50. package/src/proxmox.ts +24 -7
  51. package/src/restic.ts +8 -2
  52. package/src/ssh.ts +52 -30
  53. package/src/talos.ts +8 -2
  54. package/src/third-party/cloudflare.ts +4 -4
  55. package/src/third-party/timeweb.ts +17 -3
  56. package/src/third-party/yandex.ts +198 -88
  57. package/src/tls.ts +22 -0
  58. package/src/utils.ts +16 -1
  59. package/src/wireguard.ts +362 -120
  60. package/LICENSE +0 -21
  61. package/dist/index.js.map +0 -1
  62. package/src/databases/mariadb.ts +0 -91
  63. package/src/databases/shared.ts +0 -67
  64. package/src/k8s/apps/kubernetes-dashboard.ts +0 -28
  65. package/src/k8s/apps/maybe.ts +0 -39
  66. package/src/network/dynamic-endpoint.ts +0 -43
package/src/wireguard.ts CHANGED
@@ -5,13 +5,15 @@ import {
5
5
  defineEntity,
6
6
  defineUnit,
7
7
  type EntityInput,
8
+ type EntityValue,
8
9
  genericNameSchema,
10
+ secretSchema,
9
11
  z,
10
12
  } from "@highstate/contract"
11
13
  import { pick } from "remeda"
12
14
  import { fileEntity } from "./common"
13
15
  import { serverEntity } from "./common/server"
14
- import { etcdEntity } from "./databases"
16
+ import { etcd } from "./databases"
15
17
  import { clusterEntity, networkInterfaceEntity, workloadEntity } from "./k8s"
16
18
  import {
17
19
  addressEntity,
@@ -25,14 +27,37 @@ import { toPatchArgs } from "./utils"
25
27
  export const backendSchema = z.enum(["wireguard", "amneziawg"])
26
28
 
27
29
  export type Backend = z.infer<typeof backendSchema>
30
+ export type AmneziaParameters = z.infer<typeof amneziaParametersSchema>
31
+
32
+ export const amneziaParametersSchema = z.object({
33
+ i1: z.string().optional(),
34
+ i2: z.string().optional(),
35
+ i3: z.string().optional(),
36
+ i4: z.string().optional(),
37
+ i5: z.string().optional(),
38
+
39
+ s1: z.number().optional(),
40
+ s2: z.number().optional(),
41
+ s3: z.number().optional(),
42
+ s4: z.number().optional(),
43
+
44
+ jc: z.number().optional(),
45
+ jmin: z.number().optional(),
46
+ jmax: z.number().optional(),
47
+
48
+ h1: z.string().optional(),
49
+ h2: z.string().optional(),
50
+ h3: z.string().optional(),
51
+ h4: z.string().optional(),
52
+ })
28
53
 
29
- const networkArgs = {
54
+ export const networkArgs = {
30
55
  /**
31
56
  * The backend to use for the WireGuard network.
32
57
  *
33
58
  * Possible values are:
34
59
  * - `wireguard` - the default backend;
35
- * - `amneziawg` - the censorship-resistant fork of WireGuard (NOT SUPPORTED YET).
60
+ * - `amneziawg` - the censorship-resistant fork of WireGuard.
36
61
  */
37
62
  backend: backendSchema.default("wireguard"),
38
63
 
@@ -51,8 +76,31 @@ const networkArgs = {
51
76
  * By default, IPv6 support is disabled.
52
77
  */
53
78
  ipv6: z.boolean().default(false),
79
+
80
+ /**
81
+ * The extra parameters for the amneziawg backend.
82
+ */
83
+ amnezia: amneziaParametersSchema.optional(),
54
84
  }
55
85
 
86
+ const configSharedArgs = $args({
87
+ /**
88
+ * The filter to use when selecting endpoints for each peer.
89
+ *
90
+ * The first matching endpoint will be used.
91
+ *
92
+ * If not provided, all endpoints will be considered.
93
+ */
94
+ peerEndpointFilter: z.string().optional().meta({ language: "javascript" }),
95
+
96
+ /**
97
+ * Whether to include the `ListenPort` in the generated config.
98
+ *
99
+ * By default, is `false` because in most cases the config is used for peers which don't listen for incoming connections.
100
+ */
101
+ listen: z.boolean().default(false),
102
+ })
103
+
56
104
  /**
57
105
  * The entity representing the WireGuard network configuration.
58
106
  *
@@ -62,47 +110,139 @@ export const networkEntity = defineEntity({
62
110
  type: "wireguard.network.v1",
63
111
 
64
112
  schema: z.object(networkArgs),
113
+
114
+ meta: {
115
+ color: "#88171a",
116
+ title: "WireGuard Network",
117
+ icon: "simple-icons:wireguard",
118
+ iconColor: "#88171a",
119
+ secondaryIcon: "mdi:local-area-network-connect",
120
+ },
65
121
  })
66
122
 
67
123
  export const nodeExposePolicySchema = z.enum(["always", "when-has-endpoint", "never"])
68
124
 
125
+ export const feedDisplayInfoSchema = z.object({
126
+ /**
127
+ * The display title of the tunnel.
128
+ */
129
+ title: z.string(),
130
+
131
+ /**
132
+ * The display description of the tunnel.
133
+ */
134
+ description: z.string().optional(),
135
+
136
+ /**
137
+ * The display icon URL of the tunnel.
138
+ *
139
+ * Must only be `data:` URL with SVG image.
140
+ */
141
+ iconUrl: z.url().optional(),
142
+ })
143
+
144
+ export const feedMetadataSchema = z.object({
145
+ /**
146
+ * The ID of the tunnel in the feed.
147
+ */
148
+ id: z.string(),
149
+
150
+ /**
151
+ * The suggested name of the interface for the tunnel.
152
+ */
153
+ name: genericNameSchema,
154
+
155
+ /**
156
+ * Whether the tunnel should be enabled by the client.
157
+ */
158
+ enabled: z.boolean().default(false),
159
+
160
+ /**
161
+ * Whether the tunnel state must be forced by the client.
162
+ */
163
+ forced: z.boolean().default(false),
164
+
165
+ /**
166
+ * Whether the tunnel is exclusive and should not be enabled with other tunnels.
167
+ */
168
+ exclusive: z.boolean().default(false),
169
+
170
+ /**
171
+ * The display information of the tunnel.
172
+ */
173
+ displayInfo: feedDisplayInfoSchema,
174
+ })
175
+
69
176
  export const peerEntity = defineEntity({
70
177
  type: "wireguard.peer.v1",
71
178
 
72
179
  includes: {
73
180
  /**
74
- * The endpoints where the WireGuard peer can be reached.
181
+ * The network to which the WireGuard peer belongs.
182
+ *
183
+ * Holds shared configuration for all identities, peers, and nodes.
75
184
  */
76
- endpoints: {
77
- entity: l4EndpointEntity,
185
+ network: {
186
+ entity: networkEntity,
187
+ required: false,
188
+ },
189
+
190
+ /**
191
+ * The addresses of the WireGuard interface.
192
+ */
193
+ addresses: {
194
+ entity: addressEntity,
78
195
  multiple: true,
196
+ required: false,
79
197
  },
80
- },
81
198
 
82
- schema: z.object({
83
199
  /**
84
- * The name of the WireGuard peer.
200
+ * The list of DNS servers to setup for the interface connected to the WireGuard peer.
85
201
  */
86
- name: genericNameSchema,
202
+ dns: {
203
+ entity: addressEntity,
204
+ multiple: true,
205
+ required: false,
206
+ },
87
207
 
88
208
  /**
89
- * The network to which the WireGuard peer belongs.
209
+ * The allowed subnets of the WireGuard peer.
90
210
  *
91
- * Holds shared configuration for all identities, peers, and nodes.
211
+ * Will be used to configure the `AllowedIPs` of the peer.
92
212
  */
93
- network: networkEntity.schema.optional(),
213
+ allowedSubnets: {
214
+ entity: subnetEntity,
215
+ multiple: true,
216
+ required: false,
217
+ },
94
218
 
95
219
  /**
96
- * The addresses of the WireGuard interface.
220
+ * The endpoints where the WireGuard peer can be reached.
97
221
  */
98
- addresses: addressEntity.schema.array(),
222
+ endpoints: {
223
+ entity: l4EndpointEntity,
224
+ multiple: true,
225
+ required: false,
226
+ },
99
227
 
100
228
  /**
101
- * The allowed subnets of the WireGuard peer.
229
+ * The peers which are relayed through this peer.
102
230
  *
103
- * Will be used to configure the `AllowedIPs` of the peer.
231
+ * All their allowed IPs will be added to this peer's allowed IPs
232
+ * and will be used to setup routing for all other peers except the relayed ones.
104
233
  */
105
- allowedSubnets: subnetEntity.schema.array(),
234
+ relayedPeers: {
235
+ entity: () => peerEntity,
236
+ multiple: true,
237
+ required: false,
238
+ },
239
+ },
240
+
241
+ schema: z.object({
242
+ /**
243
+ * The name of the WireGuard peer.
244
+ */
245
+ name: genericNameSchema,
106
246
 
107
247
  /**
108
248
  * The public key of the WireGuard peer.
@@ -116,19 +256,14 @@ export const peerEntity = defineEntity({
116
256
  *
117
257
  * Will be ignored if both peers have `presharedKeyPart` set.
118
258
  */
119
- presharedKey: z.string().optional(),
259
+ presharedKey: secretSchema(z.string()).optional(),
120
260
 
121
261
  /**
122
262
  * The pre-shared key part of the WireGuard peer.
123
263
  *
124
264
  * If both peers have `presharedKeyPart` set, their `presharedKey` will be calculated as sha256 of the two parts.
125
265
  */
126
- presharedKeyPart: z.string().optional(),
127
-
128
- /**
129
- * The list of DNS servers to setup for the interface connected to the WireGuard peer.
130
- */
131
- dns: addressEntity.schema.array(),
266
+ presharedKeyPart: secretSchema(z.string()).optional(),
132
267
 
133
268
  /**
134
269
  * The port where the WireGuard peer is listening.
@@ -147,18 +282,18 @@ export const peerEntity = defineEntity({
147
282
  persistentKeepalive: z.number().int().nonnegative().default(0),
148
283
 
149
284
  /**
150
- * The peers which are relayed through this peer.
285
+ * The wg-feed metadata of the WireGuard peer.
151
286
  *
152
- * All their allowed IPs will be added to this peer's allowed IPs
153
- * and will be used to setup routing for all other peers except the relayed ones.
287
+ * Will be used in the config referencing this peer (not the peer itself).
154
288
  */
155
- get relayedPeers() {
156
- return peerEntity.schema.array().optional()
157
- },
289
+ feedMetadata: feedMetadataSchema.optional(),
158
290
  }),
159
291
 
160
292
  meta: {
161
293
  color: "#673AB7",
294
+ icon: "simple-icons:wireguard",
295
+ secondaryIcon: "mdi:badge-account-horizontal",
296
+ iconColor: "#88171a",
162
297
  },
163
298
  })
164
299
 
@@ -176,50 +311,17 @@ export const identityEntity = defineEntity({
176
311
  /**
177
312
  * The private key of the WireGuard identity.
178
313
  */
179
- privateKey: z.string(),
314
+ privateKey: secretSchema(z.string()),
180
315
  }),
181
316
 
182
317
  meta: {
183
318
  color: "#F44336",
319
+ icon: "simple-icons:wireguard",
320
+ secondaryIcon: "mdi:account",
321
+ iconColor: "#88171a",
184
322
  },
185
323
  })
186
324
 
187
- export const feedDisplayInfoSchema = z.object({
188
- /**
189
- * The display title of the tunnel.
190
- */
191
- title: z.string(),
192
-
193
- /**
194
- * The display description of the tunnel.
195
- */
196
- description: z.string().optional(),
197
-
198
- /**
199
- * The display icon URL of the tunnel.
200
- *
201
- * Must only be `data:` URL with SVG image.
202
- */
203
- iconUrl: z.url().optional(),
204
- })
205
-
206
- export const feedMetadataSchema = z.object({
207
- /**
208
- * The ID of the tunnel in the feed.
209
- */
210
- id: z.string(),
211
-
212
- /**
213
- * The suggested name of the interface for the tunnel.
214
- */
215
- name: genericNameSchema,
216
-
217
- /**
218
- * The display information of the tunnel.
219
- */
220
- displayInfo: feedDisplayInfoSchema,
221
- })
222
-
223
325
  export const configEntity = defineEntity({
224
326
  type: "wireguard.config.v1",
225
327
 
@@ -238,19 +340,30 @@ export const configEntity = defineEntity({
238
340
  */
239
341
  feedMetadata: feedMetadataSchema.optional(),
240
342
  }),
343
+
344
+ meta: {
345
+ color: "#455A64",
346
+ title: "WireGuard Config",
347
+ icon: "simple-icons:wireguard",
348
+ iconColor: "#88171a",
349
+ secondaryIcon: "mdi:settings",
350
+ },
241
351
  })
242
352
 
243
- export type Network = z.infer<typeof networkEntity.schema>
244
- export type Identity = z.infer<typeof identityEntity.schema>
245
- export type Peer = z.infer<typeof peerEntity.schema>
353
+ export type Network = EntityValue<typeof networkEntity>
354
+ export type Identity = EntityValue<typeof identityEntity>
355
+ export type Peer = EntityValue<typeof peerEntity>
246
356
  export type NodeExposePolicy = z.infer<typeof nodeExposePolicySchema>
247
- export type Config = z.infer<typeof configEntity.schema>
357
+ export type Config = EntityValue<typeof configEntity>
248
358
 
249
359
  export type NetworkInput = EntityInput<typeof networkEntity>
250
360
  export type IdentityInput = EntityInput<typeof identityEntity>
251
361
  export type PeerInput = EntityInput<typeof peerEntity>
252
362
  export type ConfigInput = EntityInput<typeof configEntity>
253
363
 
364
+ export type FeedDisplayInfo = z.infer<typeof feedDisplayInfoSchema>
365
+ export type FeedMetadata = z.infer<typeof feedMetadataSchema>
366
+
254
367
  /**
255
368
  * Holds the shared configuration for WireGuard identities, peers, and nodes.
256
369
  */
@@ -276,6 +389,35 @@ export const network = defineUnit({
276
389
  },
277
390
  })
278
391
 
392
+ const sharedFeedArgs = $args({
393
+ /**
394
+ * The metadata to include in the wg-feed for this config.
395
+ */
396
+ feedMetadata: z
397
+ .discriminatedUnion("provided", [
398
+ z.object({
399
+ /**
400
+ * Whether this config is enabled for upload to wg-feed.
401
+ *
402
+ * You must fill the metadata fields.
403
+ */
404
+ provided: z.literal("yes"),
405
+
406
+ ...pick(feedMetadataSchema.shape, ["id", "name", "enabled", "forced", "exclusive"]),
407
+
408
+ // Highstate does not support nested objects in UI
409
+ ...feedDisplayInfoSchema.shape,
410
+ }),
411
+ z.object({
412
+ /**
413
+ * Whether this config is enabled for upload to wg-feed.
414
+ */
415
+ provided: z.literal("no"),
416
+ }),
417
+ ])
418
+ .prefault({ provided: "no" }),
419
+ })
420
+
279
421
  const sharedPeerArgs = $args({
280
422
  /**
281
423
  * The name of the WireGuard peer.
@@ -363,6 +505,8 @@ const sharedPeerArgs = $args({
363
505
  * If set to 0, keepalive is disabled.
364
506
  */
365
507
  persistentKeepalive: z.number().int().nonnegative().default(0),
508
+
509
+ ...sharedFeedArgs,
366
510
  })
367
511
 
368
512
  const sharedPeerInputs = $inputs({
@@ -589,6 +733,14 @@ export const nodeK8s = defineUnit({
589
733
  * By default, is false.
590
734
  */
591
735
  allowClusterPods: z.boolean().default(false),
736
+
737
+ /**
738
+ * Whether to drop all traffic from the interface using ip rule with priority 100.
739
+ *
740
+ * This is useful for preventing the traffic leaks before upstream node is attached via `downstreamInterface` input.
741
+ * They will add their own ip rule with <100 priority which allows traffic from the interface.
742
+ */
743
+ lockdownUpstream: z.boolean().default(false),
592
744
  },
593
745
 
594
746
  inputs: {
@@ -600,7 +752,12 @@ export const nodeK8s = defineUnit({
600
752
  required: false,
601
753
  },
602
754
 
603
- interface: {
755
+ downstreamInterface: {
756
+ entity: networkInterfaceEntity,
757
+ required: false,
758
+ },
759
+
760
+ fallbackInterface: {
604
761
  entity: networkInterfaceEntity,
605
762
  required: false,
606
763
  },
@@ -640,6 +797,128 @@ export const nodeK8s = defineUnit({
640
797
  },
641
798
  })
642
799
 
800
+ /**
801
+ * The wg-feed daemon deployed in the Kubernetes cluster.
802
+ *
803
+ * It runs `wg-feed-daemon` which continuously reconciles local WireGuard tunnels
804
+ * from one or more wg-feed Setup URLs.
805
+ */
806
+ export const nodeFeedK8s = defineUnit({
807
+ type: "wireguard.node.feed.k8s.v1",
808
+
809
+ args: {
810
+ /**
811
+ * The name of the namespace/deployment/statefulset where the daemon will be deployed.
812
+ *
813
+ * By default, the name is `wg-${identity.name}`.
814
+ */
815
+ appName: z.string().optional(),
816
+
817
+ /**
818
+ * Whether to expose the WireGuard node to the outside world.
819
+ */
820
+ external: z.boolean().default(false),
821
+
822
+ /**
823
+ * Whether to create a Service and allow ingress.
824
+ */
825
+ expose: z.boolean().default(false),
826
+
827
+ /**
828
+ * The UDP port that will be exposed by the Service.
829
+ *
830
+ * This is required for consumers that need to know the port ahead of time.
831
+ */
832
+ listenPort: z.number().default(51820),
833
+
834
+ /**
835
+ * The name of the WireGuard interface to export as `interface` output.
836
+ *
837
+ * Note: wg-feed may manage multiple tunnels.
838
+ * This output is a convenience handle for downstream units.
839
+ */
840
+ interfaceName: z.string().default("wg0"),
841
+
842
+ /**
843
+ * List of CIDR blocks that should be blocked from forwarding through this WireGuard node.
844
+ *
845
+ * This prevents other peers from reaching these destination CIDRs while still allowing
846
+ * the peers in those CIDRs to access the internet and other allowed endpoints.
847
+ *
848
+ * Useful for peer isolation where you want to prevent cross-peer communication.
849
+ */
850
+ forwardRestrictedSubnets: z.string().array().default([]),
851
+
852
+ /**
853
+ * Whether to drop all traffic from the interface using ip rule with priority 100.
854
+ *
855
+ * This is useful for preventing the traffic leaks before upstream node is attached via `downstreamInterface` input.
856
+ * They will add their own ip rule with <100 priority which allows traffic from the interface.
857
+ */
858
+ lockdownUpstream: z.boolean().default(false),
859
+
860
+ /**
861
+ * The extra specification of the container which runs the wg-feed daemon.
862
+ *
863
+ * Will override any overlapping fields.
864
+ */
865
+ containerSpec: z.record(z.string(), z.unknown()).optional(),
866
+ },
867
+
868
+ inputs: {
869
+ k8sCluster: clusterEntity,
870
+ endpoints: {
871
+ entity: l7EndpointEntity,
872
+ multiple: true,
873
+ required: false,
874
+ },
875
+
876
+ peer: {
877
+ entity: peerEntity,
878
+ required: false,
879
+ },
880
+
881
+ workload: {
882
+ entity: workloadEntity,
883
+ required: false,
884
+ },
885
+
886
+ interface: {
887
+ entity: networkInterfaceEntity,
888
+ required: false,
889
+ },
890
+ },
891
+
892
+ outputs: {
893
+ workload: {
894
+ entity: workloadEntity,
895
+ },
896
+
897
+ interface: {
898
+ entity: networkInterfaceEntity,
899
+ },
900
+
901
+ peer: {
902
+ entity: peerEntity,
903
+ required: false,
904
+ },
905
+ },
906
+
907
+ meta: {
908
+ title: "WireGuard Feed Kubernetes Node",
909
+ description: "The wg-feed daemon deployed in the Kubernetes cluster.",
910
+ icon: "simple-icons:wireguard",
911
+ iconColor: "#88171a",
912
+ secondaryIcon: "devicon:kubernetes",
913
+ category: "VPN",
914
+ },
915
+
916
+ source: {
917
+ package: "@highstate/wireguard",
918
+ path: "node.feed.k8s",
919
+ },
920
+ })
921
+
643
922
  /**
644
923
  * The WireGuard node deployed on a server using wg-quick systemd service.
645
924
  */
@@ -671,6 +950,8 @@ export const node = defineUnit({
671
950
  */
672
951
  enableMasquerade: z.boolean().default(true),
673
952
 
953
+ ...configSharedArgs,
954
+
674
955
  /**
675
956
  * Script to run before bringing up the interface.
676
957
  */
@@ -711,12 +992,6 @@ export const node = defineUnit({
711
992
  entity: peerEntity,
712
993
  required: false,
713
994
  },
714
-
715
- endpoints: {
716
- entity: l4EndpointEntity,
717
- required: false,
718
- multiple: true,
719
- },
720
995
  },
721
996
 
722
997
  meta: {
@@ -733,17 +1008,6 @@ export const node = defineUnit({
733
1008
  },
734
1009
  })
735
1010
 
736
- const sharedArgs = $args({
737
- /**
738
- * The filter to use when selecting endpoints for each peer.
739
- *
740
- * The first matching endpoint will be used.
741
- *
742
- * If not provided, all endpoints will be considered.
743
- */
744
- peerEndpointFilter: z.string().optional().meta({ language: "javascript" }),
745
- })
746
-
747
1011
  /**
748
1012
  * Just the WireGuard configuration for the identity and peers.
749
1013
  */
@@ -751,34 +1015,8 @@ export const config = defineUnit({
751
1015
  type: "wireguard.config.v1",
752
1016
 
753
1017
  args: {
754
- ...sharedArgs,
755
-
756
- /**
757
- * The metadata to include in the wg-feed for this config.
758
- */
759
- feedMetadata: z
760
- .discriminatedUnion("enabled", [
761
- z.object({
762
- /**
763
- * Whether this config is enabled for upload to wg-feed.
764
- *
765
- * You must fill the metadata fields.
766
- */
767
- enabled: z.literal("true"),
768
-
769
- ...pick(feedMetadataSchema.shape, ["id", "name"]),
770
-
771
- // Highstate does not support nested objects in UI
772
- ...feedDisplayInfoSchema.shape,
773
- }),
774
- z.object({
775
- /**
776
- * Whether this config is enabled for upload to wg-feed.
777
- */
778
- enabled: z.literal("false"),
779
- }),
780
- ])
781
- .prefault({ enabled: "false" }),
1018
+ ...configSharedArgs,
1019
+ ...sharedFeedArgs,
782
1020
  },
783
1021
 
784
1022
  inputs: {
@@ -788,6 +1026,10 @@ export const config = defineUnit({
788
1026
  multiple: true,
789
1027
  required: false,
790
1028
  },
1029
+ network: {
1030
+ entity: networkEntity,
1031
+ required: false,
1032
+ },
791
1033
  },
792
1034
 
793
1035
  outputs: {
@@ -815,7 +1057,7 @@ export const configBundle = defineUnit({
815
1057
  type: "wireguard.config-bundle.v1",
816
1058
 
817
1059
  args: {
818
- ...sharedArgs,
1060
+ ...configSharedArgs,
819
1061
  },
820
1062
 
821
1063
  inputs: {
@@ -909,7 +1151,7 @@ export const feed = defineUnit({
909
1151
  },
910
1152
 
911
1153
  inputs: {
912
- etcd: etcdEntity,
1154
+ etcd: etcd.connectionEntity,
913
1155
  serverEndpoints: {
914
1156
  entity: l4EndpointEntity,
915
1157
  required: false,
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Exeteres
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.