auto-update-daily-20260202
  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    "wakasu"
 49  ];
 50
 51  mkMachineRecords = builtins.listToAttrs (
 52    map (machineName: {
 53      name = machineName;
 54      value = {
 55        A = [ (getIPForMachine globals.machines.${machineName}) ];
 56        subdomains."*".A = [ (getIPForMachine globals.machines.${machineName}) ];
 57      };
 58    }) machineList
 59  );
 60in
 61{
 62  SOA = {
 63    nameServer = "ns1.sbr.pm.";
 64    adminEmail = "admin.sbr.pm";
 65    serial = 3;
 66    refresh = 604800;
 67    retry = 86400;
 68    expire = 2419200;
 69    minimum = 604800;
 70  };
 71
 72  NS = [
 73    "ns1.sbr.pm."
 74    "ns2.sbr.pm."
 75  ];
 76
 77  # Root domain points to public endpoint
 78  A = [ "167.99.17.238" ];
 79
 80  # Email (Gandi)
 81  MX = [
 82    {
 83      preference = 10;
 84      exchange = "spool.mail.gandi.net.";
 85    }
 86    {
 87      preference = 50;
 88      exchange = "fb.mail.gandi.net.";
 89    }
 90  ];
 91
 92  subdomains = {
 93    # Name servers (demeter and athena)
 94    ns1.A = [ (getIPForMachine globals.machines.demeter) ];
 95    ns2.A = [ (getIPForMachine globals.machines.athena) ];
 96
 97    # Wildcard for public endpoint
 98    "*".A = [
 99      {
100        address = "167.99.17.238";
101        ttl = 10800;
102      }
103    ];
104
105    # Email CNAMEs (Gandi mail service)
106    imap.CNAME = [ "access.mail.gandi.net." ];
107    pop.CNAME = [ "access.mail.gandi.net." ];
108    smtp.CNAME = [ "relay.mail.gandi.net." ];
109    webmail.CNAME = [ "webmail.gandi.net." ];
110
111    # Shortcuts
112    p.A = [ "167.99.17.238" ]; # public endpoint shortcut
113    www = {
114      A = [ "167.99.17.238" ];
115      subdomains."*".A = [ "167.99.17.238" ];
116    };
117  }
118  // mkMachineRecords
119  // mkServiceRecords globals.services;
120}