zonetool is a tool to reduce the pain of managing potentially large collections of DNS zone files. It offers a simple declarative syntax, and semantics to merge manual configuration and automated output from arbitrary sources. It supports templates and inheritance as a way to simplify large deployments.
The basic entity of the data model is a dictionary corresponding to a DNS zone. The dictionary key/value pairs correspond to individual DNS resource records. Some keys are special: they define attributes of the zone itself - they are usually recognizable because they're uppercase (while normal DNS record names are lowercase).
A DNS entry consists of a name and one or more resource records, so in
our model the dictionary values can be either strings, or lists of
strings (a single string is just a shorthand syntax for a list
containing a single element). All names are relative to the zone
origin, except for the special name consisting of a single underscore
_), which stands for the zone origin itself.
Each resource record consists of a DNS RR type, and the associated
data, separated by a space (the resource data can contain further
spaces). The resource record will be written verbatim to the resulting
zone file (the
IN namespace is assumed), for example:
inventati.org: _: - A 22.214.171.124 - AAAA 2001:1:2:3::4 - MX 10 mx1.inventati.org.
describes three different DNS records, all for the zone origin: one IPv4 address, an IPv6 one, and a MX record for SMTP delivery.
Since A and AAAA records are usually the most common by far, a special shorthand notation allows you to simply specify the IP address, and the record type will be automatically determined. So, the above zone could have been written as:
inventati.org: _: - 126.96.36.199 - 2001:1:2:3::4 - MX 10 mx1.inventati.org.
Templates and inheritance
Each zone can have an
EXTENDS attribute, which contains a list of
zone names that will be merged into the current one. It is possible to
use this feature as a full-blown templating system by taking advantage
of the fact that zones whose name starts with a
@ are not going to
be present in the output. In fact, one such zone is always defined:
@default (empty by default), and it is automatically added to the
EXTENDS attribute of every zone that does not start with a
Perhaps some examples can clarify the mechanism:
autistici.org: www: 188.8.131.52 inventati.org: www: 184.108.40.206 "@default": _: - NS ns1.example.com. - NS ns2.example.com.
In the above case, the two zones defined will both have NS records
autistici.org: EXTENDS: - @base www: 220.127.116.11 "@base": _spf: TXT "v=spf1 -all" "@default": _: NS ns1.example.com.
autistici.org zone will not only include the NS record
@default, but it will also contain the
_spf TXT record
Variable substitution and configuration
Along with the zone dictionaries, it is also possible to specify arbitrary resource records in a global configuration: these records are not associated with a specific zone, and they can be substituted in-place using a shell-like variable expansion syntax.
For instance, assume that you have a list of IPs which appear in multiple records in your DNS zones: it would be nice to maintain the full list in a single place. So, if your configuration contains:
FRONTENDS = ['18.104.22.168', '22.214.171.124']
it is then possible to define a zone as follows:
autistici.org: _: "$FRONTENDS" www: "$FRONTENDS"
Note that when using this syntax, the resource record can't be a list.