mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-09-12 16:14:42 +08:00
NEW FEATURE: IMPORT_TRANSFORM_STRIP (#3181)
This commit is contained in:
parent
2abbab0c84
commit
1872b12116
7 changed files with 131 additions and 34 deletions
|
@ -53,6 +53,7 @@
|
||||||
* [IGNORE_NAME](language-reference/domain-modifiers/IGNORE_NAME.md)
|
* [IGNORE_NAME](language-reference/domain-modifiers/IGNORE_NAME.md)
|
||||||
* [IGNORE_TARGET](language-reference/domain-modifiers/IGNORE_TARGET.md)
|
* [IGNORE_TARGET](language-reference/domain-modifiers/IGNORE_TARGET.md)
|
||||||
* [IMPORT_TRANSFORM](language-reference/domain-modifiers/IMPORT_TRANSFORM.md)
|
* [IMPORT_TRANSFORM](language-reference/domain-modifiers/IMPORT_TRANSFORM.md)
|
||||||
|
* [IMPORT_TRANSFORM_STRIP](language-reference/domain-modifiers/IMPORT_TRANSFORM_STRIP.md)
|
||||||
* [INCLUDE](language-reference/domain-modifiers/INCLUDE.md)
|
* [INCLUDE](language-reference/domain-modifiers/INCLUDE.md)
|
||||||
* [LOC](language-reference/domain-modifiers/LOC.md)
|
* [LOC](language-reference/domain-modifiers/LOC.md)
|
||||||
* [LOC_BUILDER_DD](language-reference/domain-modifiers/LOC_BUILDER_DD.md)
|
* [LOC_BUILDER_DD](language-reference/domain-modifiers/LOC_BUILDER_DD.md)
|
||||||
|
|
|
@ -3,6 +3,7 @@ name: IMPORT_TRANSFORM
|
||||||
parameters:
|
parameters:
|
||||||
- transform table
|
- transform table
|
||||||
- domain
|
- domain
|
||||||
|
- ttl
|
||||||
- modifiers...
|
- modifiers...
|
||||||
ts_ignore: true
|
ts_ignore: true
|
||||||
---
|
---
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
name: IMPORT_TRANSFORM_STRIP
|
||||||
|
parameters:
|
||||||
|
- transform table
|
||||||
|
- domain
|
||||||
|
- ttl
|
||||||
|
- suffixstrip
|
||||||
|
- modifiers...
|
||||||
|
ts_ignore: true
|
||||||
|
---
|
||||||
|
|
||||||
|
{% hint style="warning" %}
|
||||||
|
Don't use this feature. It was added for a very specific situation at Stack Overflow.
|
||||||
|
{% endhint %}
|
||||||
|
|
||||||
|
`IMPORT_TRANSFORM_STRIP` is the same as `IMPORT_TRANSFORM` with an additional parameter: `suffixstrip`.
|
||||||
|
|
||||||
|
When `IMPORT_TRANSFORM_STRIP` is generating the label for new records, it
|
||||||
|
checks the label. If the label ends with `suffixstrip`, that suffix is removed.
|
||||||
|
If the label does not end with `suffixstrip`, an error is returned.
|
||||||
|
|
||||||
|
For example, if the domain is `com.extra` and the label is `foo.com`,
|
||||||
|
`IMPORT_TRANSFORM` would generate a label `foo.com.com.extra`.
|
||||||
|
`IMPORT_TRANSFORM_STRIP(... , '.com')` would generate
|
||||||
|
the label `foo.com.extra` instead.
|
|
@ -1031,7 +1031,7 @@ function IGNORE_TARGET(target, rType) {
|
||||||
return IGNORE('*', rType, target);
|
return IGNORE('*', rType, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORT_TRANSFORM(translation_table, domain)
|
// IMPORT_TRANSFORM(translation_table, domain, ttl)
|
||||||
var IMPORT_TRANSFORM = recordBuilder('IMPORT_TRANSFORM', {
|
var IMPORT_TRANSFORM = recordBuilder('IMPORT_TRANSFORM', {
|
||||||
args: [['translation_table'], ['domain'], ['ttl', _.isNumber]],
|
args: [['translation_table'], ['domain'], ['ttl', _.isNumber]],
|
||||||
transform: function (record, args, modifiers) {
|
transform: function (record, args, modifiers) {
|
||||||
|
@ -1042,6 +1042,18 @@ var IMPORT_TRANSFORM = recordBuilder('IMPORT_TRANSFORM', {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// IMPORT_TRANSFORM_STRIP(translation_table, domain, ttl, suffixstrip)
|
||||||
|
var IMPORT_TRANSFORM_STRIP = recordBuilder('IMPORT_TRANSFORM', {
|
||||||
|
args: [['translation_table'], ['domain'], ['ttl', _.isNumber], ['suffixstrip']],
|
||||||
|
transform: function (record, args, modifiers) {
|
||||||
|
record.name = '@';
|
||||||
|
record.target = args.domain;
|
||||||
|
record.meta['transform_table'] = format_tt(args.translation_table);
|
||||||
|
record.ttl = args.ttl;
|
||||||
|
record.meta['transform_suffixstrip'] = args.suffixstrip;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// PURGE()
|
// PURGE()
|
||||||
function PURGE(d) {
|
function PURGE(d) {
|
||||||
d.KeepUnknown = false;
|
d.KeepUnknown = false;
|
||||||
|
|
30
pkg/js/parse_tests/007-importTransformTTL.js
Normal file → Executable file
30
pkg/js/parse_tests/007-importTransformTTL.js
Normal file → Executable file
|
@ -1,5 +1,25 @@
|
||||||
var TRANSFORM_INT = [
|
var TRANSFORM_NEWIP = [{
|
||||||
{low: "0.0.0.0", high: "1.1.1.1", newBase: "2.2.2.2" }
|
low: "0.0.0.0",
|
||||||
]
|
high: "1.1.1.1",
|
||||||
D("foo2.com","reg");
|
newIP: "2.2.2.2"
|
||||||
D("foo.com","reg",IMPORT_TRANSFORM(TRANSFORM_INT,"foo2.com",60))
|
}];
|
||||||
|
var TRANSFORM_BASE = [{
|
||||||
|
low: "0.0.0.0",
|
||||||
|
high: "1.1.1.1",
|
||||||
|
newBase: "4.4.4.4"
|
||||||
|
}, {
|
||||||
|
low: "7.7.7.7",
|
||||||
|
high: "8.8.8.8",
|
||||||
|
newBase: "9.9.9.9"
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
D("foo1.com", "reg");
|
||||||
|
|
||||||
|
D("foo2.com", "reg",
|
||||||
|
IMPORT_TRANSFORM(TRANSFORM_BASE, "foo1.com", 60)
|
||||||
|
);
|
||||||
|
|
||||||
|
D("foo3.com", "reg",
|
||||||
|
IMPORT_TRANSFORM_STRIP(TRANSFORM_NEWIP, "foo1.com", 99, ".com")
|
||||||
|
);
|
||||||
|
|
|
@ -1,28 +1,45 @@
|
||||||
{
|
{
|
||||||
|
"registrars": [],
|
||||||
"dns_providers": [],
|
"dns_providers": [],
|
||||||
"domains": [
|
"domains": [
|
||||||
{
|
{
|
||||||
|
"name": "foo1.com",
|
||||||
|
"registrar": "reg",
|
||||||
"dnsProviders": {},
|
"dnsProviders": {},
|
||||||
"name": "foo2.com",
|
"records": []
|
||||||
"records": [],
|
|
||||||
"registrar": "reg"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "foo2.com",
|
||||||
|
"registrar": "reg",
|
||||||
"dnsProviders": {},
|
"dnsProviders": {},
|
||||||
"name": "foo.com",
|
|
||||||
"records": [
|
"records": [
|
||||||
{
|
{
|
||||||
"meta": {
|
"type": "IMPORT_TRANSFORM",
|
||||||
"transform_table": "0.0.0.0 ~ 1.1.1.1 ~ 2.2.2.2 ~ "
|
|
||||||
},
|
|
||||||
"name": "@",
|
"name": "@",
|
||||||
"target": "foo2.com",
|
|
||||||
"ttl": 60,
|
"ttl": 60,
|
||||||
"type": "IMPORT_TRANSFORM"
|
"meta": {
|
||||||
|
"transform_table": "0.0.0.0 ~ 1.1.1.1 ~ 4.4.4.4 ~ ; 7.7.7.7 ~ 8.8.8.8 ~ 9.9.9.9 ~ "
|
||||||
|
},
|
||||||
|
"target": "foo1.com"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"registrar": "reg"
|
},
|
||||||
|
{
|
||||||
|
"name": "foo3.com",
|
||||||
|
"registrar": "reg",
|
||||||
|
"dnsProviders": {},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "IMPORT_TRANSFORM",
|
||||||
|
"name": "@",
|
||||||
|
"ttl": 99,
|
||||||
|
"meta": {
|
||||||
|
"transform_suffixstrip": ".com",
|
||||||
|
"transform_table": "0.0.0.0 ~ 1.1.1.1 ~ ~ 2.2.2.2"
|
||||||
|
},
|
||||||
|
"target": "foo1.com"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"registrars": []
|
}
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -119,7 +119,7 @@ func checkLabel(label string, rType string, domain string, meta map[string]strin
|
||||||
}
|
}
|
||||||
if label == domain || strings.HasSuffix(label, "."+domain) {
|
if label == domain || strings.HasSuffix(label, "."+domain) {
|
||||||
if m := meta["skip_fqdn_check"]; m != "true" {
|
if m := meta["skip_fqdn_check"]; m != "true" {
|
||||||
return fmt.Errorf(errorRepeat(label, domain))
|
return fmt.Errorf("%s", errorRepeat(label, domain))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,8 +247,27 @@ func transformCNAME(target, oldDomain, newDomain string) string {
|
||||||
return dnsutil.AddOrigin(result, newDomain) + "."
|
return dnsutil.AddOrigin(result, newDomain) + "."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newRec(rec *models.RecordConfig, ttl uint32) *models.RecordConfig {
|
||||||
|
rec2, _ := rec.Copy()
|
||||||
|
if ttl != 0 {
|
||||||
|
rec2.TTL = ttl
|
||||||
|
}
|
||||||
|
return rec2
|
||||||
|
}
|
||||||
|
|
||||||
|
func transformLabel(label, suffixstrip string) (string, error) {
|
||||||
|
if suffixstrip == "" {
|
||||||
|
return label, nil
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(label, suffixstrip) {
|
||||||
|
return "", fmt.Errorf("label %q does not end with %q", label, suffixstrip)
|
||||||
|
}
|
||||||
|
return label[:len(label)-len(suffixstrip)], nil
|
||||||
|
}
|
||||||
|
|
||||||
// import_transform imports the records of one zone into another, modifying records along the way.
|
// import_transform imports the records of one zone into another, modifying records along the way.
|
||||||
func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []transform.IPConversion, ttl uint32) error {
|
func importTransform(srcDomain, dstDomain *models.DomainConfig,
|
||||||
|
transforms []transform.IPConversion, ttl uint32, suffixstrip string) error {
|
||||||
// Read srcDomain.Records, transform, and append to dstDomain.Records:
|
// Read srcDomain.Records, transform, and append to dstDomain.Records:
|
||||||
// 1. Skip any that aren't A or CNAMEs.
|
// 1. Skip any that aren't A or CNAMEs.
|
||||||
// 2. Append destDomainname to the end of the label.
|
// 2. Append destDomainname to the end of the label.
|
||||||
|
@ -259,15 +278,6 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra
|
||||||
if dstDomain.Records.HasRecordTypeName(rec.Type, rec.GetLabelFQDN()) {
|
if dstDomain.Records.HasRecordTypeName(rec.Type, rec.GetLabelFQDN()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newRec := func() *models.RecordConfig {
|
|
||||||
rec2, _ := rec.Copy()
|
|
||||||
newlabel := rec2.GetLabelFQDN()
|
|
||||||
rec2.SetLabel(newlabel, dstDomain.Name)
|
|
||||||
if ttl != 0 {
|
|
||||||
rec2.TTL = ttl
|
|
||||||
}
|
|
||||||
return rec2
|
|
||||||
}
|
|
||||||
switch rec.Type {
|
switch rec.Type {
|
||||||
case "A":
|
case "A":
|
||||||
trs, err := transform.IPToList(net.ParseIP(rec.GetTargetField()), transforms)
|
trs, err := transform.IPToList(net.ParseIP(rec.GetTargetField()), transforms)
|
||||||
|
@ -275,12 +285,22 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra
|
||||||
return fmt.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.GetTargetField(), transforms, err)
|
return fmt.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.GetTargetField(), transforms, err)
|
||||||
}
|
}
|
||||||
for _, tr := range trs {
|
for _, tr := range trs {
|
||||||
r := newRec()
|
r := newRec(rec, ttl)
|
||||||
|
l, err := transformLabel(r.GetLabelFQDN(), suffixstrip)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.SetLabel(l, dstDomain.Name)
|
||||||
r.SetTarget(tr.String())
|
r.SetTarget(tr.String())
|
||||||
dstDomain.Records = append(dstDomain.Records, r)
|
dstDomain.Records = append(dstDomain.Records, r)
|
||||||
}
|
}
|
||||||
case "CNAME":
|
case "CNAME":
|
||||||
r := newRec()
|
r := newRec(rec, ttl)
|
||||||
|
l, err := transformLabel(r.GetLabelFQDN(), suffixstrip)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.SetLabel(l, dstDomain.Name)
|
||||||
r.SetTarget(transformCNAME(r.GetTargetField(), srcDomain.Name, dstDomain.Name))
|
r.SetTarget(transformCNAME(r.GetTargetField(), srcDomain.Name, dstDomain.Name))
|
||||||
dstDomain.Records = append(dstDomain.Records, r)
|
dstDomain.Records = append(dstDomain.Records, r)
|
||||||
default:
|
default:
|
||||||
|
@ -445,6 +465,7 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
||||||
for _, domain := range config.Domains {
|
for _, domain := range config.Domains {
|
||||||
for _, rec := range domain.Records {
|
for _, rec := range domain.Records {
|
||||||
if rec.Type == "IMPORT_TRANSFORM" {
|
if rec.Type == "IMPORT_TRANSFORM" {
|
||||||
|
suffixstrip := rec.Metadata["transform_suffixstrip"]
|
||||||
table, err := transform.DecodeTransformTable(rec.Metadata["transform_table"])
|
table, err := transform.DecodeTransformTable(rec.Metadata["transform_table"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
|
@ -455,7 +476,7 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
||||||
err = fmt.Errorf("IMPORT_TRANSFORM mentions non-existant domain %q", rec.GetTargetField())
|
err = fmt.Errorf("IMPORT_TRANSFORM mentions non-existant domain %q", rec.GetTargetField())
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
err = importTransform(c, domain, table, rec.TTL)
|
err = importTransform(c, domain, table, rec.TTL, suffixstrip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue