ctucx.git: dns.nix

fork of https://github.com/kirelagin/dns.nix

commit 3e88c8e8c06d23b4f28da26a73a78b8ff8ca1b3b
parent 6ef7aec0150acbaaff9b69c85c2d214eec9ae39f
Author: Kirill Elagin <kirelagin@gmail.com>
Date: Fri, 8 Mar 2019 19:48:17 +0100

Make zone contain records other than SOA
4 files changed, 52 insertions(+), 14 deletions(-)
M
default.nix
|
27
++++++++++++++++++++++++++-
M
dns/default.nix
|
2
+-
M
dns/types/record.nix
|
3
++-
M
dns/types/zone.nix
|
34
+++++++++++++++++++++++-----------
diff --git a/default.nix b/default.nix
@@ -22,11 +22,36 @@ let
 
   testZones = {
     "test.com" = {
-      soa = {
+      SOA = {
         nameServer = "ns.test.com";
         adminEmail = "admin@test.com";
         serial = 2019030800;
       };
+
+      NS = [
+        { nsdname = "ns.test.com"; }
+        { nsdname = "ns2.test.com"; }
+      ];
+
+      A = [
+        { address = "1.1.1.1"; ttl = 60 * 60; }
+        { address = "1.0.0.1"; ttl = 60 * 60; }
+      ];
+
+      CAA = [
+        { issuerCritical = false;
+          tag = "issue";
+          value = "letsencrypt.org";
+        }
+        { issuerCritical = false;
+          tag = "issuewild";
+          value = ";";
+        }
+        { issuerCritical = false;
+          tag = "iodef";
+          value = "mailto:admin@example.com";
+        }
+      ];
     };
   };
 
diff --git a/dns/default.nix b/dns/default.nix
@@ -10,7 +10,7 @@ let
   mkZone = name: zone:
     pkgs.writeTextFile {
       name = "${name}.zone";
-      text = toString zone;
+      text = toString zone + "\n";
     };
 in
 
diff --git a/dns/types/record.nix b/dns/types/record.nix
@@ -13,10 +13,11 @@ let
   recordTypes = import ./records { inherit pkgs; };
 in
 
-recordType: types.submodule {
+recordType: name: types.submodule {
   options = {
     name = mkOption {
       type = types.str;
+      default = name;
       example = "example.com";
       description = "Name of the node to which this resource record pertains";
     };
diff --git a/dns/types/zone.nix b/dns/types/zone.nix
@@ -7,17 +7,20 @@
 { pkgs }:
 
 let
+  inherit (builtins) filter map;
+  inherit (pkgs.lib) concatMapStringsSep concatStringsSep filterAttrs mapAttrs;
   inherit (pkgs.lib) mkOption types;
 
   record = import ./record.nix { inherit pkgs; };
   recordTypes = import ./records { inherit pkgs; };
 
+  recordTypes' = filterAttrs (n: v: n != "SOA") recordTypes;
 in
 
 types.submodule ({name, ...}: {
   options = {
-    soa = mkOption rec {
-      type = record recordTypes.SOA;
+    SOA = mkOption rec {
+      type = record recordTypes.SOA name;
       example = {
         ttl = 24 * 60 * 60;
       } // type.example;

@@ -27,19 +30,28 @@ types.submodule ({name, ...}: {
       readOnly = true;
       visible = false;
     };
-  };
+  }  // mapAttrs (n: t: mkOption rec {
+          type = types.listOf (record t name);
+          default = [];
+          example = [ t.example ];
+          description = "List of ${t} records for this zone/subzone";
+        }) recordTypes';
 
   config = {
-    soa.name = name;
-    soa.class = "IN";
-    __toString = { soa, ... }:
-      ''
-        $TTL 24h
+    __toString = zone@{SOA, ...}:
+      let
+        groupToString = n:
+          concatMapStringsSep "\n" toString (zone."${n}");
+        groups = map groupToString (builtins.attrNames recordTypes');
+        groups' = filter (s: s != "") groups;
+      in
+        ''
+          $TTL 24h
 
-        $ORIGIN ${soa.name}.
+          $ORIGIN ${SOA.name}.
 
-        ${toString soa}
-      '';
+          ${toString SOA}
 
+        '' + concatStringsSep "\n\n" groups';
   };
 })