mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
DOCS: Migrated documentation website to Gitbook (#1809)
This commit is contained in:
committed by
GitHub
parent
f4388dd6ad
commit
f912b15adc
99
documentation/functions/global/D.md
Normal file
99
documentation/functions/global/D.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
name: D
|
||||
parameters:
|
||||
- name
|
||||
- registrar
|
||||
- modifiers...
|
||||
parameter_types:
|
||||
name: string
|
||||
registrar: string
|
||||
"modifiers...": DomainModifier[]
|
||||
---
|
||||
|
||||
`D` adds a new Domain for DNSControl to manage. The first two arguments are required: the domain name (fully qualified `example.com` without a trailing dot), and the
|
||||
name of the registrar (as previously declared with [NewRegistrar](NewRegistrar.md)). Any number of additional arguments may be included to add DNS Providers with [DNSProvider](NewDnsProvider.md),
|
||||
add records with [A](../domain/A.md), [CNAME](../domain/CNAME.md), and so forth, or add metadata.
|
||||
|
||||
Modifier arguments are processed according to type as follows:
|
||||
|
||||
- A function argument will be called with the domain object as it's only argument. Most of the [built-in modifier functions](https://docs.dnscontrol.org/language-reference/domain-modifiers) return such functions.
|
||||
- An object argument will be merged into the domain's metadata collection.
|
||||
- An array argument will have all of it's members evaluated recursively. This allows you to combine multiple common records or modifiers into a variable that can
|
||||
be used like a macro in multiple domains.
|
||||
|
||||
```javascript
|
||||
var REGISTRAR = NewRegistrar("name.com");
|
||||
var r53 = NewDnsProvider("R53");
|
||||
|
||||
// simple domain
|
||||
D("example.com", REGISTRAR, DnsProvider(r53),
|
||||
A("@","1.2.3.4"),
|
||||
CNAME("test", "foo.example2.com.")
|
||||
);
|
||||
|
||||
// "macro" for records that can be mixed into any zone
|
||||
var GOOGLE_APPS_DOMAIN_MX = [
|
||||
MX('@', 1, 'aspmx.l.google.com.'),
|
||||
MX('@', 5, 'alt1.aspmx.l.google.com.'),
|
||||
MX('@', 5, 'alt2.aspmx.l.google.com.'),
|
||||
MX('@', 10, 'alt3.aspmx.l.google.com.'),
|
||||
MX('@', 10, 'alt4.aspmx.l.google.com.'),
|
||||
]
|
||||
|
||||
D("example.com", REGISTRAR, DnsProvider(r53),
|
||||
A("@","1.2.3.4"),
|
||||
CNAME("test", "foo.example2.com."),
|
||||
GOOGLE_APPS_DOMAIN_MX
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
# Split Horizon DNS
|
||||
|
||||
DNSControl supports Split Horizon DNS. Simply
|
||||
define the domain two or more times, each with
|
||||
their own unique parameters.
|
||||
|
||||
To differentiate the different domains, specify the domains as
|
||||
`domain.tld!tag`, such as `example.com!inside` and
|
||||
`example.com!outside`.
|
||||
|
||||
```javascript
|
||||
var REG = NewRegistrar("Third-Party");
|
||||
var DNS_INSIDE = NewDnsProvider("Cloudflare");
|
||||
var DNS_OUTSIDE = NewDnsProvider("bind");
|
||||
|
||||
D("example.com!inside", REG, DnsProvider(DNS_INSIDE),
|
||||
A("www", "10.10.10.10")
|
||||
);
|
||||
|
||||
D("example.com!outside", REG, DnsProvider(DNS_OUTSIDE),
|
||||
A("www", "20.20.20.20")
|
||||
);
|
||||
|
||||
D_EXTEND("example.com!inside",
|
||||
A("internal", "10.99.99.99")
|
||||
);
|
||||
```
|
||||
|
||||
A domain name without a `!` is assigned a tag that is the empty
|
||||
string. For example, `example.com` and `example.com!` are equivalent.
|
||||
However, we strongly recommend against using the empty tag, as it
|
||||
risks creating confusion. In other words, if you have `domain.tld`
|
||||
and `domain.tld!external` you now require humans to remember that
|
||||
`domain.tld` is the external one. I mean... the internal one. You
|
||||
may have noticed this mistake, but will your coworkers? Will you in
|
||||
six months? You get the idea.
|
||||
|
||||
DNSControl command line flag `--domains` is an exact match. If you
|
||||
define domains `example.com!george` and `example.com!john` then:
|
||||
|
||||
* `--domains=example.com` will not match either domain.
|
||||
* `--domains='example.com!george'` will match only match the first.
|
||||
* `--domains='example.com!george',example.com!john` will match both.
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: The quotes are required if your shell treats `!` as a special
|
||||
character, which is probably does. If you see an error that mentions
|
||||
`event not found` you probably forgot the quotes.
|
||||
{% endhint %}
|
||||
23
documentation/functions/global/DEFAULTS.md
Normal file
23
documentation/functions/global/DEFAULTS.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: DEFAULTS
|
||||
parameters:
|
||||
- modifiers...
|
||||
parameter_types:
|
||||
"modifiers...": RecordModifier[]
|
||||
---
|
||||
|
||||
`DEFAULTS` allows you to declare a set of default arguments to apply to all subsequent domains. Subsequent calls to [D](D.md) will have these
|
||||
arguments passed as if they were the first modifiers in the argument list.
|
||||
|
||||
```javascript
|
||||
var COMMON = NewDnsProvider("foo");
|
||||
// we want to create backup zone files for all domains, but not actually register them.
|
||||
// also create a default TTL
|
||||
DEFAULTS( DnsProvider(COMMON,0), DefaultTTL(1000));
|
||||
|
||||
D("example.com", REGISTRAR, DnsProvider("R53"), A("@","1.2.3.4")); // this domain will have the defaults set.
|
||||
|
||||
// clear defaults
|
||||
DEFAULTS();
|
||||
D("example2.com", REGISTRAR, DnsProvider("R53"), A("@","1.2.3.4")); // this domain will not have the previous defaults.
|
||||
```
|
||||
39
documentation/functions/global/DOMAIN_ELSEWHERE.md
Normal file
39
documentation/functions/global/DOMAIN_ELSEWHERE.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: DOMAIN_ELSEWHERE
|
||||
parameters:
|
||||
- registrar
|
||||
- nameserver_names
|
||||
parameter_types:
|
||||
registrar: string
|
||||
nameserver_names: string[]
|
||||
---
|
||||
|
||||
`DOMAIN_ELSEWHERE()` is a helper macro that lets you easily indicate that
|
||||
a domain's zones are managed elsewhere. That is, it permits you easily delegate
|
||||
a domain to a hard-coded list of DNS servers.
|
||||
|
||||
`DOMAIN_ELSEWHERE` is useful when you control a domain's registrar but not the
|
||||
DNS servers. For example, suppose you own a domain but the DNS servers are run
|
||||
by someone else, perhaps a SaaS product you've subscribed to or a DNS server
|
||||
that is run by your brother-in-law who doesn't trust you with the API keys that
|
||||
would let you maintain the domain using DNSControl. You need an easy way to
|
||||
point (delegate) the domain at a specific list of DNS servers.
|
||||
|
||||
For example these two statements are equivalent:
|
||||
|
||||
```javascript
|
||||
DOMAIN_ELSEWHERE("example.com", REG_NAMEDOTCOM, ["ns1.foo.com", "ns2.foo.com"]);
|
||||
|
||||
// ...is equivalent to...
|
||||
|
||||
D("example.com", REG_NAMEDOTCOM,
|
||||
NO_PURGE,
|
||||
NAMESERVER("ns1.foo.com"),
|
||||
NAMESERVER("ns2.foo.com")
|
||||
);
|
||||
```
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: The `NO_PURGE` is used out of abundance of caution but since no
|
||||
`DnsProvider()` statements exist, no updates would be performed.
|
||||
{% endhint %}
|
||||
42
documentation/functions/global/DOMAIN_ELSEWHERE_AUTO.md
Normal file
42
documentation/functions/global/DOMAIN_ELSEWHERE_AUTO.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: DOMAIN_ELSEWHERE_AUTO
|
||||
parameters:
|
||||
- domain
|
||||
- registrar
|
||||
- dns provider
|
||||
parameter_types:
|
||||
domain: string
|
||||
registrar: string
|
||||
dns provider: string
|
||||
---
|
||||
|
||||
`DOMAIN_ELSEWHERE_AUTO()` is similar to `DOMAIN_ELSEWHERE()` but instead of
|
||||
a hardcoded list of nameservers, a DnsProvider() is queried.
|
||||
|
||||
`DOMAIN_ELSEWHERE_AUTO` is useful when you control a domain's registrar but the
|
||||
DNS zones are managed by another system. Luckily you have enough access to that
|
||||
other system that you can query it to determine the zone's nameservers.
|
||||
|
||||
For example, suppose you own a domain but the DNS servers for it are in Azure.
|
||||
Further suppose that something in Azure maintains the zones (automatic or
|
||||
human). Azure picks the nameservers for the domains automatically, and that
|
||||
list may change occasionally. `DOMAIN_ELSEWHERE_AUTO` allows you to easily
|
||||
query Azure to determine the domain's delegations so that you do not need to
|
||||
hard-code them in your dnsconfig.js file.
|
||||
|
||||
For example these two statements are equivalent:
|
||||
|
||||
```javascript
|
||||
DOMAIN_ELSEWHERE_AUTO("example.com", REG_NAMEDOTCOM, DSP_AZURE);
|
||||
|
||||
// ...is equivalent to...
|
||||
|
||||
D("example.com", REG_NAMEDOTCOM,
|
||||
NO_PURGE,
|
||||
DnsProvider(DSP_AZURE)
|
||||
);
|
||||
```
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: The `NO_PURGE` is used to prevent DNSControl from changing the records.
|
||||
{% endhint %}
|
||||
87
documentation/functions/global/D_EXTEND.md
Normal file
87
documentation/functions/global/D_EXTEND.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
name: D_EXTEND
|
||||
parameters:
|
||||
- name
|
||||
- modifiers...
|
||||
parameter_types:
|
||||
name: string
|
||||
"modifiers...": DomainModifier[]
|
||||
---
|
||||
|
||||
`D_EXTEND` adds records (and metadata) to a domain previously defined
|
||||
by `D()`. It can also be used to add subdomain records (and metadata)
|
||||
to a previously defined domain.
|
||||
|
||||
The first argument is a domain name. If it exactly matches a
|
||||
previously defined domain, `D_EXTEND()` behaves the same as `D()`,
|
||||
simply adding records as if they had been specified in the original
|
||||
`D()`.
|
||||
|
||||
If the domain name does not match an existing domain, but could be a
|
||||
(non-delegated) subdomain of an existing domain, the new records (and
|
||||
metadata) are added with the subdomain part appended to all record
|
||||
names (labels), and targets (as appropriate). See the examples below.
|
||||
|
||||
Matching the domain name to previously-defined domains is done using a
|
||||
`longest match` algorithm. If `domain.tld` and `sub.domain.tld` are
|
||||
defined as separate domains via separate `D()` statements, then
|
||||
`D_EXTEND('sub.sub.domain.tld', ...)` would match `sub.domain.tld`,
|
||||
not `domain.tld`.
|
||||
|
||||
Some operators only act on an apex domain (e.g.
|
||||
`CF_REDIRECT` and `CF_TEMP_REDIRECT`). Using them
|
||||
in a `D_EXTEND` subdomain may not be what you expect.
|
||||
|
||||
```javascript
|
||||
D("domain.tld", REG, DnsProvider(DNS),
|
||||
A("@", "127.0.0.1"), // domain.tld
|
||||
A("www", "127.0.0.2"), // www.domain.tld
|
||||
CNAME("a", "b") // a.domain.tld -> b.domain.tld
|
||||
);
|
||||
D_EXTEND("domain.tld",
|
||||
A("aaa", "127.0.0.3"), // aaa.domain.tld
|
||||
CNAME("c", "d") // c.domain.tld -> d.domain.tld
|
||||
);
|
||||
D_EXTEND("sub.domain.tld",
|
||||
A("bbb", "127.0.0.4"), // bbb.sub.domain.tld
|
||||
A("ccc", "127.0.0.5"), // ccc.sub.domain.tld
|
||||
CNAME("e", "f") // e.sub.domain.tld -> f.sub.domain.tld
|
||||
);
|
||||
D_EXTEND("sub.sub.domain.tld",
|
||||
A("ddd", "127.0.0.6"), // ddd.sub.sub.domain.tld
|
||||
CNAME("g", "h") // g.sub.sub.domain.tld -> h.sub.sub.domain.tld
|
||||
);
|
||||
D_EXTEND("sub.domain.tld",
|
||||
A("@", "127.0.0.7"), // sub.domain.tld
|
||||
CNAME("i", "j") // i.sub.domain.tld -> j.sub.domain.tld
|
||||
);
|
||||
```
|
||||
|
||||
This will end up in the following modifications: (This output assumes the `--verbose` flag)
|
||||
|
||||
```text
|
||||
******************** Domain: domain.tld
|
||||
----- Getting nameservers from: cloudflare
|
||||
----- DNS Provider: cloudflare...7 corrections
|
||||
#1: CREATE A aaa.domain.tld 127.0.0.3
|
||||
#2: CREATE A bbb.sub.domain.tld 127.0.0.4
|
||||
#3: CREATE A ccc.sub.domain.tld 127.0.0.5
|
||||
#4: CREATE A ddd.sub.sub.domain.tld 127.0.0.6
|
||||
#5: CREATE A sub.domain.tld 127.0.0.7
|
||||
#6: CREATE A www.domain.tld 127.0.0.2
|
||||
#7: CREATE A domain.tld 127.0.0.1
|
||||
#8: CREATE CNAME a.domain.tld b.domain.tld.
|
||||
#9: CREATE CNAME c.domain.tld d.domain.tld.
|
||||
#10: CREATE CNAME e.sub.domain.tld f.sub.domain.tld.
|
||||
#11: CREATE CNAME g.sub.sub.domain.tld h.sub.sub.domain.tld.
|
||||
#12: CREATE CNAME i.sub.domain.tld j.sub.domain.tld.
|
||||
```
|
||||
|
||||
ProTips: `D_EXTEND()` permits you to create very complex and
|
||||
sophisticated configurations, but you shouldn't. Be nice to the next
|
||||
person that edits the file, who may not be as expert as yourself.
|
||||
Enhance readability by putting any `D_EXTEND()` statements immediately
|
||||
after the original `D()`, like in above example. Avoid the temptation
|
||||
to obscure the addition of records to existing domains with randomly
|
||||
placed `D_EXTEND()` statements. Don't build up a domain using loops of
|
||||
`D_EXTEND()` statements. You'll be glad you didn't.
|
||||
44
documentation/functions/global/FETCH.md
Normal file
44
documentation/functions/global/FETCH.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: FETCH
|
||||
parameters:
|
||||
- url
|
||||
- args
|
||||
ts_ignore: true
|
||||
# Make sure to update fetch.d.ts if changing the docs below!
|
||||
---
|
||||
|
||||
`FETCH` is a wrapper for the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). This allows dynamically setting DNS records based on an external data source, e.g. the API of your cloud provider.
|
||||
|
||||
Compared to `fetch` from Fetch API, `FETCH` will call [PANIC](PANIC.md) to terminate the execution of the script, and therefore DNSControl, if a network error occurs.
|
||||
|
||||
Otherwise the syntax of `FETCH` is the same as `fetch`.
|
||||
|
||||
`FETCH` is not enabled by default. Please read the warnings below.
|
||||
|
||||
> WARNING:
|
||||
>
|
||||
> 1. Relying on external sources adds a point of failure. If the external source doesn't work, your script won't either. Please make sure you are aware of the consequences.
|
||||
> 2. Make sure DNSControl only uses verified configuration if you want to use `FETCH`. For example, an attacker can send Pull Requests to your config repo, and have your CI test malicious configurations and make arbitrary HTTP requests. Therefore, `FETCH` must be explicitly enabled with flag `--allow-fetch` on DNSControl invocation.
|
||||
|
||||
```javascript
|
||||
var REG_NONE = NewRegistrar('none');
|
||||
var DNS_BIND = NewDnsProvider('bind');
|
||||
|
||||
D('example.com', REG_NONE, DnsProvider(DNS_BIND), [
|
||||
A('@', '1.2.3.4'),
|
||||
]);
|
||||
|
||||
FETCH('https://example.com', {
|
||||
// All three options below are optional
|
||||
headers: {"X-Authentication": "barfoo"},
|
||||
method: "POST",
|
||||
body: "Hello World",
|
||||
}).then(function(r) {
|
||||
return r.text();
|
||||
}).then(function(t) {
|
||||
// Example of generating record based on response
|
||||
D_EXTEND('example.com', [
|
||||
TXT('@', t.slice(0, 100)),
|
||||
]);
|
||||
});
|
||||
```
|
||||
29
documentation/functions/global/IP.md
Normal file
29
documentation/functions/global/IP.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: IP
|
||||
parameters:
|
||||
- ip
|
||||
parameter_types:
|
||||
ip: string
|
||||
return: number
|
||||
---
|
||||
|
||||
Converts an IPv4 address from string to an integer. This allows performing mathematical operations with the IP address.
|
||||
|
||||
```javascript
|
||||
var addrA = IP('1.2.3.4')
|
||||
var addrB = addrA + 1
|
||||
// addrB = 1.2.3.5
|
||||
```
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: `IP()` does not accept IPv6 addresses (PRs gladly accepted!). IPv6 addresses are simply strings:
|
||||
{% endhint %}
|
||||
|
||||
```javascript
|
||||
// IPv4 Var
|
||||
var addrA1 = IP("1.2.3.4");
|
||||
var addrA2 = "1.2.3.4";
|
||||
|
||||
// IPv6 Var
|
||||
var addrAAAA = "0:0:0:0:0:0:0:0";
|
||||
```
|
||||
46
documentation/functions/global/NewDnsProvider.md
Normal file
46
documentation/functions/global/NewDnsProvider.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: NewDnsProvider
|
||||
parameters:
|
||||
- name
|
||||
- type
|
||||
- meta
|
||||
parameter_types:
|
||||
name: string
|
||||
type: string?
|
||||
meta: object?
|
||||
return: string
|
||||
---
|
||||
|
||||
NewDnsProvider activates a DNS Service Provider (DSP) specified in `creds.json`.
|
||||
A DSP stores a DNS zone's records and provides DNS service for the zone (i.e.
|
||||
answers on port 53 to queries related to the zone).
|
||||
|
||||
* `name` must match the name of an entry in `creds.json`.
|
||||
* `type` specifies a valid DNS provider type identifier listed on the [provider page](../../providers.md).
|
||||
* Starting with [v3.16](../../v316.md), the type is optional. If it is absent, the `TYPE` field in `creds.json` is used instead. You can leave it out. (Thanks to JavaScript magic, you can leave it out even when there are more fields).
|
||||
* Starting with v4.0, specifying the type may be an error. Please add the `TYPE` field to `creds.json` and remove this parameter from `dnsconfig.js` to prepare.
|
||||
* `meta` is a way to send additional parameters to the provider. It is optional and only certain providers use it. See the [individual provider docs](../../providers.md) for details.
|
||||
|
||||
This function will return an opaque string that should be assigned to a variable name for use in [D](D.md) directives.
|
||||
|
||||
Prior to [v3.16](../../v316.md):
|
||||
|
||||
```javascript
|
||||
var REG_MYNDC = NewRegistrar("mynamedotcom", "NAMEDOTCOM");
|
||||
var DNS_MYAWS = NewDnsProvider("myaws", "ROUTE53");
|
||||
|
||||
D("example.com", REG_MYNDC, DnsProvider(DNS_MYAWS),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
|
||||
In [v3.16](../../v316.md) and later:
|
||||
|
||||
```javascript
|
||||
var REG_MYNDC = NewRegistrar("mynamedotcom");
|
||||
var DNS_MYAWS = NewDnsProvider("myaws");
|
||||
|
||||
D("example.com", REG_MYNDC, DnsProvider(DNS_MYAWS),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
46
documentation/functions/global/NewRegistrar.md
Normal file
46
documentation/functions/global/NewRegistrar.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: NewRegistrar
|
||||
parameters:
|
||||
- name
|
||||
- type
|
||||
- meta
|
||||
parameter_types:
|
||||
name: string
|
||||
type: string?
|
||||
meta: object?
|
||||
return: string
|
||||
---
|
||||
|
||||
NewRegistrar activates a Registrar Provider specified in `creds.json`.
|
||||
A registrar maintains the domain's registration and delegation (i.e. the
|
||||
nameservers for the domain). DNSControl only manages the delegation.
|
||||
|
||||
* `name` must match the name of an entry in `creds.json`.
|
||||
* `type` specifies a valid DNS provider type identifier listed on the [provider page](../../providers.md).
|
||||
* Starting with [v3.16](../../v316.md), the type is optional. If it is absent, the `TYPE` field in `creds.json` is used instead. You can leave it out. (Thanks to JavaScript magic, you can leave it out even when there are more fields).
|
||||
* Starting with v4.0, specifying the type may be an error. Please add the `TYPE` field to `creds.json` and remove this parameter from `dnsconfig.js` to prepare.
|
||||
* `meta` is a way to send additional parameters to the provider. It is optional and only certain providers use it. See the [individual provider docs](../../providers.md) for details.
|
||||
|
||||
This function will return an opaque string that should be assigned to a variable name for use in [D](D.md) directives.
|
||||
|
||||
Prior to [v3.16](../../v316.md):
|
||||
|
||||
```javascript
|
||||
var REG_MYNDC = NewRegistrar("mynamedotcom", "NAMEDOTCOM");
|
||||
var DNS_MYAWS = NewDnsProvider("myaws", "ROUTE53");
|
||||
|
||||
D("example.com", REG_MYNDC, DnsProvider(DNS_MYAWS),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
|
||||
In [v3.16](../../v316.md) and later:
|
||||
|
||||
```javascript
|
||||
var REG_MYNDC = NewRegistrar("mynamedotcom");
|
||||
var DNS_MYAWS = NewDnsProvider("myaws");
|
||||
|
||||
D("example.com", REG_MYNDC, DnsProvider(DNS_MYAWS),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
14
documentation/functions/global/PANIC.md
Normal file
14
documentation/functions/global/PANIC.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: PANIC
|
||||
parameters:
|
||||
- message
|
||||
parameter_types:
|
||||
message: string
|
||||
ts_return: never
|
||||
---
|
||||
|
||||
`PANIC` terminates the script and therefore DNSControl with an exit code of 1. This should be used if your script cannot gather enough information to generate records, for example when a HTTP request failed.
|
||||
|
||||
```javascript
|
||||
PANIC("Something really bad has happened");
|
||||
```
|
||||
54
documentation/functions/global/REV.md
Normal file
54
documentation/functions/global/REV.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: REV
|
||||
parameters:
|
||||
- address
|
||||
parameter_types:
|
||||
address: string
|
||||
ts_return: string
|
||||
---
|
||||
|
||||
`REV` returns the reverse lookup domain for an IP network. For
|
||||
example `REV('1.2.3.0/24')` returns `3.2.1.in-addr.arpa.` and
|
||||
`REV('2001:db8:302::/48)` returns `2.0.3.0.8.b.d.0.1.0.0.2.ip6.arpa.`.
|
||||
This is used in `D()` functions to create reverse DNS lookup zones.
|
||||
|
||||
This is a convenience function. You could specify `D('3.2.1.in-addr.arpa',
|
||||
...` if you like to do things manually but why would you risk making
|
||||
typos?
|
||||
|
||||
`REV` complies with RFC2317, "Classless in-addr.arpa delegation"
|
||||
for netmasks of size /25 through /31.
|
||||
While the RFC permits any format, we abide by the recommended format:
|
||||
`FIRST/MASK.C.B.A.in-addr.arpa` where `FIRST` is the first IP address
|
||||
of the zone, `MASK` is the netmask of the zone (25-31 inclusive),
|
||||
and A, B, C are the first 3 octets of the IP address. For example
|
||||
`172.20.18.130/27` is located in a zone named
|
||||
`128/27.18.20.172.in-addr.arpa`
|
||||
|
||||
If the address does not include a "/" then `REV` assumes /32 for IPv4 addresses
|
||||
and /128 for IPv6 addresses.
|
||||
|
||||
Note that the lower bits (the ones outside the netmask) must be zeros. They are not
|
||||
zeroed out automatically. Thus, `REV('1.2.3.4/24')` is an error. This is done
|
||||
to catch typos.
|
||||
|
||||
```javascript
|
||||
D(REV('1.2.3.0/24'), REGISTRAR, DnsProvider(BIND),
|
||||
PTR("1", 'foo.example.com.'),
|
||||
PTR("2", 'bar.example.com.'),
|
||||
PTR("3", 'baz.example.com.'),
|
||||
// These take advantage of DNSControl's ability to generate the right name:
|
||||
PTR("1.2.3.10", 'ten.example.com.'),
|
||||
);
|
||||
|
||||
D(REV('2001:db8:302::/48'), REGISTRAR, DnsProvider(BIND),
|
||||
PTR("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0", 'foo.example.com.'), // 2001:db8:302::1
|
||||
// These take advantage of DNSControl's ability to generate the right name:
|
||||
PTR("2001:db8:302::2", 'two.example.com.'), // 2.0.0...
|
||||
PTR("2001:db8:302::3", 'three.example.com.'), // 3.0.0...
|
||||
);
|
||||
```
|
||||
|
||||
In the future we plan on adding a flag to `A()` which will insert
|
||||
the correct PTR() record if the appropriate `D(REV()` domain (i.e. `.arpa` domain) has been
|
||||
defined.
|
||||
62
documentation/functions/global/getConfiguredDomains.md
Normal file
62
documentation/functions/global/getConfiguredDomains.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
name: getConfiguredDomains
|
||||
ts_is_function: true
|
||||
ts_return: string[]
|
||||
---
|
||||
|
||||
`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:
|
||||
```javascript
|
||||
var domains = getConfiguredDomains();
|
||||
for(i = 0; i < domains.length; i++) {
|
||||
D_EXTEND(domains[i],
|
||||
TXT('_important', 'BLA') // I know, not really creative.
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
This will end up in following modifications: (All output assumes the `--verbose` flag)
|
||||
|
||||
|
||||
```text
|
||||
******************** 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
|
||||
```
|
||||
|
||||
Example for adding DMARC report records:
|
||||
|
||||
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.
|
||||
|
||||
```javascript
|
||||
var domains = getConfiguredDomains();
|
||||
for(i = 0; i < domains.length; i++) {
|
||||
D_EXTEND("domain1.tld",
|
||||
TXT(domains[i] + '._report._dmarc', 'v=DMARC1')
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
This will end up in following modifications:
|
||||
|
||||
```text
|
||||
******************** 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
|
||||
```
|
||||
92
documentation/functions/global/require.md
Normal file
92
documentation/functions/global/require.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
name: require
|
||||
parameters:
|
||||
- path
|
||||
ts_ignore: true
|
||||
---
|
||||
|
||||
`require(...)` loads the specified JavaScript or JSON file, allowing
|
||||
to split your configuration across multiple files.
|
||||
|
||||
If the supplied `path` string ends with `.js`, the file is interpreted
|
||||
as JavaScript code, almost as though its contents had been included in
|
||||
the currently-executing file. If the path string ends with `.json`,
|
||||
`require()` returns the `JSON.parse()` of the file's contents.
|
||||
|
||||
If the path string begins with a `.`, it is interpreted relative to
|
||||
the currently-loading file (which may not be the file where the
|
||||
`require()` statement is, if called within a function), otherwise it
|
||||
is interpreted relative to the program's working directory at the time
|
||||
of the call.
|
||||
|
||||
```javascript
|
||||
// dnsconfig.js
|
||||
require('kubernetes/clusters.js');
|
||||
|
||||
D("mydomain.net", REG, PROVIDER,
|
||||
IncludeKubernetes()
|
||||
);
|
||||
```
|
||||
|
||||
```javascript
|
||||
// kubernetes/clusters.js
|
||||
require('./clusters/prod.js');
|
||||
require('./clusters/dev.js');
|
||||
|
||||
function IncludeKubernetes() {
|
||||
return [includeK8Sprod(), includeK8Sdev()];
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
// kubernetes/clusters/prod.js
|
||||
function includeK8Sprod() {
|
||||
return [
|
||||
// ...
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
// kubernetes/clusters/dev.js
|
||||
function includeK8Sdev() {
|
||||
return [
|
||||
// ...
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
You can also use it to require JSON files and initialize variables with it:
|
||||
|
||||
```javascript
|
||||
// dnsconfig.js
|
||||
var domains = require('./domain-ip-map.json')
|
||||
|
||||
for (var domain in domains) {
|
||||
D(domain, REG, PROVIDER,
|
||||
A("@", domains[domain])
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
// domain-ip-map.json
|
||||
{
|
||||
"mydomain.net": "1.1.1.1",
|
||||
"myotherdomain.org": "5.5.5.5"
|
||||
}
|
||||
```
|
||||
|
||||
# Future
|
||||
|
||||
It might be better to rename the function to something like
|
||||
`include()` instead, (leaving `require` as a deprecated alias) because
|
||||
by analogy it is *much* closer to PHP's `include()` function than it
|
||||
is to node's `require()`. After all, the reason node.js calls it
|
||||
"require" is because it's a declarative statement saying the file is
|
||||
needed, and so should be loaded if it hasn't already been loaded.
|
||||
|
||||
In contrast, dnscontrol's require is actually an imperative command to
|
||||
load the file and execute the code or parse the data from it. (So if
|
||||
two files both `require("./tools.js")`, for example, then it will be
|
||||
loaded twice, whereas in node.js it would only be loaded once.)
|
||||
46
documentation/functions/global/require_glob.md
Normal file
46
documentation/functions/global/require_glob.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: require_glob
|
||||
parameters:
|
||||
- path
|
||||
- recursive
|
||||
parameter_types:
|
||||
path: string
|
||||
recursive: boolean
|
||||
---
|
||||
|
||||
`require_glob()` can recursively load `.js` files, optionally non-recursive as well.
|
||||
|
||||
Possible parameters are:
|
||||
|
||||
- Path as string, where you would like to start including files. Mandatory. Pattern matching possible, see [GoLand path/filepath/#Match docs](https://golang.org/pkg/path/filepath/#Match).
|
||||
- If being recursive. This is a boolean if the search should be recursive or not. Define either `true` or `false`. Default is `true`.
|
||||
|
||||
Example to load `.js` files recursively:
|
||||
|
||||
```javascript
|
||||
require_glob("./domains/");
|
||||
```
|
||||
|
||||
Example to load `.js` files only in `domains/`:
|
||||
|
||||
```javascript
|
||||
require_glob("./domains/", false);
|
||||
```
|
||||
|
||||
One more important thing to note: `require_glob()` is as smart as `require()` is. It loads files always relative to the JavaScript
|
||||
file where it's being executed in. Let's go with an example, as it describes it better:
|
||||
|
||||
`dnscontrol.js`:
|
||||
|
||||
```javascript
|
||||
require("domains/index.js");
|
||||
```
|
||||
|
||||
`domains/index.js`:
|
||||
|
||||
```javascript
|
||||
require_glob("./user1/");
|
||||
```
|
||||
|
||||
This will now load files being present underneath `./domains/user1/` and **NOT** at below `./domains/`, as `require_glob()`
|
||||
is called in the subfolder `domains/`.
|
||||
Reference in New Issue
Block a user