Dynamically Generate Records over a number range

12 views
Skip to first unread message

Tom Misilo

unread,
Mar 7, 2025, 4:33:15 PMMar 7
to DNSControl-discuss
Hello!


I tried searching the Docs and listserv but didn't come up with an example.

Is there a way DNSControl way to support the $GENERATE function of bind?

https://www.zytrax.com/books/dns/ch8/generate.html

I want to create a bunch of PTR records for our subnets to help better identify them,
For example
$GENERATE 11-15 $ PTR ip-192-168-0-$.annex.domain.tld.

Something that would create the equivalent

PTR('11', 'ip-192-168-0-11.annex.domain.tld.'),
PTR('12', 'ip-192-168-0-12.annex.domain.tld.'),
PTR('13', 'ip-192-168-0-13.annex.domain.tld.'),
PTR('14', 'ip-192-168-0-14.annex.domain.tld.'),
PTR('15', 'ip-192-168-0-15.annex.domain.tld.'),


And on the reverse to be able to do 

$GENERATE 48-63 ip-192-168-0-$ A 192.168.0.$
Which generates the corresponding
A('ip-192-168-0-11', '192.168.0.11'),
A('ip-192-168-0-12', '192.168.0.12'),
A('ip-192-168-0-13', '192.168.0.13'),
A('ip-192-168-0-14', '192.168.0.14'),
A('ip-192-168-0-15', '192.168.0.15'),

Thank you!
Tom

Phil Pennock

unread,
Mar 7, 2025, 5:50:00 PMMar 7
to Tom Misilo, DNSControl-discuss
On 2025-03-07 at 13:33 -0800, Tom Misilo wrote:
> I tried searching the Docs and listserv but didn't come up with an example.
>
> Is there a way DNSControl way to support the $GENERATE function of bind?

So $GENERATE is a hack for Bind zonefiles because there's no scripting
support. It's effectively a very focused script which does make all the
individual records in-memory.

With DNSControl, you have JavaScript as the scripting language so you
can just emit all the records you want. Note though that it's the older
ES5 dialect of JavaScript. Still, see a worked example below.

> $GENERATE 11-15 $ PTR ip-192-168-0-$.annex.domain.tld.
>
> Something that would create the equivalent
>
> PTR('11', 'ip-192-168-0-11.annex.domain.tld.'),
> PTR('12', 'ip-192-168-0-12.annex.domain.tld.'),
> PTR('13', 'ip-192-168-0-13.annex.domain.tld.'),
> PTR('14', 'ip-192-168-0-14.annex.domain.tld.'),
> PTR('15', 'ip-192-168-0-15.annex.domain.tld.'),
>
>
> And on the reverse to be able to do
>
> $GENERATE 48-63 ip-192-168-0-$ A 192.168.0.$
> Which generates the corresponding
> A('ip-192-168-0-11', '192.168.0.11'),
> A('ip-192-168-0-12', '192.168.0.12'),
> A('ip-192-168-0-13', '192.168.0.13'),
> A('ip-192-168-0-14', '192.168.0.14'),
> A('ip-192-168-0-15', '192.168.0.15'),

There's a worked example in
<https://docs.dnscontrol.org/language-reference/domain-modifiers/ptr> of
adding forward/reverse DNS which might be a more natural/simpler way.

But to answer the question exactly as asked, perhaps this will help?
The `range()` function is the annoying part, since my JS is very very
rusty and ES5 seems hard to find docs for. :(

I called the function `generate_rr2fields` not `generate` because you
might want to do things like pass through TTLs or other stuff. Left as
an exercise for the reader.

```javascript
function range(start, stop, step) {
if (typeof(step) === 'undefined') { step = 1; };
var a = [];
for (i = start; i <= stop; i += step) {
a = a.concat(i);
}
return a;
};

function generate_rr2fields(start, stop, rrFunc, leftPrefix, leftSuffix, rightPrefix, rightSuffix) {
return function(d) {
range(start, stop).forEach(function(item) {
rrFunc(leftPrefix + item + leftSuffix, rightPrefix + item + rightSuffix)(d);
})
}
};

D('annex.domain.tld', NewRegistrar('none'), DnsProvider('bind'),
generate_rr2fields(11, 15, PTR, '', '', 'ip-192-168-0-', ''),
);

D('example.org', NewRegistrar('none'), DnsProvider('bind'),
generate_rr2fields(48, 63, A, 'ip-192-168-0-', '', '192.168.0.', ''),
);
```
Reply all
Reply to author
Forward
0 new messages