flake-update-20260505
  1# Common DNS zone builder for sbr.pm
  2# Takes an IP selector function to allow different IP selection strategies
  3{
  4  dns,
  5  globals,
  6  getIPForMachine,
  7}:
  8with dns.lib.combinators;
  9let
 10  # Helper to generate service DNS records
 11  mkServiceRecords =
 12    services:
 13    builtins.listToAttrs (
 14      builtins.concatMap (
 15        serviceName:
 16        let
 17          service = services.${serviceName};
 18          hostName = if builtins.isAttrs service then service.host else service;
 19          ip = getIPForMachine globals.machines.${hostName};
 20          aliases = if builtins.isAttrs service then (service.aliases or [ ]) else [ ];
 21        in
 22        [
 23          {
 24            name = serviceName;
 25            value.A = [ ip ];
 26          }
 27        ]
 28        ++ (map (alias: {
 29          name = alias;
 30          value.A = [ ip ];
 31        }) aliases)
 32      ) (builtins.attrNames services)
 33    );
 34
 35  # Only include machines that should be in sbr.pm zone
 36  machineList = [
 37    "shikoku"
 38    "sakhalin"
 39    "aix"
 40    "rhea"
 41    "aion"
 42    "demeter"
 43    "athena"
 44    "nagoya"
 45    "kerkouane"
 46    "aomi"
 47    "kyushu"
 48    "okinawa"
 49    "wakasu"
 50  ];
 51
 52  mkMachineRecords = builtins.listToAttrs (
 53    map (machineName: {
 54      name = machineName;
 55      value = {
 56        A = [ (getIPForMachine globals.machines.${machineName}) ];
 57        subdomains."*".A = [ (getIPForMachine globals.machines.${machineName}) ];
 58      };
 59    }) machineList
 60  );
 61in
 62{
 63  SOA = {
 64    nameServer = "ns1.sbr.pm.";
 65    adminEmail = "admin.sbr.pm";
 66    serial = 3;
 67    refresh = 604800;
 68    retry = 86400;
 69    expire = 2419200;
 70    minimum = 604800;
 71  };
 72
 73  NS = [
 74    "ns1.sbr.pm."
 75    "ns2.sbr.pm."
 76  ];
 77
 78  # Root domain points to public endpoint
 79  A = [ "46.224.100.116" ];
 80
 81  # Email (Gandi)
 82  MX = [
 83    {
 84      preference = 10;
 85      exchange = "spool.mail.gandi.net.";
 86    }
 87    {
 88      preference = 50;
 89      exchange = "fb.mail.gandi.net.";
 90    }
 91  ];
 92
 93  subdomains = {
 94    # Name servers (demeter and athena)
 95    ns1.A = [ (getIPForMachine globals.machines.demeter) ];
 96    ns2.A = [ (getIPForMachine globals.machines.athena) ];
 97
 98    # Wildcard for public endpoint
 99    "*".A = [
100      {
101        address = "46.224.100.116";
102        ttl = 10800;
103      }
104    ];
105
106    # Email CNAMEs (Gandi mail service)
107    imap.CNAME = [ "access.mail.gandi.net." ];
108    pop.CNAME = [ "access.mail.gandi.net." ];
109    smtp.CNAME = [ "relay.mail.gandi.net." ];
110    webmail.CNAME = [ "webmail.gandi.net." ];
111
112    # Shortcuts
113    p.A = [ "46.224.100.116" ]; # public endpoint shortcut
114    www = {
115      A = [ "46.224.100.116" ];
116      subdomains."*".A = [ "46.224.100.116" ];
117    };
118  }
119  // mkMachineRecords
120  // mkServiceRecords globals.services;
121}