mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Direct SOA record management (#1115)
* Adds SOA record to JS, zone parsing and record validation * adds JS parsing test for SOA record * fix validation & regenerates static resources * Adds label and target test for SOA record * Removes serial from SOA JS macro * Adds generated resources * reformat with gofmt Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
@ -34,6 +34,7 @@ func generateFeatureMatrix() error {
|
|||||||
{"CAA", "Provider can manage CAA records"},
|
{"CAA", "Provider can manage CAA records"},
|
||||||
{"PTR", "Provider supports adding PTR records for reverse lookup zones"},
|
{"PTR", "Provider supports adding PTR records for reverse lookup zones"},
|
||||||
{"NAPTR", "Provider can manage NAPTR records"},
|
{"NAPTR", "Provider can manage NAPTR records"},
|
||||||
|
{"SOA", "Provider can manage SOA records"},
|
||||||
{"SRV", "Driver has explicitly implemented SRV record management"},
|
{"SRV", "Driver has explicitly implemented SRV record management"},
|
||||||
{"SSHFP", "Provider can manage SSHFP records"},
|
{"SSHFP", "Provider can manage SSHFP records"},
|
||||||
{"TLSA", "Provider can manage TLSA records"},
|
{"TLSA", "Provider can manage TLSA records"},
|
||||||
@ -83,6 +84,7 @@ func generateFeatureMatrix() error {
|
|||||||
setCap("PTR", providers.CanUsePTR)
|
setCap("PTR", providers.CanUsePTR)
|
||||||
setCap("R53_ALIAS", providers.CanUseRoute53Alias)
|
setCap("R53_ALIAS", providers.CanUseRoute53Alias)
|
||||||
setCap("AZURE_ALIAS", providers.CanUseAzureAlias)
|
setCap("AZURE_ALIAS", providers.CanUseAzureAlias)
|
||||||
|
setCap("SOA", providers.CanUseSOA)
|
||||||
setCap("SRV", providers.CanUseSRV)
|
setCap("SRV", providers.CanUseSRV)
|
||||||
setCap("SSHFP", providers.CanUseSSHFP)
|
setCap("SSHFP", providers.CanUseSSHFP)
|
||||||
setCap("TLSA", providers.CanUseTLSA)
|
setCap("TLSA", providers.CanUseTLSA)
|
||||||
|
@ -746,6 +746,44 @@
|
|||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider can manage SOA records">SOA</th>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Driver has explicitly implemented SRV record management">SRV</th>
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Driver has explicitly implemented SRV record management">SRV</th>
|
||||||
<td class="danger">
|
<td class="danger">
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
// NS
|
// NS
|
||||||
// PTR
|
// PTR
|
||||||
// SRV
|
// SRV
|
||||||
|
// SOA
|
||||||
// SSHFP
|
// SSHFP
|
||||||
// TLSA
|
// TLSA
|
||||||
// TXT
|
// TXT
|
||||||
|
@ -357,6 +357,28 @@ var NAPTR = recordBuilder('NAPTR', {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// SOA(name,ns,mbox,serial,refresh,retry,expire,minimum, recordModifiers...)
|
||||||
|
var SOA = recordBuilder('SOA', {
|
||||||
|
args: [
|
||||||
|
['name', _.isString],
|
||||||
|
['target', _.isString],
|
||||||
|
['mbox', _.isString],
|
||||||
|
['refresh', _.isNumber],
|
||||||
|
['retry', _.isNumber],
|
||||||
|
['expire', _.isNumber],
|
||||||
|
['minttl', _.isNumber],
|
||||||
|
],
|
||||||
|
transform: function(record, args, modifiers) {
|
||||||
|
record.name = args.name;
|
||||||
|
record.target = args.target;
|
||||||
|
record.soambox = args.mbox;
|
||||||
|
record.soarefresh = args.refresh;
|
||||||
|
record.soaretry = args.retry;
|
||||||
|
record.soaexpire = args.expire;
|
||||||
|
record.soaminttl = args.minttl;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// SRV(name,priority,weight,port,target, recordModifiers...)
|
// SRV(name,priority,weight,port,target, recordModifiers...)
|
||||||
var SRV = recordBuilder('SRV', {
|
var SRV = recordBuilder('SRV', {
|
||||||
args: [
|
args: [
|
||||||
|
3
pkg/js/parse_tests/038-soa.js
Normal file
3
pkg/js/parse_tests/038-soa.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
D("foo.com","none",
|
||||||
|
SOA('@', 'ns1.foo.com.', 'admin.foo.com', 3600, 900, 604800, 86400)
|
||||||
|
);
|
23
pkg/js/parse_tests/038-soa.json
Normal file
23
pkg/js/parse_tests/038-soa.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"registrars": [],
|
||||||
|
"dns_providers": [],
|
||||||
|
"domains": [
|
||||||
|
{
|
||||||
|
"name": "foo.com",
|
||||||
|
"registrar": "none",
|
||||||
|
"dnsProviders": {},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "SOA",
|
||||||
|
"name": "@",
|
||||||
|
"target": "ns1.foo.com.",
|
||||||
|
"soambox": "admin.foo.com",
|
||||||
|
"soarefresh": 3600,
|
||||||
|
"soaexpire": 604800,
|
||||||
|
"soaretry": 900,
|
||||||
|
"soaminttl": 86400
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
pkg/js/parse_tests/038-soa/foo.com.zone
Normal file
2
pkg/js/parse_tests/038-soa/foo.com.zone
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
$TTL 300
|
||||||
|
@ IN SOA ns1.foo.com. admin.foo.com 0 3600 900 604800 86400
|
205
pkg/js/static.go
205
pkg/js/static.go
@ -212,24 +212,24 @@ 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: 32454,
|
size: 33082,
|
||||||
modtime: 0,
|
modtime: 0,
|
||||||
compressed: `
|
compressed: `
|
||||||
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
|
||||||
@ -262,98 +262,101 @@ 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
|
||||||
|
BAAA//+k69kyOoEAAA==
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
|
|||||||
"TLSA": true,
|
"TLSA": true,
|
||||||
"IMPORT_TRANSFORM": false,
|
"IMPORT_TRANSFORM": false,
|
||||||
"MX": true,
|
"MX": true,
|
||||||
|
"SOA": true,
|
||||||
"SRV": true,
|
"SRV": true,
|
||||||
"SSHFP": true,
|
"SSHFP": true,
|
||||||
"TXT": true,
|
"TXT": true,
|
||||||
@ -124,6 +125,28 @@ func checkLabel(label string, rType string, target, domain string, meta map[stri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkSoa(expire uint32, minttl uint32, refresh uint32, retry uint32, serial uint32, mbox string) error {
|
||||||
|
if expire <= 0 {
|
||||||
|
return fmt.Errorf("SOA Expire must be > 0")
|
||||||
|
}
|
||||||
|
if minttl <= 0 {
|
||||||
|
return fmt.Errorf("SOA Minimum TTL must be > 0")
|
||||||
|
}
|
||||||
|
if refresh <= 0 {
|
||||||
|
return fmt.Errorf("SOA Refresh must be > 0")
|
||||||
|
}
|
||||||
|
if retry <= 0 {
|
||||||
|
return fmt.Errorf("SOA Retry must be > 0")
|
||||||
|
}
|
||||||
|
if mbox == "" {
|
||||||
|
return fmt.Errorf("SOA MBox must be specified")
|
||||||
|
}
|
||||||
|
if strings.ContainsRune(mbox, '@') {
|
||||||
|
return fmt.Errorf("SOA MBox must have '.' instead of '@'")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// checkTargets returns true if rec.Target is valid for the rec.Type.
|
// checkTargets returns true if rec.Target is valid for the rec.Type.
|
||||||
func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
||||||
label := rec.GetLabel()
|
label := rec.GetLabel()
|
||||||
@ -161,7 +184,11 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||||||
case "ALIAS":
|
case "ALIAS":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
case "SOA":
|
case "SOA":
|
||||||
|
check(checkSoa(rec.SoaExpire, rec.SoaMinttl, rec.SoaRefresh, rec.SoaRetry, rec.SoaSerial, rec.SoaMbox))
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
|
if label != "@" {
|
||||||
|
check(fmt.Errorf("SOA record is only valid for bare domain."))
|
||||||
|
}
|
||||||
case "SRV":
|
case "SRV":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
case "TXT", "IMPORT_TRANSFORM", "CAA", "SSHFP", "TLSA", "DS":
|
case "TXT", "IMPORT_TRANSFORM", "CAA", "SSHFP", "TLSA", "DS":
|
||||||
@ -524,6 +551,7 @@ var providerCapabilityChecks = []pairTypeCapability{
|
|||||||
capabilityCheck("PTR", providers.CanUsePTR),
|
capabilityCheck("PTR", providers.CanUsePTR),
|
||||||
capabilityCheck("R53_ALIAS", providers.CanUseRoute53Alias),
|
capabilityCheck("R53_ALIAS", providers.CanUseRoute53Alias),
|
||||||
capabilityCheck("SSHFP", providers.CanUseSSHFP),
|
capabilityCheck("SSHFP", providers.CanUseSSHFP),
|
||||||
|
capabilityCheck("SOA", providers.CanUseSOA),
|
||||||
capabilityCheck("SRV", providers.CanUseSRV),
|
capabilityCheck("SRV", providers.CanUseSRV),
|
||||||
capabilityCheck("TLSA", providers.CanUseTLSA),
|
capabilityCheck("TLSA", providers.CanUseTLSA),
|
||||||
capabilityCheck("AZURE_ALIAS", providers.CanUseAzureAlias),
|
capabilityCheck("AZURE_ALIAS", providers.CanUseAzureAlias),
|
||||||
|
@ -9,6 +9,73 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v3/providers"
|
"github.com/StackExchange/dnscontrol/v3/providers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestSoaLabelAndTarget(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
isError bool
|
||||||
|
label string
|
||||||
|
target string
|
||||||
|
}{
|
||||||
|
{false, "@", "ns1.foo.com."},
|
||||||
|
// Invalid target
|
||||||
|
{true, "@", "ns1.foo.com"},
|
||||||
|
// Invalid label, only '@' is allowed for SOA records
|
||||||
|
{true, "foo.com", "ns1.foo.com."},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
experiment := fmt.Sprintf("%s %s", test.label, test.target)
|
||||||
|
rc := makeRC(test.label, "foo.com", test.target, models.RecordConfig{Type: "SOA",
|
||||||
|
SoaExpire: 1, SoaMinttl: 1, SoaRefresh: 1, SoaRetry: 1, SoaSerial: 1, SoaMbox: "bar.foo.com"})
|
||||||
|
err := checkTargets(rc, "foo.com")
|
||||||
|
if err != nil && !test.isError {
|
||||||
|
t.Errorf("%v: Error (%v)\n", experiment, err)
|
||||||
|
}
|
||||||
|
if err == nil && test.isError {
|
||||||
|
t.Errorf("%v: Expected error but got none \n", experiment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSoa(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
isError bool
|
||||||
|
expire uint32
|
||||||
|
minttl uint32
|
||||||
|
refresh uint32
|
||||||
|
retry uint32
|
||||||
|
serial uint32
|
||||||
|
mbox string
|
||||||
|
}{
|
||||||
|
// Expire
|
||||||
|
{false, 123, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
{true, 0, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
// MinTTL
|
||||||
|
{false, 123, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
{true, 123, 0, 123, 123, 123, "foo.bar.com."},
|
||||||
|
// Refresh
|
||||||
|
{false, 123, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
{true, 123, 123, 0, 123, 123, "foo.bar.com."},
|
||||||
|
// Retry
|
||||||
|
{false, 123, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
{true, 123, 123, 123, 0, 123, "foo.bar.com."},
|
||||||
|
// Serial
|
||||||
|
{false, 123, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
{false, 123, 123, 123, 123, 0, "foo.bar.com."},
|
||||||
|
// MBox
|
||||||
|
{true, 123, 123, 123, 123, 123, ""},
|
||||||
|
{true, 123, 123, 123, 123, 123, "foo@bar.com."},
|
||||||
|
{false, 123, 123, 123, 123, 123, "foo.bar.com."},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
experiment := fmt.Sprintf("%d %d %d %d %d %s", test.expire, test.minttl, test.refresh,
|
||||||
|
test.retry, test.serial, test.mbox)
|
||||||
|
t.Run(experiment, func(t *testing.T) {
|
||||||
|
err := checkSoa(test.expire, test.minttl, test.refresh, test.retry, test.serial, test.mbox)
|
||||||
|
checkError(t, err, test.isError, experiment)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCheckLabel(t *testing.T) {
|
func TestCheckLabel(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
label string
|
label string
|
||||||
|
@ -66,6 +66,9 @@ const (
|
|||||||
|
|
||||||
// CanUseAzureAlias indicates the provider support the specific Azure_ALIAS records that only the Azure provider supports
|
// CanUseAzureAlias indicates the provider support the specific Azure_ALIAS records that only the Azure provider supports
|
||||||
CanUseAzureAlias
|
CanUseAzureAlias
|
||||||
|
|
||||||
|
// CanUseSOA indicates the provider supports full management of a zone's SOA record
|
||||||
|
CanUseSOA
|
||||||
)
|
)
|
||||||
|
|
||||||
var providerCapabilities = map[string]map[Capability]bool{}
|
var providerCapabilities = map[string]map[Capability]bool{}
|
||||||
|
@ -25,11 +25,12 @@ func _() {
|
|||||||
_ = x[CanUseRoute53Alias-14]
|
_ = x[CanUseRoute53Alias-14]
|
||||||
_ = x[CanGetZones-15]
|
_ = x[CanGetZones-15]
|
||||||
_ = x[CanUseAzureAlias-16]
|
_ = x[CanUseAzureAlias-16]
|
||||||
|
_ = x[CanUseSOA-17]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Capability_name = "CanUseAliasCanUseCAACanUseDSCanUseDSForChildrenCanUsePTRCanUseNAPTRCanUseSRVCanUseSSHFPCanUseTLSACanAutoDNSSECCantUseNOPURGEDocOfficiallySupportedDocDualHostDocCreateDomainsCanUseRoute53AliasCanGetZonesCanUseAzureAlias"
|
const _Capability_name = "CanUseAliasCanUseCAACanUseDSCanUseDSForChildrenCanUsePTRCanUseNAPTRCanUseSRVCanUseSSHFPCanUseTLSACanAutoDNSSECCantUseNOPURGEDocOfficiallySupportedDocDualHostDocCreateDomainsCanUseRoute53AliasCanGetZonesCanUseAzureAliasCanUseSOA"
|
||||||
|
|
||||||
var _Capability_index = [...]uint8{0, 11, 20, 28, 47, 56, 67, 76, 87, 97, 110, 124, 146, 157, 173, 191, 202, 218}
|
var _Capability_index = [...]uint8{0, 11, 20, 28, 47, 56, 67, 76, 87, 97, 110, 124, 146, 157, 173, 191, 202, 218, 227}
|
||||||
|
|
||||||
func (i Capability) String() string {
|
func (i Capability) String() string {
|
||||||
if i >= Capability(len(_Capability_index)-1) {
|
if i >= Capability(len(_Capability_index)-1) {
|
||||||
|
Reference in New Issue
Block a user