@highstate/wireguard 0.16.0 → 0.18.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.
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "sourceHashes": {
3
- "./dist/network/index.js": 4207313116,
4
- "./dist/identity/index.js": 11316155,
5
- "./dist/config/index.js": 2931949109,
6
- "./dist/config-bundle/index.js": 943827142,
7
- "./dist/feed/index.js": 3874422537,
8
- "./dist/node/index.js": 2641283547,
9
- "./dist/node.k8s/index.js": 232582473,
10
- "./dist/peer/index.js": 3842560375,
11
- "./dist/peer-patch/index.js": 2928862803
3
+ "./dist/network/index.js": 2729064733,
4
+ "./dist/identity/index.js": 1488982650,
5
+ "./dist/config/index.js": 4138551284,
6
+ "./dist/config-bundle/index.js": 2428967255,
7
+ "./dist/feed/index.js": 2728646360,
8
+ "./dist/node/index.js": 3305271322,
9
+ "./dist/node.k8s/index.js": 3947569897,
10
+ "./dist/peer/index.js": 3177474230,
11
+ "./dist/peer-patch/index.js": 4143865746
12
12
  }
13
13
  }
@@ -157,6 +157,12 @@ if (workload instanceof ExposableWorkload) {
157
157
  });
158
158
  }
159
159
  }
160
+ if (args.allowClusterPods) {
161
+ new NetworkPolicy("allow-egress-to-cluster-pods", {
162
+ namespace,
163
+ egressRule: { toClusterPods: true }
164
+ });
165
+ }
160
166
  var endpoints = await toPromise(
161
167
  workload instanceof ExposableWorkload ? workload.optionalService.apply((service) => service?.endpoints) : []
162
168
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../assets/images.json","../../src/node.k8s/index.ts"],"names":["wireguard"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"wireguard\": {\n \"name\": \"docker.io/linuxserver/wireguard\",\n \"tag\": \"latest\",\n \"image\": \"docker.io/linuxserver/wireguard:latest@sha256:7792dcef56c51e6b4d499a209e980ed74309bf3bee6af12168ea02bf289eddd9\"\n }\n}\n","import { createAddressSpace, l4EndpointToString, subnetToString } from \"@highstate/common\"\nimport { ExposableWorkload, Namespace, NetworkPolicy, Secret, Workload } from \"@highstate/k8s\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport * as images from \"../../assets/images.json\"\nimport { generateIdentityConfig, isExitNode, shouldExpose } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.nodeK8s)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst identityName = identity.peer.name.replaceAll(\".\", \"-\")\nconst appName = args.appName ?? `wg-${identityName}`\n\nconst namespace = Namespace.createOrPatch(appName, {\n cluster: inputs.k8sCluster,\n resource: inputs.workload ?? inputs.interface?.workload,\n\n metadata: {\n labels: {\n \"pod-security.kubernetes.io/enforce\": \"privileged\",\n },\n },\n})\n\nconst downstreamInterface = await toPromise(inputs.interface)\n\nconst preUp: string[] = []\n\nconst postUp: string[] = [\n // enable masquerading for all traffic going out of the WireGuard node\n // TODO: consider adding more specific and restrictive rules\n \"iptables -t nat -A POSTROUTING -j MASQUERADE\",\n]\n\nconst preDown: string[] = [\n // remove the masquerading rule\n \"iptables -t nat -D POSTROUTING -j MASQUERADE\",\n]\n\n// add forwarding restrictions for specified CIDRs\nfor (const restrictedCidr of args.forwardRestrictedSubnets) {\n // block forwarding to restricted CIDR (prevents other peers from reaching these destinations)\n postUp.push(`iptables -I FORWARD -d ${restrictedCidr} -j DROP`)\n preDown.push(`iptables -D FORWARD -d ${restrictedCidr} -j DROP`)\n}\n\nif (downstreamInterface) {\n // wait until the interface is up\n preUp.push(`while ! ip link show ${downstreamInterface.name} | grep -q 'UP' ; do sleep 1; done`)\n\n // remove the default rule to route all non-encapsulated traffic to upstream wireguard interface\n postUp.push(\"ip rule del not from all fwmark 0xca6c lookup 51820\")\n\n // add a rule to route all downstream traffic to the upstream wireguard interface\n postUp.push(\"ip rule add from all fwmark 0x1 lookup 51820\")\n\n // mark all downstream traffic with 0x1\n postUp.push(\n `iptables -t mangle -A PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all downstream traffic to the upstream wireguard interface\n preDown.push(\n `iptables -t mangle -D PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all non-encapsulated traffic to upstream wireguard interface\n preDown.push(\"ip rule del from all fwmark 0x1 lookup 51820\")\n}\n\nconst interfaceName = identityName.substring(0, 15) // linux kernel limit\n\n// if there is a workload, we will use a different port to prevent potential conflicts\nconst containerPort = (inputs.workload ?? inputs.interface?.workload) ? 51821 : 51820\n\nconst configSecret = Secret.create(appName, {\n namespace,\n\n stringData: {\n [`${interfaceName}.conf`]: generateIdentityConfig({\n identity,\n peers,\n listenPort: containerPort,\n preUp,\n postUp,\n preDown,\n cluster: await toPromise(inputs.k8sCluster),\n }),\n },\n})\n\nconst workload = await toPromise(\n Workload.createOrPatchGeneric(appName, {\n defaultType: \"Deployment\",\n namespace,\n\n existing: inputs.workload ?? inputs.interface?.workload,\n\n container: deepmerge(\n {\n image: images.wireguard.image,\n\n environment: {\n PUID: \"1000\",\n PGID: \"1000\",\n TZ: \"Etc/UTC\",\n },\n\n securityContext: {\n capabilities: {\n add: [\"NET_ADMIN\"],\n },\n },\n\n port: {\n containerPort,\n protocol: \"UDP\",\n },\n\n volumeMount: {\n volume: configSecret,\n mountPath: \"/config/wg_confs\",\n },\n },\n args.containerSpec ?? {},\n ),\n\n service: shouldExpose(identity, args.exposePolicy)\n ? {\n external: args.external,\n port: {\n port: identity.peer.listenPort ?? 51820,\n targetPort: containerPort,\n protocol: \"UDP\",\n nodePort: args.external ? identity.peer.listenPort : undefined,\n },\n }\n : undefined,\n }),\n)\n\nif (shouldExpose(identity, args.exposePolicy) && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-wireguard-ingress\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow encapsulated WireGuard traffic to the node from anywhere.\",\n\n ingressRule: {\n fromAll: true,\n },\n })\n}\n\nif (isExitNode(identity.peer) && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-all-egress\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow all egress traffic from the WireGuard node since it is an exit node.\",\n\n egressRule: {\n toAll: true,\n },\n })\n}\n\nconst pureAllowedSpace = createAddressSpace({\n included: identity.peer.allowedSubnets,\n excluded: identity.peer.addresses,\n})\n\n// allow egress to the subnets that are not part of the peer's addresses\nif (pureAllowedSpace.subnets.length > 0 && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-egress-to-allowed-subnets\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow egress traffic from the WireGuard node to its allowed subnets.\",\n\n egressRule: {\n toCidrs: pureAllowedSpace.subnets.map(subnetToString),\n },\n })\n}\n\nif (workload instanceof ExposableWorkload) {\n for (const peer of peers) {\n if (!peer.endpoints.length) {\n continue\n }\n\n new NetworkPolicy(`allow-egress-to-peer-${peer.name}`, {\n namespace,\n selector: workload.spec.selector,\n\n description: `Allow egress traffic from the WireGuard node to the endpoints of the peer \"${peer.name}\".`,\n\n egressRule: {\n toEndpoints: peer.endpoints,\n },\n })\n }\n}\n\nconst endpoints = await toPromise(\n workload instanceof ExposableWorkload\n ? workload.optionalService.apply(service => service?.endpoints!)\n : [],\n)\n\nexport default outputs({\n workload: workload.entity,\n\n interface: {\n name: interfaceName,\n workload: workload.entity,\n },\n\n peer: {\n ...identity.peer,\n endpoints,\n },\n\n $statusFields: {\n endpoints: endpoints.map(l4EndpointToString),\n },\n\n $terminals: [workload.terminal],\n})\n"]}
1
+ {"version":3,"sources":["../../assets/images.json","../../src/node.k8s/index.ts"],"names":["wireguard"],"mappings":";;;;;;;;;AACE,IAAA,SAAA,GAAa;AAAA,EAGX,KAAA,EAAS;AACX,CAAA;;;ACGF,IAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAQ,GAAI,OAAA,CAAQA,YAAU,OAAO,CAAA;AAE3D,IAAM,EAAE,QAAA,EAAU,KAAA,EAAM,GAAI,MAAM,UAAU,MAAM,CAAA;AAElD,IAAM,eAAe,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,KAAK,GAAG,CAAA;AAC3D,IAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,CAAA,GAAA,EAAM,YAAY,CAAA,CAAA;AAElD,IAAM,SAAA,GAAY,SAAA,CAAU,aAAA,CAAc,OAAA,EAAS;AAAA,EACjD,SAAS,MAAA,CAAO,UAAA;AAAA,EAChB,QAAA,EAAU,MAAA,CAAO,QAAA,IAAY,MAAA,CAAO,SAAA,EAAW,QAAA;AAAA,EAE/C,QAAA,EAAU;AAAA,IACR,MAAA,EAAQ;AAAA,MACN,oCAAA,EAAsC;AAAA;AACxC;AAEJ,CAAC,CAAA;AAED,IAAM,mBAAA,GAAsB,MAAM,SAAA,CAAU,MAAA,CAAO,SAAS,CAAA;AAE5D,IAAM,QAAkB,EAAC;AAEzB,IAAM,MAAA,GAAmB;AAAA;AAAA;AAAA,EAGvB;AACF,CAAA;AAEA,IAAM,OAAA,GAAoB;AAAA;AAAA,EAExB;AACF,CAAA;AAGA,KAAA,MAAW,cAAA,IAAkB,KAAK,wBAAA,EAA0B;AAE1D,EAAA,MAAA,CAAO,IAAA,CAAK,CAAA,uBAAA,EAA0B,cAAc,CAAA,QAAA,CAAU,CAAA;AAC9D,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,uBAAA,EAA0B,cAAc,CAAA,QAAA,CAAU,CAAA;AACjE;AAEA,IAAI,mBAAA,EAAqB;AAEvB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,qBAAA,EAAwB,mBAAA,CAAoB,IAAI,CAAA,kCAAA,CAAoC,CAAA;AAG/F,EAAA,MAAA,CAAO,KAAK,qDAAqD,CAAA;AAGjE,EAAA,MAAA,CAAO,KAAK,8CAA8C,CAAA;AAG1D,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,CAAA,oCAAA,EAAuC,oBAAoB,IAAI,CAAA,uBAAA;AAAA,GACjE;AAGA,EAAA,OAAA,CAAQ,IAAA;AAAA,IACN,CAAA,oCAAA,EAAuC,oBAAoB,IAAI,CAAA,uBAAA;AAAA,GACjE;AAGA,EAAA,OAAA,CAAQ,KAAK,8CAA8C,CAAA;AAC7D;AAEA,IAAM,aAAA,GAAgB,YAAA,CAAa,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA;AAGlD,IAAM,gBAAiB,MAAA,CAAO,QAAA,IAAY,MAAA,CAAO,SAAA,EAAW,WAAY,KAAA,GAAQ,KAAA;AAEhF,IAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAO,OAAA,EAAS;AAAA,EAC1C,SAAA;AAAA,EAEA,UAAA,EAAY;AAAA,IACV,CAAC,CAAA,EAAG,aAAa,CAAA,KAAA,CAAO,GAAG,sBAAA,CAAuB;AAAA,MAChD,QAAA;AAAA,MACA,KAAA;AAAA,MACA,UAAA,EAAY,aAAA;AAAA,MACZ,KAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA,EAAS,MAAM,SAAA,CAAU,MAAA,CAAO,UAAU;AAAA,KAC3C;AAAA;AAEL,CAAC,CAAA;AAED,IAAM,WAAW,MAAM,SAAA;AAAA,EACrB,QAAA,CAAS,qBAAqB,OAAA,EAAS;AAAA,IACrC,WAAA,EAAa,YAAA;AAAA,IACb,SAAA;AAAA,IAEA,QAAA,EAAU,MAAA,CAAO,QAAA,IAAY,MAAA,CAAO,SAAA,EAAW,QAAA;AAAA,IAE/C,SAAA,EAAW,SAAA;AAAA,MACT;AAAA,QACE,OAAc,SAAA,CAAU,KAAA;AAAA,QAExB,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,EAAA,EAAI;AAAA,SACN;AAAA,QAEA,eAAA,EAAiB;AAAA,UACf,YAAA,EAAc;AAAA,YACZ,GAAA,EAAK,CAAC,WAAW;AAAA;AACnB,SACF;AAAA,QAEA,IAAA,EAAM;AAAA,UACJ,aAAA;AAAA,UACA,QAAA,EAAU;AAAA,SACZ;AAAA,QAEA,WAAA,EAAa;AAAA,UACX,MAAA,EAAQ,YAAA;AAAA,UACR,SAAA,EAAW;AAAA;AACb,OACF;AAAA,MACA,IAAA,CAAK,iBAAiB;AAAC,KACzB;AAAA,IAEA,OAAA,EAAS,YAAA,CAAa,QAAA,EAAU,IAAA,CAAK,YAAY,CAAA,GAC7C;AAAA,MACE,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,QAAA,CAAS,IAAA,CAAK,UAAA,IAAc,KAAA;AAAA,QAClC,UAAA,EAAY,aAAA;AAAA,QACZ,QAAA,EAAU,KAAA;AAAA,QACV,QAAA,EAAU,IAAA,CAAK,QAAA,GAAW,QAAA,CAAS,KAAK,UAAA,GAAa;AAAA;AACvD,KACF,GACA;AAAA,GACL;AACH,CAAA;AAEA,IAAI,aAAa,QAAA,EAAU,IAAA,CAAK,YAAY,CAAA,IAAK,oBAAoB,iBAAA,EAAmB;AACtF,EAAA,IAAI,cAAc,yBAAA,EAA2B;AAAA,IAC3C,SAAA;AAAA,IACA,QAAA,EAAU,SAAS,IAAA,CAAK,QAAA;AAAA,IAExB,WAAA,EAAa,iEAAA;AAAA,IAEb,WAAA,EAAa;AAAA,MACX,OAAA,EAAS;AAAA;AACX,GACD,CAAA;AACH;AAEA,IAAI,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA,IAAK,oBAAoB,iBAAA,EAAmB;AACtE,EAAA,IAAI,cAAc,kBAAA,EAAoB;AAAA,IACpC,SAAA;AAAA,IACA,QAAA,EAAU,SAAS,IAAA,CAAK,QAAA;AAAA,IAExB,WAAA,EAAa,4EAAA;AAAA,IAEb,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA;AACT,GACD,CAAA;AACH;AAEA,IAAM,mBAAmB,kBAAA,CAAmB;AAAA,EAC1C,QAAA,EAAU,SAAS,IAAA,CAAK,cAAA;AAAA,EACxB,QAAA,EAAU,SAAS,IAAA,CAAK;AAC1B,CAAC,CAAA;AAGD,IAAI,gBAAA,CAAiB,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,oBAAoB,iBAAA,EAAmB;AAChF,EAAA,IAAI,cAAc,iCAAA,EAAmC;AAAA,IACnD,SAAA;AAAA,IACA,QAAA,EAAU,SAAS,IAAA,CAAK,QAAA;AAAA,IAExB,WAAA,EAAa,sEAAA;AAAA,IAEb,UAAA,EAAY;AAAA,MACV,OAAA,EAAS,gBAAA,CAAiB,OAAA,CAAQ,GAAA,CAAI,cAAc;AAAA;AACtD,GACD,CAAA;AACH;AAEA,IAAI,oBAAoB,iBAAA,EAAmB;AACzC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ;AAC1B,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,aAAA,CAAc,CAAA,qBAAA,EAAwB,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI;AAAA,MACrD,SAAA;AAAA,MACA,QAAA,EAAU,SAAS,IAAA,CAAK,QAAA;AAAA,MAExB,WAAA,EAAa,CAAA,2EAAA,EAA8E,IAAA,CAAK,IAAI,CAAA,EAAA,CAAA;AAAA,MAEpG,UAAA,EAAY;AAAA,QACV,aAAa,IAAA,CAAK;AAAA;AACpB,KACD,CAAA;AAAA,EACH;AACF;AAEA,IAAI,KAAK,gBAAA,EAAkB;AACzB,EAAA,IAAI,cAAc,8BAAA,EAAgC;AAAA,IAChD,SAAA;AAAA,IACA,UAAA,EAAY,EAAE,aAAA,EAAe,IAAA;AAAK,GACnC,CAAA;AACH;AAEA,IAAM,YAAY,MAAM,SAAA;AAAA,EACtB,QAAA,YAAoB,oBAChB,QAAA,CAAS,eAAA,CAAgB,MAAM,CAAA,OAAA,KAAW,OAAA,EAAS,SAAU,CAAA,GAC7D;AACN,CAAA;AAEA,IAAO,eAAQ,OAAA,CAAQ;AAAA,EACrB,UAAU,QAAA,CAAS,MAAA;AAAA,EAEnB,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,aAAA;AAAA,IACN,UAAU,QAAA,CAAS;AAAA,GACrB;AAAA,EAEA,IAAA,EAAM;AAAA,IACJ,GAAG,QAAA,CAAS,IAAA;AAAA,IACZ;AAAA,GACF;AAAA,EAEA,aAAA,EAAe;AAAA,IACb,SAAA,EAAW,SAAA,CAAU,GAAA,CAAI,kBAAkB;AAAA,GAC7C;AAAA,EAEA,UAAA,EAAY,CAAC,QAAA,CAAS,QAAQ;AAChC,CAAC","file":"index.js","sourcesContent":["{\n \"wireguard\": {\n \"name\": \"docker.io/linuxserver/wireguard\",\n \"tag\": \"latest\",\n \"image\": \"docker.io/linuxserver/wireguard:latest@sha256:7792dcef56c51e6b4d499a209e980ed74309bf3bee6af12168ea02bf289eddd9\"\n }\n}\n","import { createAddressSpace, l4EndpointToString, subnetToString } from \"@highstate/common\"\nimport { ExposableWorkload, Namespace, NetworkPolicy, Secret, Workload } from \"@highstate/k8s\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport * as images from \"../../assets/images.json\"\nimport { generateIdentityConfig, isExitNode, shouldExpose } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.nodeK8s)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst identityName = identity.peer.name.replaceAll(\".\", \"-\")\nconst appName = args.appName ?? `wg-${identityName}`\n\nconst namespace = Namespace.createOrPatch(appName, {\n cluster: inputs.k8sCluster,\n resource: inputs.workload ?? inputs.interface?.workload,\n\n metadata: {\n labels: {\n \"pod-security.kubernetes.io/enforce\": \"privileged\",\n },\n },\n})\n\nconst downstreamInterface = await toPromise(inputs.interface)\n\nconst preUp: string[] = []\n\nconst postUp: string[] = [\n // enable masquerading for all traffic going out of the WireGuard node\n // TODO: consider adding more specific and restrictive rules\n \"iptables -t nat -A POSTROUTING -j MASQUERADE\",\n]\n\nconst preDown: string[] = [\n // remove the masquerading rule\n \"iptables -t nat -D POSTROUTING -j MASQUERADE\",\n]\n\n// add forwarding restrictions for specified CIDRs\nfor (const restrictedCidr of args.forwardRestrictedSubnets) {\n // block forwarding to restricted CIDR (prevents other peers from reaching these destinations)\n postUp.push(`iptables -I FORWARD -d ${restrictedCidr} -j DROP`)\n preDown.push(`iptables -D FORWARD -d ${restrictedCidr} -j DROP`)\n}\n\nif (downstreamInterface) {\n // wait until the interface is up\n preUp.push(`while ! ip link show ${downstreamInterface.name} | grep -q 'UP' ; do sleep 1; done`)\n\n // remove the default rule to route all non-encapsulated traffic to upstream wireguard interface\n postUp.push(\"ip rule del not from all fwmark 0xca6c lookup 51820\")\n\n // add a rule to route all downstream traffic to the upstream wireguard interface\n postUp.push(\"ip rule add from all fwmark 0x1 lookup 51820\")\n\n // mark all downstream traffic with 0x1\n postUp.push(\n `iptables -t mangle -A PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all downstream traffic to the upstream wireguard interface\n preDown.push(\n `iptables -t mangle -D PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all non-encapsulated traffic to upstream wireguard interface\n preDown.push(\"ip rule del from all fwmark 0x1 lookup 51820\")\n}\n\nconst interfaceName = identityName.substring(0, 15) // linux kernel limit\n\n// if there is a workload, we will use a different port to prevent potential conflicts\nconst containerPort = (inputs.workload ?? inputs.interface?.workload) ? 51821 : 51820\n\nconst configSecret = Secret.create(appName, {\n namespace,\n\n stringData: {\n [`${interfaceName}.conf`]: generateIdentityConfig({\n identity,\n peers,\n listenPort: containerPort,\n preUp,\n postUp,\n preDown,\n cluster: await toPromise(inputs.k8sCluster),\n }),\n },\n})\n\nconst workload = await toPromise(\n Workload.createOrPatchGeneric(appName, {\n defaultType: \"Deployment\",\n namespace,\n\n existing: inputs.workload ?? inputs.interface?.workload,\n\n container: deepmerge(\n {\n image: images.wireguard.image,\n\n environment: {\n PUID: \"1000\",\n PGID: \"1000\",\n TZ: \"Etc/UTC\",\n },\n\n securityContext: {\n capabilities: {\n add: [\"NET_ADMIN\"],\n },\n },\n\n port: {\n containerPort,\n protocol: \"UDP\",\n },\n\n volumeMount: {\n volume: configSecret,\n mountPath: \"/config/wg_confs\",\n },\n },\n args.containerSpec ?? {},\n ),\n\n service: shouldExpose(identity, args.exposePolicy)\n ? {\n external: args.external,\n port: {\n port: identity.peer.listenPort ?? 51820,\n targetPort: containerPort,\n protocol: \"UDP\",\n nodePort: args.external ? identity.peer.listenPort : undefined,\n },\n }\n : undefined,\n }),\n)\n\nif (shouldExpose(identity, args.exposePolicy) && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-wireguard-ingress\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow encapsulated WireGuard traffic to the node from anywhere.\",\n\n ingressRule: {\n fromAll: true,\n },\n })\n}\n\nif (isExitNode(identity.peer) && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-all-egress\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow all egress traffic from the WireGuard node since it is an exit node.\",\n\n egressRule: {\n toAll: true,\n },\n })\n}\n\nconst pureAllowedSpace = createAddressSpace({\n included: identity.peer.allowedSubnets,\n excluded: identity.peer.addresses,\n})\n\n// allow egress to the subnets that are not part of the peer's addresses\nif (pureAllowedSpace.subnets.length > 0 && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-egress-to-allowed-subnets\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow egress traffic from the WireGuard node to its allowed subnets.\",\n\n egressRule: {\n toCidrs: pureAllowedSpace.subnets.map(subnetToString),\n },\n })\n}\n\nif (workload instanceof ExposableWorkload) {\n for (const peer of peers) {\n if (!peer.endpoints.length) {\n continue\n }\n\n new NetworkPolicy(`allow-egress-to-peer-${peer.name}`, {\n namespace,\n selector: workload.spec.selector,\n\n description: `Allow egress traffic from the WireGuard node to the endpoints of the peer \"${peer.name}\".`,\n\n egressRule: {\n toEndpoints: peer.endpoints,\n },\n })\n }\n}\n\nif (args.allowClusterPods) {\n new NetworkPolicy(\"allow-egress-to-cluster-pods\", {\n namespace,\n egressRule: { toClusterPods: true },\n })\n}\n\nconst endpoints = await toPromise(\n workload instanceof ExposableWorkload\n ? workload.optionalService.apply(service => service?.endpoints!)\n : [],\n)\n\nexport default outputs({\n workload: workload.entity,\n\n interface: {\n name: interfaceName,\n workload: workload.entity,\n },\n\n peer: {\n ...identity.peer,\n endpoints,\n },\n\n $statusFields: {\n endpoints: endpoints.map(l4EndpointToString),\n },\n\n $terminals: [workload.terminal],\n})\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/wireguard",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -34,18 +34,18 @@
34
34
  "@paralleldrive/cuid2": "^2.2.2",
35
35
  "uuid": "^11.1.0",
36
36
  "age-encryption": "^0.2.4",
37
- "@highstate/common": "0.16.0",
38
- "@highstate/k8s": "0.16.0",
39
- "@highstate/contract": "0.17.0",
40
- "@highstate/library": "0.16.0",
41
- "@highstate/pulumi": "0.17.0",
37
+ "@highstate/common": "0.18.0",
38
+ "@highstate/k8s": "0.18.0",
39
+ "@highstate/library": "0.18.0",
40
+ "@highstate/pulumi": "0.18.0",
41
+ "@highstate/contract": "0.18.0",
42
42
  "@highstate/etcd-sdk": "0.14.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@biomejs/biome": "2.2.0",
46
46
  "@types/zip-stream": "^7.0.0",
47
47
  "@typescript/native-preview": "^7.0.0-dev.20250920.1",
48
- "@highstate/cli": "0.17.0"
48
+ "@highstate/cli": "0.18.0"
49
49
  },
50
50
  "repository": {
51
51
  "url": "https://github.com/highstate-io/highstate"