DOCS: Improve cli-variables.md (#1328)

* DOCS: Rewrite cli-variables.md
This commit is contained in:
Tom Limoncelli 2021-12-14 16:29:01 -05:00 committed by GitHub
parent 02c5258396
commit 14c3014a2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,61 +4,133 @@ title: CLI variables
---
# CLI variables
With dnscontrol you can pass variables from CLI into your `dnsconfig.js`.
You can pass variables into your configuration from the command line using the `-v key=value` flag. There is also a mechanism called `CLI_DEFAULTS` which lets you easily set the defaults on variables that are otherwise controlled from the command line.
This gives you the opportunity to run different code when a value is passed.
## 1. Passing variables
To pass a variable from CLI, just use the parameter `-v key=value` of the commands `preview` or `push`.
## Passing variables
Example: `dnscontrol push -v testKey=testValue`
To pass a variable from CLI, just use the parameter `-v key=value` when using subcommands `preview` or `push`.
This would pass the variable with the name `testKey` and the value of `testValue` to `dnsconfig.js`
Example: `dnscontrol preview -v testKey=testValue`
## 2. Define defaults
If you want to define some default values, that are used when no variable is passed from CLI,
you can do this with the following function:
This would set the variable with the name `testKey` and the value of `testValue` when processing `dnsconfig.js`
## Define defaults
The `CLI_DEFAULTS` feature is used to define default values for when a variable is not defined on the command line.
```js
CLI_DEFAULTS({
'testValue': 'defaultValue'
"variableName": "defaultValue",
});
```
You need to define this defaults just once in your `dnsconfig.js`.
Define the defaults **before** using it.
You need to define this defaults just once in your `dnsconfig.js`. It should be defined **before** using it.
_Please keep in mind, if there is no default value and you do not pass a variable, but you are using it in your `dnsconfig.js` it will fail!_
_Please keep in mind that accessing an undefined variable is an error. If it is not set on the command line nor in `CLI_DEFAULTS`, accessing the variable will fail._
## 3. Use cases
See some use cases for CLI variables.
## Example 1: Different IPs for internal/external DNS
In this example we have a number of variables which need to be set differently when `view=internal`.
In this configuration:
* `dnscontrol push` would generate the external (default) view.
* `dnscontrol push -v view=internal` would generate the internal view.
#### Different IPs for internal/external DNS
```js
// See https://stackexchange.github.io/dnscontrol/cli-variables
CLI_DEFAULTS({
'cliServer': 'external'
"view": "external",
});
if (this.view == "internal") {
if (view == "external") {
// BIND view: external (192.168.0.0/16 addresses)
var host01 = "192.168.0.16";
var host02 = "192.168.0.17";
} else {
// BIND view: internal (10.0.0.0/8 addresses)
var host01 = "10.0.0.16";
var host02 = "10.0.0.17";
}
D("example.org", registrar, DnsProvider(public), DnsProvider(bind),
A('sitea', host01, TTL(1800)),
A('siteb', host01, TTL(1800)),
A('sitec', host02, TTL(1800)),
A('sited', host02, TTL(1800))
/// ...much later...
D("example.org", REG_NAMECOM, DnsProvider(DNS_NAMECOM), DnsProvider(DNS_BIND),
A("sitea", host01, TTL(1800)),
A("siteb", host01, TTL(1800)),
A("sitec", host02, TTL(1800)),
A("sited", host02, TTL(1800))
);
```
Running `dnscontrol push -v view=internal` would generate the zone for your internal dns.
Just running `dnscontrol push` would generate the zone for your external dns.
## Example 2: Different DNS records
So you can use the same zone for external and internal resolution and there is no need to duplicate it.
In this example different code is run when `emergency=true`. Normally
`server12` is an A record but in an emergency it is a CNAME.
In this configuration:
* `dnscontrol push` would generate the normal configuration.
* `dnscontrol push -v emergency=true` would generate the emergency configuration.
```js
// See https://stackexchange.github.io/dnscontrol/cli-variables
CLI_DEFAULTS({
"emergency": false,
});
// ...much later...
D("example.com", REG_EXAMPLE, DnsProvider(DNS_EXAMPLE),
A("www", "10.10.10.10"),
);
if (emergency) {
// Emergency mode: Configure A/B/C using CNAMEs to our alternate site.
D_EXTEND("example.com",
CNAME("a", "a.othersite"),
CNAME("b", "b.othersite"),
CNAME("c", "c.othersite")
);
} else {
// Normal operation: Configure A/B/C using A records.
D_EXTEND("example.com",
A("a", "10.10.10.10"),
A("b", "10.10.10.11"),
A("c", "10.10.10.12")
);
}
```
#### ProTips
#### ProTip
The cli variables functionality 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.
sophisticated configurations, but you shouldn't. Be nice to the next person
that edits the file, who may not be as expert as yourself.
While there is no limit to the number of variables that can be set on the
command line, doing so is annoying to the person using the tool. It is better
to set one variables which specifies a "mode". This mode is then used to
automatically set other variables. This way the user can determine the mode and
the code can determine what to do in that mode. This is less error-prone and
more testable.
In the first example, you'll see that one variable is used to set a mode which
then determines many other variables. This is done in one place, at the top of
the file. Everything related to this is isolated to one place, thus easier to
maintain. The rest of the file simply uses those variables.
In the second example, you'll see a boolean variable is set which selects which
code will run different code. While the conditional code is not isolated to the
top of the file, the conditional code is placed immediately after the domain.
In both examples, not setting any variables on the command line does something
reasonable. If someone accidentally runs `dnscontrol push` without any
variables, the behavior is correct (assuming we're not in emergency mode, which
is unlikely).