1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

New features: DU() and getConfiguredDomains() to assist modifying domains (#800)

* Added DU() and getConfiguredDomains()

* Added docs for both new functions

* Added a space between option and its value

* Renamed "DU" to "D_EXTEND", adjusted docs

* Fixed: Changed old DU() calls to D_EXTEND()
This commit is contained in:
Patrik Kernstock
2020-08-04 14:43:02 +01:00
committed by GitHub
parent f21c8fc400
commit d2d210a5af
5 changed files with 235 additions and 105 deletions

View File

@ -0,0 +1,30 @@
---
name: D_EXTEND
parameters:
- name
- modifiers...
---
`D_EXTEND` adds records (and metadata) to a domain. The domain must have previously been defined by `D()`. `D_EXTEND()` behaves the same as `D()` in all other ways: The first argument is the domain name. See the documentation of `D` for further details.
Example:
{% include startExample.html %}
{% highlight js %}
D('domain.tld', REG, DnsProvider(DNS),
A('@', "127.0.0.1")
)
D_EXTEND('domain.tld',
A('@', "127.0.0.2")
)
{%endhighlight%}
This will end up in following modifications:
```
******************** Domain: domain.tld
----- Getting nameservers from: registrar
----- DNS Provider: registrar...3 corrections
#1: CREATE A domain.tld 127.0.0.1 ttl=43200
#2: CREATE A domain.tld 127.0.0.2 ttl=43200
#3: REFRESH zone domain.tld
```
{% include endExample.html %}

View File

@ -0,0 +1,63 @@
---
name: getConfiguredDomains
parameters:
- name
- modifiers...
---
`getConfiguredDomains` getConfiguredDomains is a helper function that returns the domain names
configured at the time the function is called. Calling this function early or later in
`dnsconfig.js` may return different results. Typical usage is to iterate over all
domains at the end of your configuration file.
Example for adding records to all configured domains:
{% include startExample.html %}
{% highlight js %}
var domains = getConfiguredDomains();
for(i = 0; i < domains.length; i++) {
D_EXTEND(domains[i],
TXT('_important', 'BLA') // I know, not really creative.
)
}
{%endhighlight%}
This will end up in following modifications:
```
******************** Domain: domain1.tld
----- Getting nameservers from: registrar
----- DNS Provider: registrar...2 corrections
#1: CREATE TXT _important.domain1.tld "BLA" ttl=43200
#2: REFRESH zone domain1.tld
******************** Domain: domain2.tld
----- Getting nameservers from: registrar
----- DNS Provider: registrar...2 corrections
#1: CREATE TXT _important.domain2.tld "BLA" ttl=43200
#2: REFRESH zone domain2.tld
```
{% include endExample.html %}
Example for adding DMARC report records:
{% include startExample.html %}
This example might be more useful, specially for configuring the DMARC report records. According to DMARC RFC you need to specify `domain2.tld._report.dmarc.domain1.tld` to allow `domain2.tld` to send aggregate/forensic email reports to `domain1.tld`. This can be used to do this in an easy way, without using the wildcard from the RFC.
{% highlight js %}
var domains = getConfiguredDomains();
for(i = 0; i < domains.length; i++) {
D_EXTEND("domain1.tld",
TXT(domains[i] + '._report._dmarc', 'v=DMARC1')
);
}
{%endhighlight%}
This will end up in following modifications:
```
******************** Domain: domain2.tld
----- Getting nameservers from: registrar
----- DNS Provider: registrar...4 corrections
#1: CREATE TXT domain1.tld._report._dmarc.domain2.tld "v=DMARC1" ttl=43200
#2: CREATE TXT domain3.tld._report._dmarc.domain2.tld "v=DMARC1" ttl=43200
#3: CREATE TXT domain4.tld._report._dmarc.domain2.tld "v=DMARC1" ttl=43200
#4: REFRESH zone domain2.tld
```
{% include endExample.html %}

View File

@ -25,6 +25,12 @@ function initialize() {
defaultArgs = [];
}
// Returns an array of domains which were registered so far during runtime
// Own function for compatibility reasons or if some day special processing would be required.
function getConfiguredDomains() {
return conf.domain_names;
}
function NewRegistrar(name, type, meta) {
if (type) {
type == 'MANUAL';
@ -94,6 +100,32 @@ function D(name, registrar) {
conf.domain_names.push(name);
}
// DU(name): Update an already added DNS Domain with D().
function D_EXTEND(name) {
var domain = _getDomainObject(name);
if (domain == null) {
throw name + ' was not declared yet and therefore cannot be updated. Use D() before.';
}
for (var i = 0; i < defaultArgs.length; i++) {
processDargs(defaultArgs[i], domain.obj);
}
for (var i = 1; i < arguments.length; i++) {
var m = arguments[i];
processDargs(m, domain.obj);
}
conf.domains[domain.id] = domain.obj; // let's overwrite the object.
}
// _getDomainObject(name): This is a small helper function to get the domain JS object returned.
function _getDomainObject(name) {
for(var i = 0; i < conf.domains.length; i++) {
if (conf.domains[i]['name'] == name) {
return {'id': i, 'obj': conf.domains[i]};
}
}
return null;
}
// DEFAULTS provides a set of default arguments to apply to all future domains.
// Each call to DEFAULTS will clear any previous values set.
function DEFAULTS() {

View File

@ -212,112 +212,117 @@ var _escData = map[string]*_escFile{
"/helpers.js": {
name: "helpers.js",
local: "pkg/js/helpers.js",
size: 24193,
size: 25306,
modtime: 0,
compressed: `
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
NmaBXgAA
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
hjskFLAWqHsOMBIs/l8AAAD//+WKkZfaYgAA
`,
},
}