mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
DOCS: Documentation directory structure (#2905)
This commit is contained in:
committed by
GitHub
parent
17d644cfc6
commit
c31064781f
100
documentation/language-reference/top-level-functions/D.md
Normal file
100
documentation/language-reference/top-level-functions/D.md
Normal file
@ -0,0 +1,100 @@
|
||||
---
|
||||
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-modifiers/A.md), [CNAME](../domain-modifiers/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-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.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
// simple domain
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
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", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
A("@","1.2.3.4"),
|
||||
CNAME("test", "foo.example2.com."),
|
||||
GOOGLE_APPS_DOMAIN_MX
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
|
||||
# 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`.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var REG_THIRDPARTY = NewRegistrar("ThirdParty");
|
||||
var DNS_INSIDE = NewDnsProvider("Cloudflare");
|
||||
var DNS_OUTSIDE = NewDnsProvider("bind");
|
||||
|
||||
D("example.com!inside", REG_THIRDPARTY, DnsProvider(DNS_INSIDE),
|
||||
A("www", "10.10.10.10")
|
||||
);
|
||||
|
||||
D("example.com!outside", REG_THIRDPARTY, DnsProvider(DNS_OUTSIDE),
|
||||
A("www", "20.20.20.20")
|
||||
);
|
||||
|
||||
D_EXTEND("example.com!inside",
|
||||
A("internal", "10.99.99.99")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
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` matches the full name (with the "!"). 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 %}
|
@ -0,0 +1,42 @@
|
||||
---
|
||||
name: DEFAULTS
|
||||
parameters:
|
||||
- modifiers...
|
||||
parameter_types:
|
||||
"modifiers...": DomainModifier[]
|
||||
---
|
||||
|
||||
`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.
|
||||
|
||||
## Example
|
||||
|
||||
We want to create backup zone files for all domains, but not actually register them. Also create a [`DefaultTTL`](../domain-modifiers/DefaultTTL.md).
|
||||
The domain `example.com` will have the defaults set.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var COMMON = NewDnsProvider("foo");
|
||||
DEFAULTS(
|
||||
DnsProvider(COMMON, 0),
|
||||
DefaultTTL("1d")
|
||||
);
|
||||
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
If you want to clear the defaults, you can do the following.
|
||||
The domain `example2.com` will **not** have the defaults set.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
DEFAULTS();
|
||||
|
||||
D("example2.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
@ -0,0 +1,45 @@
|
||||
---
|
||||
name: DOMAIN_ELSEWHERE
|
||||
parameters:
|
||||
- name
|
||||
- registrar
|
||||
- nameserver_names
|
||||
parameter_types:
|
||||
name: string
|
||||
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:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
DOMAIN_ELSEWHERE("example.com", REG_MY_PROVIDER, ["ns1.foo.com", "ns2.foo.com"]);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
NO_PURGE,
|
||||
NAMESERVER("ns1.foo.com"),
|
||||
NAMESERVER("ns2.foo.com")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: The [`NO_PURGE`](../domain-modifiers/NO_PURGE.md) is used out of abundance of caution but since no
|
||||
`DnsProvider()` statements exist, no updates would be performed.
|
||||
{% endhint %}
|
@ -0,0 +1,48 @@
|
||||
---
|
||||
name: DOMAIN_ELSEWHERE_AUTO
|
||||
parameters:
|
||||
- name
|
||||
- domain
|
||||
- registrar
|
||||
- dns provider
|
||||
parameter_types:
|
||||
name: string
|
||||
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:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
DOMAIN_ELSEWHERE_AUTO("example.com", REG_NAMEDOTCOM, DSP_AZURE);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("example.com", REG_NAMEDOTCOM,
|
||||
NO_PURGE,
|
||||
DnsProvider(DSP_AZURE)
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: The [`NO_PURGE`](../domain-modifiers/NO_PURGE.md) is used to prevent DNSControl from changing the records.
|
||||
{% endhint %}
|
@ -0,0 +1,89 @@
|
||||
---
|
||||
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()`](D.md). 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()`](D.md),
|
||||
simply adding records as if they had been specified in the original
|
||||
[`D()`](D.md).
|
||||
|
||||
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()`](D.md) 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`](../domain-modifiers/CF_REDIRECT.md) and [`CF_TEMP_REDIRECT`](../domain-modifiers/CF_TEMP_REDIRECT.md)). Using them
|
||||
in a `D_EXTEND` subdomain may not be what you expect.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("domain.tld", REG_MY_PROVIDER, 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
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
This will end up in the following modifications: (This output assumes the `--full` 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()`](D.md), 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.
|
@ -0,0 +1,43 @@
|
||||
---
|
||||
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.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER), [
|
||||
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)),
|
||||
]);
|
||||
});
|
||||
```
|
||||
{% endcode %}
|
33
documentation/language-reference/top-level-functions/IP.md
Normal file
33
documentation/language-reference/top-level-functions/IP.md
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
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.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var addrA = IP("1.2.3.4")
|
||||
var addrB = addrA + 1
|
||||
// addrB = 1.2.3.5
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% hint style="info" %}
|
||||
**NOTE**: `IP()` does not accept IPv6 addresses (PRs gladly accepted!). IPv6 addresses are simply strings:
|
||||
{% endhint %}
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```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";
|
||||
```
|
||||
{% endcode %}
|
@ -0,0 +1,50 @@
|
||||
---
|
||||
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):
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```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")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
In [v3.16](../../v316.md) and later:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var REG_MYNDC = NewRegistrar("mynamedotcom");
|
||||
var DNS_MYAWS = NewDnsProvider("myaws");
|
||||
|
||||
D("example.com", REG_MYNDC, DnsProvider(DNS_MYAWS),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
@ -0,0 +1,50 @@
|
||||
---
|
||||
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):
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```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")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
In [v3.16](../../v316.md) and later:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var REG_MYNDC = NewRegistrar("mynamedotcom");
|
||||
var DNS_MYAWS = NewDnsProvider("myaws");
|
||||
|
||||
D("example.com", REG_MYNDC, DnsProvider(DNS_MYAWS),
|
||||
A("@","1.2.3.4")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
PANIC("Something really bad has happened");
|
||||
```
|
||||
{% endcode %}
|
81
documentation/language-reference/top-level-functions/REV.md
Normal file
81
documentation/language-reference/top-level-functions/REV.md
Normal file
@ -0,0 +1,81 @@
|
||||
---
|
||||
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.`.
|
||||
|
||||
`REV()` is commonly used with the [`D()`](D.md) functions to create reverse DNS lookup zones.
|
||||
|
||||
These two are equivalent:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("3.2.1.in-addr.arpa", ...
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D(REV("1.2.3.0/24", ...
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
The latter is easier to type and less error-prone.
|
||||
|
||||
If the address does not include a "/" then `REV()` assumes /32 for IPv4 addresses
|
||||
and /128 for IPv6 addresses.
|
||||
|
||||
# RFC compliance
|
||||
|
||||
`REV()` implements both RFC 2317 and the newer RFC 4183. The `REVCOMPAT()`
|
||||
function selects which mode is used. If `REVCOMPAT()` is not called, a default
|
||||
is selected for you. The default will change to RFC 4183 in DNSControl v5.0.
|
||||
|
||||
See [`REVCOMPAT()`](REVCOMPAT.md) for details.
|
||||
|
||||
|
||||
# Host bits
|
||||
|
||||
v4.x:
|
||||
The host 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.
|
||||
|
||||
v5.0 and later:
|
||||
The host bits (the ones outside the netmask) are ignored. Thus
|
||||
`REV("1.2.3.4/24")` and `REV("1.2.3.0/24")` are equivalent.
|
||||
|
||||
# Examples
|
||||
|
||||
Here's an example reverse lookup domain:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```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."),
|
||||
// If the first parameter is an IP address, DNSControl automatically calls REV() for you.
|
||||
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
|
||||
// If the first parameter is an IP address, DNSControl automatically calls REV() for you.
|
||||
PTR("2001:db8:302::2", "two.example.com."), // 2.0.0...
|
||||
PTR("2001:db8:302::3", "three.example.com."), // 3.0.0...
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
# Automatic forward and reverse record generation
|
||||
|
||||
DNSControl does not automatically generate forward and reverse lookups. However
|
||||
it is possible to write a macro that does this. See
|
||||
[`PTR()`](../domain/PTR.md) for an example.
|
@ -0,0 +1,47 @@
|
||||
---
|
||||
name: REVCOMPAT
|
||||
parameters:
|
||||
- rfc
|
||||
parameter_types:
|
||||
rfc: string
|
||||
ts_return: string
|
||||
---
|
||||
|
||||
`REVCOMPAT()` controls which RFC the [`REV()`](REV.md) function adheres to.
|
||||
|
||||
Include one of these two commands near the top `dnsconfig.js` (at the global level):
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
REVCOMPAT("rfc2317"); // RFC 2117: Compatible with old files.
|
||||
REVCOMPAT("rfc4183"); // RFC 4183: Adopt the newer standard.
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
`REVCOMPAT()` is global for all of `dnsconfig.js`. It must appear before any
|
||||
use of `REV()`; If not, behavior is undefined.
|
||||
|
||||
# RFC 4183 vs RFC 2317
|
||||
|
||||
RFC 2317 and RFC 4183 are two different ways to implement reverse lookups for
|
||||
CIDR blocks that are not on 8-bit boundaries (/24, /16, /8).
|
||||
|
||||
Originally DNSControl implemented the older standard, which only specifies what
|
||||
to do for /8, /16, /24 - /32. Using `REV()` for /9-17 and /17-23 CIDRs was an
|
||||
error.
|
||||
|
||||
v4 defaults to RFC 2317. In v5.0 the default will change to RFC 4183.
|
||||
`REVCOMPAT()` is provided for those that wish to retain the old behavior.
|
||||
|
||||
For more information, see [Opinion #9](../../opinions.md#opinion-9-rfc-4183-is-better-than-rfc-2317).
|
||||
|
||||
# Transition plan
|
||||
|
||||
What's the default behavior if `REVCOMPAT()` is not used?
|
||||
|
||||
| Version | /9 to /15 and /17 to /23 | /25 to 32 | Warnings |
|
||||
|---------|--------------------------|-----------|----------------------------|
|
||||
| v4 | RFC 4183 | RFC 2317 | Only if /25 - /32 are used |
|
||||
| v5 | RFC 4183 | RFC 4183 | none |
|
||||
|
||||
No warnings are generated if the `REVCOMPAT()` function is used.
|
@ -0,0 +1,66 @@
|
||||
---
|
||||
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:
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var domains = getConfiguredDomains();
|
||||
for(i = 0; i < domains.length; i++) {
|
||||
D_EXTEND(domains[i],
|
||||
TXT("_important", "BLA") // I know, not really creative.
|
||||
)
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
This will end up in following modifications: (All output assumes the `--full` 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.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var domains = getConfiguredDomains();
|
||||
for(i = 0; i < domains.length; i++) {
|
||||
D_EXTEND("domain1.tld",
|
||||
TXT(domains[i] + "._report._dmarc", "v=DMARC1")
|
||||
);
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
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
|
||||
```
|
118
documentation/language-reference/top-level-functions/require.md
Normal file
118
documentation/language-reference/top-level-functions/require.md
Normal file
@ -0,0 +1,118 @@
|
||||
---
|
||||
name: require
|
||||
parameters:
|
||||
- path
|
||||
ts_ignore: true
|
||||
---
|
||||
|
||||
`require(...)` loads the specified JavaScript or JSON file, allowing
|
||||
to split your configuration across multiple files.
|
||||
|
||||
A better name for this function might be "include".
|
||||
|
||||
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.
|
||||
|
||||
### Example 1: Simple
|
||||
|
||||
In this example, we separate our macros in one file, and put groups of domains
|
||||
in 3 other files. The result is a cleaner separation of code vs. domains.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require("lib/macros.json");
|
||||
|
||||
require("domains/main.json");
|
||||
require("domains/parked.json");
|
||||
require("domains/otherstuff.json");
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
### Example 2: Complex
|
||||
|
||||
Here's a more complex example:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require("kubernetes/clusters.js");
|
||||
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
IncludeKubernetes()
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="kubernetes/clusters.js" %}
|
||||
```javascript
|
||||
require("./clusters/prod.js");
|
||||
require("./clusters/dev.js");
|
||||
|
||||
function IncludeKubernetes() {
|
||||
return [includeK8Sprod(), includeK8Sdev()];
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="kubernetes/clusters/prod.js" %}
|
||||
```javascript
|
||||
function includeK8Sprod() {
|
||||
return [
|
||||
// ...
|
||||
];
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="kubernetes/clusters/dev.js" %}
|
||||
```javascript
|
||||
function includeK8Sdev() {
|
||||
return [
|
||||
// ...
|
||||
];
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
### Example 3: JSON
|
||||
|
||||
Requiring JSON files initializes variables:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
var domains = require("./domain-ip-map.json")
|
||||
|
||||
for (var domain in domains) {
|
||||
D(domain, REG_MY_PROVIDER, PROVIDER,
|
||||
A("@", domains[domain])
|
||||
);
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="domain-ip-map.json" %}
|
||||
```javascript
|
||||
{
|
||||
"example.com": "1.1.1.1",
|
||||
"other-example.com``": "5.5.5.5"
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
# Notes
|
||||
|
||||
`require()` is *much* closer to PHP's `include()` function than it
|
||||
is to node's `require()`.
|
||||
|
||||
Node's `require()` only includes a file once.
|
||||
In contrast, DNSControl's `require()` is actually an imperative command to
|
||||
load the file and execute the code or parse the data from it. For example if
|
||||
two files both `require("./tools.js")`, then it will be
|
||||
loaded twice, whereas in node.js it would only be loaded once.
|
@ -0,0 +1,52 @@
|
||||
---
|
||||
name: require_glob
|
||||
parameters:
|
||||
- path
|
||||
- recursive
|
||||
parameter_types:
|
||||
path: string
|
||||
recursive: boolean
|
||||
---
|
||||
|
||||
`require_glob()` recursively loads `.js` files that match a glob (wildcard). The recursion can be disabled.
|
||||
|
||||
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:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require_glob("./domains/");
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Example to load `.js` files only in `domains/`:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require_glob("./domains/", false);
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
# Comparison to require()
|
||||
|
||||
`require_glob()` and `require()` both use the same rules for determining which directory path is
|
||||
relative to.
|
||||
|
||||
This will load files being present underneath `./domains/user1/` and **NOT** at below `./domains/`, as `require_glob()`
|
||||
is called in the subfolder `domains/`.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require("domains/index.js");
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="domains/index.js" %}
|
||||
```javascript
|
||||
require_glob("./user1/");
|
||||
```
|
||||
{% endcode %}
|
Reference in New Issue
Block a user