# Names inside the VPN. Every swarm name that is not public resolves to the # VPN address of the machine serving it, through a static table written on # each host. Identical on every host. # # Two readers need the table. Processes on the host read /etc/hosts # (`networking.hosts`). Containers (agents, swarm services) ask the hive's # dnsmasq, which ignores /etc/hosts, so it also reads the table through # `addn-hosts`. # # A host leaves out the names it serves itself: hyperhive already answers # those with the bridge address, and a table entry would override it. { config, lib, ... }: let mesh = import ./mesh.nix; self = config.networking.hostName; swarm = config.services.hyperhive.swarm; # Which machine serves which name. A hive's machine is `hive-` and it # serves the hive's own names: its dashboard and its domain. servedBy = lib.mapAttrs' ( hive: entry: lib.nameValuePair "hive-${hive}" [ swarm.dashboardDomains.${hive} entry.domain ] ) swarm.hives // { swarm-central = [ swarm.domain swarm.bao.domain swarm.bao.ui.domain ]; swarm-services = [ swarm.forge.domain swarm.matrix.gatewayHost swarm.authelia.domain swarm.nats.domain swarm.otel.domain swarm.grafana.domain swarm.victoriametrics.domain swarm.victorialogs.domain ]; swarm-heavyduty = [ swarm.attic.ownDomain ]; }; elsewhere = removeAttrs servedBy [ self ]; in { networking.hosts = lib.mapAttrs' ( machine: names: lib.nameValuePair mesh.${machine}.address names ) elsewhere; services.dnsmasq.settings.addn-hosts = "${builtins.toFile "swarm-vpn-hosts" ( lib.concatStringsSep "\n" ( lib.mapAttrsToList ( machine: names: "${mesh.${machine}.address} ${lib.concatStringsSep " " names}" ) elsewhere ) )}"; }