ctucx.git: nixfiles

ctucx' nixfiles

commit a9a2f802ffb0458620b73aa6599820d438cd2133
parent 5a42d974f4f42c210a171140172a52899abd5c52
Author: Katja (ctucx) <git@ctu.cx>
Date: Fri, 28 Feb 2025 23:14:47 +0100

modules/linux/dns: use pipe operator, implement `extraZones` option, fix zone-notify
1 file changed, 96 insertions(+), 45 deletions(-)
M
modules/linux/dns.nix
|
141
++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
diff --git a/modules/linux/dns.nix b/modules/linux/dns.nix
@@ -4,13 +4,29 @@ with lib;
 
 let
   cfg = config.dns;
-  getAddressesFunction = nodes: isPrimary: lib.flatten (
-    lib.mapAttrsToList (
-      name: node: [
-        (lib.mkIf (node.config.networking.primaryIP  != "") node.config.networking.primaryIP)
-        (lib.mkIf (node.config.networking.primaryIP4 != "") node.config.networking.primaryIP4)
+
+  filterDNSServerAddresses = nodes: isPrimary: lib.flatten (
+    nodes
+    |> lib.filterAttrs (hostName: nodeCfg: nodeCfg.config.dns.enable && nodeCfg.config.dns.primary == isPrimary)
+    |> lib.mapAttrsToList (
+      hostName: nodeCfg: [
+        (lib.mkIf (nodeCfg.config.networking.primaryIP  != "") nodeCfg.config.networking.primaryIP)
+        (lib.mkIf (nodeCfg.config.networking.primaryIP4 != "") nodeCfg.config.networking.primaryIP4)
       ]
-    ) (lib.filterAttrs (name: node: node.config.dns.enable && node.config.dns.primary == isPrimary) nodes)
+    )
+  );
+
+  filterDNSServerSecondaries = nodes: (
+    nodes
+    |> lib.filterAttrs (hostName: nodeCfg: nodeCfg.config.dns.enable && !nodeCfg.config.dns.primary)
+    |> lib.mapAttrs(
+      hostName: nodeCfg: {
+        address = [
+          (lib.mkIf (nodeCfg.config.networking.primaryIP  != "") nodeCfg.config.networking.primaryIP)
+          (lib.mkIf (nodeCfg.config.networking.primaryIP4 != "") nodeCfg.config.networking.primaryIP4)
+        ];
+      }
+    )
   );
 
 in {

@@ -44,6 +60,11 @@ in {
       type    = lib.types.attrsOf pkgs.dns.lib.types.zone;
       default = {};
     };
+
+    extraZones = mkOption {
+      type    = (pkgs.formats.yaml { }).type;
+      default = {};
+    };
   };
 
   config = mkIf cfg.enable {

@@ -52,19 +73,22 @@ in {
 
     # serve records defined in all host configs
     dns.allZones = mkMerge (
-      mapAttrsToList (
-        name: host: host.config.dns.zones
-      ) nodes
+      nodes
+      |> mapAttrsToList ( name: host: host.config.dns.zones )
     );
 
-    environment.etc = (lib.mapAttrs' (name: zone: {
-       name = "${cfg.zonesDir}/${name}.zone";
-       value = { source = pkgs.dns.util."${currentSystem}".writeZone name zone; };
-    }) cfg.allZones);
+    environment.etc = lib.mkIf cfg.primary (
+      cfg.allZones
+      |> lib.mapAttrs' (name: zone: {
+         name = "${cfg.zonesDir}/${name}.zone";
+         value = { source = pkgs.dns.util."${currentSystem}".writeZone name zone; };
+      })
+    );
 
     services.knot = let
-      primaryAddresses   = getAddressesFunction nodes true;
-      secondaryAddresses = getAddressesFunction nodes false;
+      primaryAddresses   = filterDNSServerAddresses   nodes true;
+      secondaryAddresses = filterDNSServerAddresses   nodes false;
+      secondaries        = filterDNSServerSecondaries nodes;
     in {
 	    enable = true;
 	    keyFiles = [];

@@ -79,48 +103,66 @@ in {
         mod-rrl.default.rate-limit = 200;
         mod-rrl.default.slip       = 2;
 
-        remote.primary.address   = primaryAddresses;
-        remote.secondary.address = secondaryAddresses;
+        remote = { primary.address = primaryAddresses; } // secondaries;
 
-        acl.primary.address = secondaryAddresses;
-        acl.primary.action  = "transfer";
+        acl.allowTransfer.address = secondaryAddresses;
+        acl.allowTransfer.action  = "transfer";
 
-        acl.secondary.address = primaryAddresses;
-        acl.secondary.action  = "notify";
+        acl.allowNotify.address   = primaryAddresses;
+        acl.allowNotify.action    = "notify";
 
-        template.default = {
-          semantic-checks = true;
-          global-module   = "mod-rrl/default";
-        };
+        template = let
+          notify = {
+            acl          = "allowTransfer";
+            notify       = builtins.attrNames secondaries;
+          };
 
-        template.primaryZone = {
-          storage         = "${cfg.dataDir}/zones";
+          catalog = {
+            catalog-role = "member";
+            catalog-zone = "catalog.";
+          };
 
-          journal-content = "all";
+        in {
 
-          zonefile-sync   = -1;
-          zonefile-load   = "difference-no-serial";
+          default = {
+            semantic-checks = true;
+            global-module   = "mod-rrl/default";
+          };
 
-          acl          = "primary";
-          notify       = "secondary";
+          notifyZone  = notify;
+          extraZone   = notify // catalog;
+          primaryZone = notify // catalog // {
+            storage         = "${cfg.dataDir}/nixZones";
 
-          catalog-role = "member";
-          catalog-zone = "catalog.";
-        };
+            journal-content = "all";
+
+            zonefile-sync   = -1;
+            zonefile-load   = "difference-no-serial";
+          };
+
+          secondaryZone = {
+            master = "primary";
+            acl    = "allowNotify";
 
-        template.secondaryZone = {
-          acl     = "secondary";
-          master  = "primary";
+            journal-content = "all";
+
+            zonefile-sync   = -1;
+            zonefile-load   = "none";
+          };
         };
 
         zone = if !cfg.primary then {
           "catalog.".catalog-role     = "interpret";
           "catalog.".catalog-template = "secondaryZone";
+          "catalog.".template         = "secondaryZone";
         } else {
           "catalog.".catalog-role = "generate";
+          "catalog.".template     = "notifyZone";
         } // (lib.mapAttrs (name: zone: {
           template = "primaryZone";
-        }) cfg.allZones);
+        }) cfg.allZones) // (lib.mapAttrs (name: zone: {
+          template = "extraZone";
+        } // zone) cfg.extraZones);
 	    };
   	};
 

@@ -132,7 +174,7 @@ in {
         age   = "-";
       };
 
-      knotZones."${cfg.dataDir}/zones".d = lib.mkIf cfg.primary {
+      knotZones."${cfg.dataDir}/nixZones".d = lib.mkIf cfg.primary {
         group = "knot";
         user  = "knot";
         mode  = "770";

@@ -141,18 +183,27 @@ in {
     };
 
     systemd.services.knot = lib.mkIf cfg.primary {
-      reloadTriggers = lib.mapAttrsToList (name: zone: pkgs.dns.util."${currentSystem}".writeZone name zone) cfg.allZones;
+      reloadTriggers = (
+        cfg.allZones
+        |> lib.mapAttrsToList (name: zone: pkgs.dns.util."${currentSystem}".writeZone name zone)
+       ) ++ (
+        cfg.extraZones
+        |> lib.mapAttrsToList (name: zone: (if (builtins.hasAttr "storage" zone) then "${zone.storage}/${zone.file}" else "${zone.file}"))
+      );
 
       preStart = ''
         set -euo pipefail
-        cp --dereference /etc/${cfg.zonesDir}/* ${cfg.dataDir}/zones
-        chmod -R 770 ${cfg.dataDir}/zones
+
+        cp --dereference /etc/${cfg.zonesDir}/* ${cfg.dataDir}/nixZones
+        chmod -R 770 ${cfg.dataDir}/nixZones
       ''; 
 
       serviceConfig.ExecReload = lib.mkForce (pkgs.writeShellScript "knot-reload" ''
         set -eou pipefail
-        cp --dereference /etc/${cfg.zonesDir}/* ${cfg.dataDir}/zones
-        chmod -R 770 ${cfg.dataDir}/zones
+
+        cp --dereference /etc/${cfg.zonesDir}/* ${cfg.dataDir}/nixZones
+        chmod -R 770 ${cfg.dataDir}/nixZones
+
         ${config.services.knot.package}/bin/knotc reload
       '');
     };