ctucx.git: dns.nix

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

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
#
# SPDX-FileCopyrightText: 2019 Kirill Elagin <https://kir.elagin.me/>
# SPDX-FileCopyrightText: 2021 Naïm Favier <n@monade.li>
#
# SPDX-License-Identifier: MPL-2.0 or MIT
#

{ lib }:

let
  inherit (builtins) attrValues filter map removeAttrs;
  inherit (lib) concatMapStringsSep concatStringsSep mapAttrs
                     mapAttrsToList optionalString;
  inherit (lib) mkOption literalExample types;

  inherit (import ./record.nix { inherit lib; }) recordType writeRecord;

  rsubtypes = import ./records { inherit lib; };
  rsubtypes' = removeAttrs rsubtypes ["SOA"];

  subzoneOptions = {
    subdomains = mkOption {
      type = types.attrsOf subzone;
      default = {};
      example = {
        www = {
          A = [ { address = "1.1.1.1"; } ];
        };
        staging = {
          A = [ { address = "1.0.0.1"; } ];
        };
      };
      description = "Records for subdomains of the domain";
    };
  } //
    mapAttrs (n: t: mkOption rec {
      type = types.listOf (recordType t);
      default = [];
      # example = [ t.example ];  # TODO: any way to auto-generate an example for submodule?
      description = "List of ${n} records for this zone/subzone";
    }) rsubtypes';

  subzone = types.submodule {
    options = subzoneOptions;
  };

  writeSubzone = name: zone:
    let
      groupToString = pseudo: subt:
        concatMapStringsSep "\n" (writeRecord name subt) (zone."${pseudo}");
      groups = mapAttrsToList groupToString rsubtypes';
      groups' = filter (s: s != "") groups;

      writeSubzone' = subname: writeSubzone "${subname}.${name}";
      sub = concatStringsSep "\n\n" (mapAttrsToList writeSubzone' zone.subdomains);
    in
      concatStringsSep "\n\n" groups'
      + optionalString (sub != "") ("\n\n" + sub);

  zoneToString = name: zone@{SOA, ...}:
    ''
      ${writeRecord name rsubtypes.SOA SOA}
    '' + writeSubzone name zone + "\n";

  zone = types.submodule ({ name, ... }: {
    options = {
      TTL = mkOption {
        type = types.ints.unsigned;
        default = 60 * 60;
        example = literalExample "60 * 60";
        description = "Default record caching duration. Sets the $TTL variable";
      };
      SOA = mkOption rec {
        type = recordType rsubtypes.SOA;
        example = {
          ttl = 24 * 60 * 60;
        } // type.example;
        description = "SOA record";
      };
    } // subzoneOptions;

  });

in

{
  inherit zone;
  inherit subzone;
  inherit zoneToString;
}