mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Add D_EXTEND (#885) (thanks to @ad8-bdl!)
* fix get-zones code block indentation * extend D_EXTEND to handle subdomains * fix targets: make absolute incl. subdomain where necessary * clarify subdomain target test (not IP && not fqdn) * Add parse_tests for D and D_EXTEND * _getDomainObject: examine all domains * human readable form * consistent test IP addresses * Improve docs and formatting * propagate subdomain to canonicalisation * en-US spelling * rm extraneous console.log * ignore subdomain for CF_REDIRECT * clarify D_EXTEND doc re. CF_REDIRECT * rm extraneous linebreak * _getDomainObject: examine all domains * human readable form * consistent test IP addresses * propagate subdomain to canonicalisation * en-US spelling * rm extraneous console.log * ignore subdomain for CF_REDIRECT * clarify D_EXTEND doc re. CF_REDIRECT * rm extraneous linebreak * GANDI_V5: Use github.com/go-gandi/go-gandi, not github.com/tiramiseb/go-gandi (#883) * DOCUMENTATION: Fix error in CNAME.md (#877) The current example `CNAME("def", "test.subdomain"), // def.example.com -> test.subdomain.example.com` is invalid (correctly raises a validation error, "ERROR: in CNAME def.example.com: target (test.subdomain) must end with a (.)") * typos, fmt; example syntax fixes and real output * formatting; re-add lost comment * RecordConfig subdomain should be nullable * providers/cscglobal/api.go: Fix fmt string * More tests and docs * go generate Co-authored-by: Ben L <47653825+ad8-bdl@users.noreply.github.com>
This commit is contained in:
@@ -5,26 +5,83 @@ parameters:
|
|||||||
- modifiers...
|
- 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.
|
`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.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
{% include startExample.html %}
|
{% include startExample.html %}
|
||||||
{% highlight js %}
|
{% highlight js %}
|
||||||
D('domain.tld', REG, DnsProvider(DNS),
|
D("domain.tld", REG, DnsProvider(DNS),
|
||||||
A('@', "127.0.0.1")
|
A("@", "127.0.0.1"), // domain.tld
|
||||||
)
|
A("www", "127.0.0.2"), // www.domain.tld
|
||||||
D_EXTEND('domain.tld',
|
CNAME("a", "b") // a.domain.tld -> b.domain.tld
|
||||||
A('@', "127.0.0.2")
|
);
|
||||||
)
|
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
|
||||||
|
);
|
||||||
{%endhighlight%}
|
{%endhighlight%}
|
||||||
|
|
||||||
This will end up in following modifications:
|
This will end up in the following modifications:
|
||||||
```
|
```
|
||||||
******************** Domain: domain.tld
|
******************** Domain: domain.tld
|
||||||
----- Getting nameservers from: registrar
|
----- Getting nameservers from: cloudflare
|
||||||
----- DNS Provider: registrar...3 corrections
|
----- DNS Provider: cloudflare...7 corrections
|
||||||
#1: CREATE A domain.tld 127.0.0.1 ttl=43200
|
#1: CREATE A aaa.domain.tld 127.0.0.3
|
||||||
#2: CREATE A domain.tld 127.0.0.2 ttl=43200
|
#2: CREATE A bbb.sub.domain.tld 127.0.0.4
|
||||||
#3: REFRESH zone domain.tld
|
#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.
|
||||||
```
|
```
|
||||||
{% include endExample.html %}
|
{% include endExample.html %}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import (
|
|||||||
// the intended FQDN is "foo.com.foo.com." (which may look odd)
|
// the intended FQDN is "foo.com.foo.com." (which may look odd)
|
||||||
// NameFQDN:
|
// NameFQDN:
|
||||||
// This is the FQDN version of Name.
|
// This is the FQDN version of Name.
|
||||||
// It should never have a trailiing ".".
|
// It should never have a trailing ".".
|
||||||
// NOTE: Eventually we will unexport Name/NameFQDN. Please start using
|
// NOTE: Eventually we will unexport Name/NameFQDN. Please start using
|
||||||
// the setters (SetLabel/SetLabelFromFQDN) and getters (GetLabel/GetLabelFQDN).
|
// the setters (SetLabel/SetLabelFromFQDN) and getters (GetLabel/GetLabelFQDN).
|
||||||
// as they will always work.
|
// as they will always work.
|
||||||
@@ -59,13 +59,18 @@ import (
|
|||||||
// fields.
|
// fields.
|
||||||
// NOTE: Eventually we will unexport Target. Please start using the
|
// NOTE: Eventually we will unexport Target. Please start using the
|
||||||
// setters (SetTarget*) and getters (GetTarget*) as they will always work.
|
// setters (SetTarget*) and getters (GetTarget*) as they will always work.
|
||||||
|
// SubDomain:
|
||||||
|
// This is the subdomain path, if any, imported from the configuration. If
|
||||||
|
// present at the time of canonicalization it is inserted between the
|
||||||
|
// Name and origin when constructing a canonical (FQDN) target.
|
||||||
//
|
//
|
||||||
// Idioms:
|
// Idioms:
|
||||||
// rec.Label() == "@" // Is this record at the apex?
|
// rec.Label() == "@" // Is this record at the apex?
|
||||||
//
|
//
|
||||||
type RecordConfig struct {
|
type RecordConfig struct {
|
||||||
Type string `json:"type"` // All caps rtype name.
|
Type string `json:"type"` // All caps rtype name.
|
||||||
Name string `json:"name"` // The short name. See above.
|
Name string `json:"name"` // The short name. See above.
|
||||||
|
SubDomain string `json:"subdomain,omitempty"`
|
||||||
NameFQDN string `json:"-"` // Must end with ".$origin". See above.
|
NameFQDN string `json:"-"` // Must end with ".$origin". See above.
|
||||||
Target string `json:"target"` // If a name, must end with "."
|
Target string `json:"target"` // If a name, must end with "."
|
||||||
TTL uint32 `json:"ttl,omitempty"`
|
TTL uint32 `json:"ttl,omitempty"`
|
||||||
|
|||||||
92
pkg/js/030-dextenddoc.json
Normal file
92
pkg/js/030-dextenddoc.json
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"dns_providers": [
|
||||||
|
{
|
||||||
|
"name": "Cloudflare",
|
||||||
|
"type": "CLOUDFLAREAPI"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"domains": [
|
||||||
|
{
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"name": "domain.tld",
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"name": "@",
|
||||||
|
"target": "127.0.0.1",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "www",
|
||||||
|
"target": "127.0.0.2",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"target": "b",
|
||||||
|
"type": "CNAME"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aaa",
|
||||||
|
"target": "127.0.0.3",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "c",
|
||||||
|
"target": "d",
|
||||||
|
"type": "CNAME"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bbb.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "127.0.0.4",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ccc.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "127.0.0.5",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "e.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "f",
|
||||||
|
"type": "CNAME"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ddd.sub.sub",
|
||||||
|
"subdomain": "sub.sub",
|
||||||
|
"target": "127.0.0.6",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "g.sub.sub",
|
||||||
|
"subdomain": "sub.sub",
|
||||||
|
"target": "h",
|
||||||
|
"type": "CNAME"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "127.0.0.7",
|
||||||
|
"type": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "i.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "j",
|
||||||
|
"type": "CNAME"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"registrar": "Third-Party"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"registrars": [
|
||||||
|
{
|
||||||
|
"name": "Third-Party",
|
||||||
|
"type": "NONE"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -53,6 +53,7 @@ function NewDnsProvider(name, type, meta) {
|
|||||||
function newDomain(name, registrar) {
|
function newDomain(name, registrar) {
|
||||||
return {
|
return {
|
||||||
name: name,
|
name: name,
|
||||||
|
subdomain: '',
|
||||||
registrar: registrar,
|
registrar: registrar,
|
||||||
meta: {},
|
meta: {},
|
||||||
records: [],
|
records: [],
|
||||||
@@ -102,12 +103,13 @@ function D(name, registrar) {
|
|||||||
conf.domain_names.push(name);
|
conf.domain_names.push(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DU(name): Update an already added DNS Domain with D().
|
// D_EXTEND(name): Update a DNS Domain already added with D(), or subdomain thereof
|
||||||
function D_EXTEND(name) {
|
function D_EXTEND(name) {
|
||||||
var domain = _getDomainObject(name);
|
var domain = _getDomainObject(name);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
throw name + ' was not declared yet and therefore cannot be updated. Use D() before.';
|
throw name + ' was not declared yet and therefore cannot be updated. Use D() before.';
|
||||||
}
|
}
|
||||||
|
domain.obj.subdomain = name.substr(0, name.length-domain.obj.name.length - 1);
|
||||||
for (var i = 0; i < defaultArgs.length; i++) {
|
for (var i = 0; i < defaultArgs.length; i++) {
|
||||||
processDargs(defaultArgs[i], domain.obj);
|
processDargs(defaultArgs[i], domain.obj);
|
||||||
}
|
}
|
||||||
@@ -119,13 +121,19 @@ function D_EXTEND(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// _getDomainObject(name): This is a small helper function to get the domain JS object returned.
|
// _getDomainObject(name): This is a small helper function to get the domain JS object returned.
|
||||||
|
// returns the domain object defined for the given name or subdomain thereof
|
||||||
function _getDomainObject(name) {
|
function _getDomainObject(name) {
|
||||||
|
domain = null;
|
||||||
|
domain_len = 0;
|
||||||
for(var i = 0; i < conf.domains.length; i++) {
|
for(var i = 0; i < conf.domains.length; i++) {
|
||||||
if (conf.domains[i]['name'] == name) {
|
if (name.substr(-conf.domains[i]['name'].length) == conf.domains[i]['name']) {
|
||||||
return {'id': i, 'obj': conf.domains[i]};
|
if (conf.domains[i]['name'].length > domain_len) {
|
||||||
|
domain_len = conf.domains[i]['name'].length;
|
||||||
|
domain = {'id': i, 'obj': conf.domains[i]};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEFAULTS provides a set of default arguments to apply to all future domains.
|
// DEFAULTS provides a set of default arguments to apply to all future domains.
|
||||||
@@ -660,6 +668,17 @@ function recordBuilder(type, opts) {
|
|||||||
opts.applyModifier(record, modifiers);
|
opts.applyModifier(record, modifiers);
|
||||||
opts.transform(record, parsedArgs, modifiers);
|
opts.transform(record, parsedArgs, modifiers);
|
||||||
|
|
||||||
|
// Handle D_EXTEND() with subdomains.
|
||||||
|
if (d.subdomain && record.type != 'CF_REDIRECT' &&
|
||||||
|
record.type != 'CF_TEMP_REDIRECT') {
|
||||||
|
record.subdomain = d.subdomain;
|
||||||
|
if (record.name == '@') {
|
||||||
|
record.name = d.subdomain;
|
||||||
|
} else {
|
||||||
|
record.name += '.' + d.subdomain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d.records.push(record);
|
d.records.push(record);
|
||||||
return record;
|
return record;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
var REG = NewRegistrar("Third-Party","NONE");
|
var REG = NewRegistrar("Third-Party","NONE");
|
||||||
var CF = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI")
|
var CF = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI");
|
||||||
|
|
||||||
D("foo.com",REG,DnsProvider(CF),
|
D("foo.com",REG,DnsProvider(CF),
|
||||||
A("@","1.2.3.4")
|
A("@","1.2.3.4")
|
||||||
);
|
);
|
||||||
22
pkg/js/parse_tests/028-dextend.js
Normal file
22
pkg/js/parse_tests/028-dextend.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
var REG = NewRegistrar("Third-Party", "NONE");
|
||||||
|
var CF = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI");
|
||||||
|
|
||||||
|
// Zone and subdomain Zone:
|
||||||
|
D("foo.com", REG, DnsProvider(CF),
|
||||||
|
A("@", "10.1.1.1"),
|
||||||
|
A("www", "10.2.2.2")
|
||||||
|
);
|
||||||
|
D("bar.foo.com", REG, DnsProvider(CF),
|
||||||
|
A("@", "10.3.3.3"),
|
||||||
|
A("www", "10.4.4.4")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zone that gets extended
|
||||||
|
D("foo.edu", REG, DnsProvider(CF),
|
||||||
|
A("@", "10.5.5.5"),
|
||||||
|
A("www", "10.6.6.6")
|
||||||
|
);
|
||||||
|
D_EXTEND("foo.edu",
|
||||||
|
A("more1", "10.7.7.7"),
|
||||||
|
A("more2", "10.8.8.8")
|
||||||
|
);
|
||||||
83
pkg/js/parse_tests/028-dextend.json
Normal file
83
pkg/js/parse_tests/028-dextend.json
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"registrars": [
|
||||||
|
{
|
||||||
|
"name": "Third-Party",
|
||||||
|
"type": "NONE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dns_providers": [
|
||||||
|
{
|
||||||
|
"name": "Cloudflare",
|
||||||
|
"type": "CLOUDFLAREAPI"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"domains": [
|
||||||
|
{
|
||||||
|
"name": "foo.com",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "10.1.1.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "10.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bar.foo.com",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "10.3.3.3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "10.4.4.4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo.edu",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "10.5.5.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "10.6.6.6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "more1",
|
||||||
|
"target": "10.7.7.7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "more2",
|
||||||
|
"target": "10.8.8.8"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
84
pkg/js/parse_tests/029-dextendsub.js
Normal file
84
pkg/js/parse_tests/029-dextendsub.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
var REG = NewRegistrar("Third-Party", "NONE");
|
||||||
|
var CF = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI");
|
||||||
|
|
||||||
|
// Zone that gets extended by subdomain
|
||||||
|
D("foo.net", REG, DnsProvider(CF),
|
||||||
|
A("@", "10.1.1.1"),
|
||||||
|
A("www", "10.2.2.2")
|
||||||
|
);
|
||||||
|
D_EXTEND("bar.foo.net",
|
||||||
|
A("@", "10.3.3.3"),
|
||||||
|
A("www", "10.4.4.4")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zone and subdomain zone, each get extended.
|
||||||
|
D("foo.tld", REG, DnsProvider(CF),
|
||||||
|
A("@", "20.5.5.5"),
|
||||||
|
A("www", "20.6.6.6")
|
||||||
|
);
|
||||||
|
D("bar.foo.tld", REG, DnsProvider(CF),
|
||||||
|
A("@", "30.7.7.7"),
|
||||||
|
A("www", "30.8.8.8")
|
||||||
|
);
|
||||||
|
D_EXTEND("bar.foo.tld",
|
||||||
|
A("a", "30.9.9.9")
|
||||||
|
);
|
||||||
|
D_EXTEND("foo.tld",
|
||||||
|
A("a", "20.10.10.10")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zone and subdomain zone, each get extended by a subdomain.
|
||||||
|
D("foo.help", REG, DnsProvider(CF),
|
||||||
|
A("@", "40.12.12.12"),
|
||||||
|
A("www", "40.12.12.12")
|
||||||
|
);
|
||||||
|
D("bar.foo.help", REG, DnsProvider(CF),
|
||||||
|
A("@", "50.13.13.13"),
|
||||||
|
A("www", "50.14.14.14")
|
||||||
|
);
|
||||||
|
D_EXTEND("zip.bar.foo.help",
|
||||||
|
A("@", "50.15.15.15"),
|
||||||
|
A("www", "50.16.16.16")
|
||||||
|
);
|
||||||
|
D_EXTEND("morty.foo.help",
|
||||||
|
A("@", "40.17.17.17"),
|
||||||
|
A("www", "40.18.18.18")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zone extended by a subdomain and sub-subdomain.
|
||||||
|
D("foo.here", REG, DnsProvider(CF),
|
||||||
|
A("@", "60.19.19.19"),
|
||||||
|
A("www", "60.20.20.20")
|
||||||
|
);
|
||||||
|
D_EXTEND("bar.foo.here",
|
||||||
|
A("@", "60.21.21.21"),
|
||||||
|
A("www", "60.22.22.22")
|
||||||
|
);
|
||||||
|
D_EXTEND("baz.bar.foo.here",
|
||||||
|
A("@", "60.23.23.23"),
|
||||||
|
A("www", "60.24.24.24")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zone extended by a sub-subdomain.
|
||||||
|
D_EXTEND("a.long.path.of.sub.domains.foo.net",
|
||||||
|
A("@", "10.25.25.25"),
|
||||||
|
A("www", "10.26.26.26")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zone extended by a subdomain, with absolute and relative CNAME targets
|
||||||
|
D("example.tld", REG, DnsProvider(CF));
|
||||||
|
D_EXTEND("sub.example.tld",
|
||||||
|
CNAME("a", "b"), // a.sub.example.tld -> b.sub.example.tld
|
||||||
|
CNAME("b", "@"), // a.sub.example.tld -> sub.example.tld
|
||||||
|
CNAME("c", "sub.example.tld."), // a.sub.example.tld -> sub.example.tld
|
||||||
|
//CNAME("d", "x.y"), // Error. Contains dot but doesn't end with dot.
|
||||||
|
CNAME("e", "otherdomain.tld.") // a.sub.example.tld -> otherdomain.tld
|
||||||
|
// Also test for MX, NS, ANAME, SRV.
|
||||||
|
// Not sure if PTR needs any special treatment. Haven't thought about it much.
|
||||||
|
);
|
||||||
|
|
||||||
|
D("foo.com", REG, DnsProvider(CF));
|
||||||
|
D_EXTEND("sub.foo.com",
|
||||||
|
CF_REDIRECT("test.foo.com","https://goo.com/$1"),
|
||||||
|
CF_TEMP_REDIRECT("test.foo.com","https://goo.com/$1")
|
||||||
|
);
|
||||||
264
pkg/js/parse_tests/029-dextendsub.json
Normal file
264
pkg/js/parse_tests/029-dextendsub.json
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
{
|
||||||
|
"registrars": [
|
||||||
|
{
|
||||||
|
"name": "Third-Party",
|
||||||
|
"type": "NONE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dns_providers": [
|
||||||
|
{
|
||||||
|
"name": "Cloudflare",
|
||||||
|
"type": "CLOUDFLAREAPI"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"domains": [
|
||||||
|
{
|
||||||
|
"name": "foo.net",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "10.1.1.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "10.2.2.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "bar",
|
||||||
|
"subdomain": "bar",
|
||||||
|
"target": "10.3.3.3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www.bar",
|
||||||
|
"subdomain": "bar",
|
||||||
|
"target": "10.4.4.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "a.long.path.of.sub.domains",
|
||||||
|
"subdomain": "a.long.path.of.sub.domains",
|
||||||
|
"target": "10.25.25.25"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www.a.long.path.of.sub.domains",
|
||||||
|
"subdomain": "a.long.path.of.sub.domains",
|
||||||
|
"target": "10.26.26.26"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo.tld",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "20.5.5.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "20.6.6.6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "a",
|
||||||
|
"target": "20.10.10.10"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bar.foo.tld",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "30.7.7.7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "30.8.8.8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "a",
|
||||||
|
"target": "30.9.9.9"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo.help",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "40.12.12.12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "40.12.12.12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "morty",
|
||||||
|
"subdomain": "morty",
|
||||||
|
"target": "40.17.17.17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www.morty",
|
||||||
|
"subdomain": "morty",
|
||||||
|
"target": "40.18.18.18"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bar.foo.help",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "50.13.13.13"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "50.14.14.14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "zip",
|
||||||
|
"subdomain": "zip",
|
||||||
|
"target": "50.15.15.15"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www.zip",
|
||||||
|
"subdomain": "zip",
|
||||||
|
"target": "50.16.16.16"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo.here",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"target": "60.19.19.19"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www",
|
||||||
|
"target": "60.20.20.20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "bar",
|
||||||
|
"subdomain": "bar",
|
||||||
|
"target": "60.21.21.21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www.bar",
|
||||||
|
"subdomain": "bar",
|
||||||
|
"target": "60.22.22.22"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "baz.bar",
|
||||||
|
"subdomain": "baz.bar",
|
||||||
|
"target": "60.23.23.23"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "A",
|
||||||
|
"name": "www.baz.bar",
|
||||||
|
"subdomain": "baz.bar",
|
||||||
|
"target": "60.24.24.24"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "example.tld",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "CNAME",
|
||||||
|
"name": "a.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CNAME",
|
||||||
|
"name": "b.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "@"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CNAME",
|
||||||
|
"name": "c.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "sub.example.tld."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CNAME",
|
||||||
|
"name": "e.sub",
|
||||||
|
"subdomain": "sub",
|
||||||
|
"target": "otherdomain.tld."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo.com",
|
||||||
|
"registrar": "Third-Party",
|
||||||
|
"dnsProviders": {
|
||||||
|
"Cloudflare": -1
|
||||||
|
},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "CF_REDIRECT",
|
||||||
|
"name": "@",
|
||||||
|
"target": "test.foo.com,https://goo.com/$1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CF_TEMP_REDIRECT",
|
||||||
|
"name": "@",
|
||||||
|
"target": "test.foo.com,https://goo.com/$1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
27
pkg/js/parse_tests/030-dextenddoc.js
Normal file
27
pkg/js/parse_tests/030-dextenddoc.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
var REG = NewRegistrar("Third-Party", "NONE");
|
||||||
|
var DNS = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI");
|
||||||
|
|
||||||
|
// The example from docs/_functions/global/D_EXTEND.md
|
||||||
|
|
||||||
|
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.domain.tld -> h.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
|
||||||
|
);
|
||||||
67
pkg/js/parse_tests/030-dextenddoc.json
Normal file
67
pkg/js/parse_tests/030-dextenddoc.json
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"registrars":
|
||||||
|
[
|
||||||
|
{"name":"Third-Party","type":"NONE"}
|
||||||
|
],
|
||||||
|
"dns_providers":[{"name":"Cloudflare","type":"CLOUDFLAREAPI"}],
|
||||||
|
"domains":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name":"domain.tld",
|
||||||
|
"registrar":"Third-Party",
|
||||||
|
"dnsProviders": {"Cloudflare":-1},
|
||||||
|
"records":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type":"A",
|
||||||
|
"name":"@",
|
||||||
|
"target":"127.0.0.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"A",
|
||||||
|
"name":"www",
|
||||||
|
"target":"127.0.0.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"CNAME",
|
||||||
|
"name":"a",
|
||||||
|
"target":"b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"A",
|
||||||
|
"name":"aaa",
|
||||||
|
"target":"127.0.0.3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"CNAME",
|
||||||
|
"name":"c",
|
||||||
|
"target":"d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"A",
|
||||||
|
"name":"bbb.sub",
|
||||||
|
"subdomain":"sub",
|
||||||
|
"target":"127.0.0.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"A","name":"ccc.sub","subdomain":"sub","target":"127.0.0.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"CNAME","name":"e.sub","subdomain":"sub","target":"f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"A","name":"ddd.sub.sub","subdomain":"sub.sub","target":"127.0.0.6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"CNAME","name":"g.sub.sub","subdomain":"sub.sub","target":"h"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"A","name":"sub","subdomain":"sub","target":"127.0.0.7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"CNAME","name":"i.sub","subdomain":"sub","target":"j"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
45
pkg/js/parse_tests/031-dextendnames.js
Normal file
45
pkg/js/parse_tests/031-dextendnames.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
var REG = NewRegistrar("Third-Party", "NONE");
|
||||||
|
var DNS = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI");
|
||||||
|
|
||||||
|
// Test the name matching algorithm
|
||||||
|
|
||||||
|
D("domain.tld", REG, DnsProvider(DNS),
|
||||||
|
A("@", "127.0.0.1"),
|
||||||
|
A("a", "127.0.0.2"),
|
||||||
|
CNAME("b", "c")
|
||||||
|
);
|
||||||
|
|
||||||
|
D("sub.domain.tld", REG, DnsProvider(DNS),
|
||||||
|
A("@", "127.0.1.1"),
|
||||||
|
A("aa", "127.0.1.2"),
|
||||||
|
CNAME("bb", "cc")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Should match domain.tld
|
||||||
|
D_EXTEND("domain.tld",
|
||||||
|
A("@", "127.0.0.3"),
|
||||||
|
A("d", "127.0.0.4"),
|
||||||
|
CNAME("e", "f")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should match domain.tld
|
||||||
|
D_EXTEND("ub.domain.tld",
|
||||||
|
A("@", "127.0.0.5"),
|
||||||
|
A("g", "127.0.0.6"),
|
||||||
|
CNAME("h", "i")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should match sub.domain.tld
|
||||||
|
D_EXTEND("sub.domain.tld",
|
||||||
|
A("@", "127.0.1.3"),
|
||||||
|
A("dd", "127.0.1.4"),
|
||||||
|
CNAME("ee", "ff")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should match domain.tld
|
||||||
|
D_EXTEND("ssub.domain.tld",
|
||||||
|
A("@", "127.0.0.7"),
|
||||||
|
A("j", "127.0.0.8"),
|
||||||
|
CNAME("k", "l")
|
||||||
|
);
|
||||||
46
pkg/js/parse_tests/031-dextendnames.json
Normal file
46
pkg/js/parse_tests/031-dextendnames.json
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"registrars":
|
||||||
|
[
|
||||||
|
{"name":"Third-Party","type":"NONE"}
|
||||||
|
],
|
||||||
|
"dns_providers":
|
||||||
|
[
|
||||||
|
{"name":"Cloudflare","type":"CLOUDFLAREAPI"}],
|
||||||
|
"domains":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name":"domain.tld",
|
||||||
|
"registrar":"Third-Party",
|
||||||
|
"dnsProviders":{"Cloudflare":-1},
|
||||||
|
"records":
|
||||||
|
[
|
||||||
|
{"type":"A","name":"@","target":"127.0.0.1"},
|
||||||
|
{"type":"A","name":"a","target":"127.0.0.2"},
|
||||||
|
{"type":"CNAME","name":"b","target":"c"},
|
||||||
|
{"type":"A","name":"@","target":"127.0.0.3"},
|
||||||
|
{"type":"A","name":"d","target":"127.0.0.4"},
|
||||||
|
{"type":"CNAME","name":"e","target":"f"},
|
||||||
|
{"type":"A","name":"ub","subdomain":"ub","target":"127.0.0.5"},
|
||||||
|
{"type":"A","name":"g.ub","subdomain":"ub","target":"127.0.0.6"},
|
||||||
|
{"type":"CNAME","name":"h.ub","subdomain":"ub","target":"i"},
|
||||||
|
{"type":"A","name":"@","subdomain":"ssub","target":"127.0.0.7"},
|
||||||
|
{"type":"A","name":"j","subdomain":"ssub","target":"127.0.0.8"},
|
||||||
|
{"type":"CNAME","name":"k","subdomain":"ssub","target":"l"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"sub.domain.tld",
|
||||||
|
"registrar":"Third-Party",
|
||||||
|
"dnsProviders":{"Cloudflare":-1},
|
||||||
|
"records":
|
||||||
|
[
|
||||||
|
{"type":"A","name":"@","target":"127.0.1.1"},
|
||||||
|
{"type":"A","name":"aa","target":"127.0.1.2"},
|
||||||
|
{"type":"CNAME","name":"bb","target":"cc"},
|
||||||
|
{"type":"A","name":"@","target":"127.0.1.3"},
|
||||||
|
{"type":"A","name":"dd","target":"127.0.1.4"},
|
||||||
|
{"type":"CNAME","name":"ee","target":"ff"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
236
pkg/js/static.go
236
pkg/js/static.go
@@ -212,124 +212,128 @@ var _escData = map[string]*_escFile{
|
|||||||
"/helpers.js": {
|
"/helpers.js": {
|
||||||
name: "helpers.js",
|
name: "helpers.js",
|
||||||
local: "pkg/js/helpers.js",
|
local: "pkg/js/helpers.js",
|
||||||
size: 26563,
|
size: 27416,
|
||||||
modtime: 0,
|
modtime: 0,
|
||||||
compressed: `
|
compressed: `
|
||||||
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
|
||||||
|
6diybudx5/8FAAD//7FJb88YawAA
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,7 +304,11 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
|||||||
// These record types have a target that is a hostname.
|
// These record types have a target that is a hostname.
|
||||||
// We normalize them to a FQDN so there is less variation to handle. If a
|
// We normalize them to a FQDN so there is less variation to handle. If a
|
||||||
// provider API requires a shortname, the provider must do the shortening.
|
// provider API requires a shortname, the provider must do the shortening.
|
||||||
rec.SetTarget(dnsutil.AddOrigin(rec.GetTargetField(), domain.Name+"."))
|
origin := domain.Name + "."
|
||||||
|
if len(rec.SubDomain) > 0 {
|
||||||
|
origin = rec.SubDomain + "." + origin
|
||||||
|
}
|
||||||
|
rec.SetTarget(dnsutil.AddOrigin(rec.GetTargetField(), origin))
|
||||||
} else if rec.Type == "A" || rec.Type == "AAAA" {
|
} else if rec.Type == "A" || rec.Type == "AAAA" {
|
||||||
rec.SetTarget(net.ParseIP(rec.GetTargetField()).String())
|
rec.SetTarget(net.ParseIP(rec.GetTargetField()).String())
|
||||||
} else if rec.Type == "PTR" {
|
} else if rec.Type == "PTR" {
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ func (c *api) get(endpoint string) ([]byte, error) {
|
|||||||
|
|
||||||
if resp.StatusCode == 400 {
|
if resp.StatusCode == 400 {
|
||||||
// 400, error message is in the body as plain text
|
// 400, error message is in the body as plain text
|
||||||
return nil, fmt.Errorf("CSC Global API error: %w URL: %s%s",
|
return nil, fmt.Errorf("CSC Global API error: %s URL: %s%s",
|
||||||
bodyString,
|
bodyString,
|
||||||
req.Host, req.URL.RequestURI())
|
req.Host, req.URL.RequestURI())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user