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;
}