mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
New RTYPE: DS records now supported! (#753)
Thanks to @haraldkoch for starting this, @McNetic for picking it up. * Added DS record type * Added DS for cloudflare provider with tests * Removed DS validation, fixed parse test * Added generated files * Added dnsimple ds record * Regenerated documentation matrix * rebased and regenerated * Updated integration tests * Rebase and regenerate * Enable DS record type for provider desec * Added DS record type * Added DS for cloudflare provider with tests * Removed DS validation, fixed parse test * Added generated files * Added dnsimple ds record * Regenerated documentation matrix * rebased and regenerated * Updated integration tests * Rebase and regenerate * Enable DS record type for provider desec * Rebase and fixes Co-authored-by: Robert Koch <robert@kochie.io> Co-authored-by: Nicolai Ehemann <nicolai.ehemann@enerko-informatik.de>
This commit is contained in:
@ -40,6 +40,7 @@ func generateFeatureMatrix() error {
|
|||||||
{"TXTMulti", "Provider can manage TXT records with multiple strings"},
|
{"TXTMulti", "Provider can manage TXT records with multiple strings"},
|
||||||
{"R53_ALIAS", "Provider supports Route 53 limited ALIAS"},
|
{"R53_ALIAS", "Provider supports Route 53 limited ALIAS"},
|
||||||
{"AZURE_ALIAS", "Provider supports Azure DNS limited ALIAS"},
|
{"AZURE_ALIAS", "Provider supports Azure DNS limited ALIAS"},
|
||||||
|
{"DS", "Provider supports adding DS records"},
|
||||||
|
|
||||||
{"dual host", "This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records"},
|
{"dual host", "This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records"},
|
||||||
{"create-domains", "This means the provider can automatically create domains that do not currently exist on your account. The 'dnscontrol create-domains' command will initialize any missing domains"},
|
{"create-domains", "This means the provider can automatically create domains that do not currently exist on your account. The 'dnscontrol create-domains' command will initialize any missing domains"},
|
||||||
@ -87,6 +88,7 @@ func generateFeatureMatrix() error {
|
|||||||
setCap("TLSA", providers.CanUseTLSA)
|
setCap("TLSA", providers.CanUseTLSA)
|
||||||
setCap("TXTMulti", providers.CanUseTXTMulti)
|
setCap("TXTMulti", providers.CanUseTXTMulti)
|
||||||
setCap("get-zones", providers.CanGetZones)
|
setCap("get-zones", providers.CanGetZones)
|
||||||
|
setCap("DS", providers.CanUseDS)
|
||||||
setDoc("dual host", providers.DocDualHost, false)
|
setDoc("dual host", providers.DocDualHost, false)
|
||||||
setDoc("create-domains", providers.DocCreateDomains, true)
|
setDoc("create-domains", providers.DocCreateDomains, true)
|
||||||
|
|
||||||
|
30
docs/_functions/domain/DS.md
Normal file
30
docs/_functions/domain/DS.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: DS
|
||||||
|
parameters:
|
||||||
|
- name
|
||||||
|
- keytag
|
||||||
|
- algorithm
|
||||||
|
- digesttype
|
||||||
|
- digest
|
||||||
|
- modifiers...
|
||||||
|
---
|
||||||
|
|
||||||
|
DS adds a DS record to the domain.
|
||||||
|
|
||||||
|
Key Tag should be a number.
|
||||||
|
|
||||||
|
Algorithm should be a number.
|
||||||
|
|
||||||
|
Digest Type must be a number.
|
||||||
|
|
||||||
|
Digest must be a string.
|
||||||
|
|
||||||
|
{% include startExample.html %}
|
||||||
|
{% highlight js %}
|
||||||
|
|
||||||
|
D("example.com", REGISTRAR, DnsProvider(R53),
|
||||||
|
DS("example.com", 2371, 13, 2, "ABCDEF")
|
||||||
|
);
|
||||||
|
|
||||||
|
{%endhighlight%}
|
||||||
|
{% include endExample.html %}
|
@ -28,6 +28,7 @@
|
|||||||
<th class="rotate"><div><span>OCTODNS</span></div></th>
|
<th class="rotate"><div><span>OCTODNS</span></div></th>
|
||||||
<th class="rotate"><div><span>OPENSRS</span></div></th>
|
<th class="rotate"><div><span>OPENSRS</span></div></th>
|
||||||
<th class="rotate"><div><span>OVH</span></div></th>
|
<th class="rotate"><div><span>OVH</span></div></th>
|
||||||
|
<th class="rotate"><div><span>POWERDNS</span></div></th>
|
||||||
<th class="rotate"><div><span>ROUTE53</span></div></th>
|
<th class="rotate"><div><span>ROUTE53</span></div></th>
|
||||||
<th class="rotate"><div><span>SOFTLAYER</span></div></th>
|
<th class="rotate"><div><span>SOFTLAYER</span></div></th>
|
||||||
<th class="rotate"><div><span>VULTR</span></div></th>
|
<th class="rotate"><div><span>VULTR</span></div></th>
|
||||||
@ -102,6 +103,9 @@
|
|||||||
<td class="danger">
|
<td class="danger">
|
||||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="danger">
|
||||||
|
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -189,6 +193,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="The provider has registrar capabilities to set nameservers for zones">Registrar</th>
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="The provider has registrar capabilities to set nameservers for zones">Registrar</th>
|
||||||
@ -258,6 +265,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="danger">
|
||||||
|
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -316,6 +326,9 @@
|
|||||||
<td class="danger">
|
<td class="danger">
|
||||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="R53 does not provide a generic ALIAS functionality. Use R53_ALIAS instead.">
|
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="R53 does not provide a generic ALIAS functionality. Use R53_ALIAS instead.">
|
||||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -356,6 +369,9 @@
|
|||||||
<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 class="info" data-toggle="tooltip" data-container="body" data-placement="top" title="Need support in library first">
|
||||||
|
<i class="fa fa-circle-o text-info" aria-hidden="true"></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>
|
||||||
@ -419,6 +435,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
@ -485,6 +504,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td class="danger">
|
<td class="danger">
|
||||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||||
@ -525,6 +547,7 @@
|
|||||||
<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>
|
<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>
|
||||||
@ -597,6 +620,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider can manage SSHFP records">SSHFP</th>
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider can manage SSHFP records">SSHFP</th>
|
||||||
@ -642,6 +668,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></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 class="success">
|
<td class="success">
|
||||||
@ -696,6 +725,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></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 class="danger">
|
<td class="danger">
|
||||||
@ -744,6 +776,7 @@
|
|||||||
<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 class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -776,6 +809,7 @@
|
|||||||
<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 class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -811,6 +845,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>
|
||||||
<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>
|
||||||
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports adding DS records">DS</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 class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></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>
|
<tr>
|
||||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records">dual host</th>
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records">dual host</th>
|
||||||
@ -872,6 +944,7 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -949,6 +1022,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td class="danger">
|
<td class="danger">
|
||||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
@ -1033,6 +1109,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="indicates the dnscontrol get-zones subcommand is implemented.">get-zones</th>
|
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="indicates the dnscontrol get-zones subcommand is implemented.">get-zones</th>
|
||||||
@ -1099,6 +1178,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td class="info">
|
<td class="info">
|
||||||
<i class="fa fa-circle-o text-info" aria-hidden="true"></i>
|
<i class="fa fa-circle-o text-info" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
|
1
go.mod
1
go.mod
@ -34,6 +34,7 @@ require (
|
|||||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
||||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
||||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
||||||
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
||||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
|
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
|
||||||
github.com/sergi/go-diff v1.1.0 // indirect
|
github.com/sergi/go-diff v1.1.0 // indirect
|
||||||
|
@ -373,6 +373,15 @@ func naptr(name string, order uint16, preference uint16, flags string, service s
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ds(name string, keyTag uint16, algorithm, digestType uint8, digest string) *rec {
|
||||||
|
r := makeRec(name, "", "DS")
|
||||||
|
r.DsKeyTag = keyTag
|
||||||
|
r.DsAlgorithm = algorithm
|
||||||
|
r.DsDigestType = digestType
|
||||||
|
r.DsDigest = digest
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func srv(name string, priority, weight, port uint16, target string) *rec {
|
func srv(name string, priority, weight, port uint16, target string) *rec {
|
||||||
r := makeRec(name, target, "SRV")
|
r := makeRec(name, target, "SRV")
|
||||||
r.SrvPriority = priority
|
r.SrvPriority = priority
|
||||||
@ -829,6 +838,18 @@ func makeTests(t *testing.T) []*TestGroup {
|
|||||||
txtmulti("foo3", []string{strings.Repeat("X", 255), strings.Repeat("Y", 255), strings.Repeat("Z", 255)})),
|
txtmulti("foo3", []string{strings.Repeat("X", 255), strings.Repeat("Y", 255), strings.Repeat("Z", 255)})),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
testgroup("DS",
|
||||||
|
requires(providers.canUseDS),
|
||||||
|
tc("create DS", ds("@", 1, 13, 1, "ADIGEST")),
|
||||||
|
tc("modify field 1", ds("@", 65535, 13, 1, "ADIGEST")),
|
||||||
|
tc("modify field 3", ds("@", 65535, 13, 2, "ADIGEST")),
|
||||||
|
tc("modify field 2+3", ds("@", 65535, 1, 4, "ADIGEST")),
|
||||||
|
tc("modify field 2", ds("@", 65535, 3, 4, "ADIGEST")),
|
||||||
|
tc("modify field 2", ds("@", 65535, 254, 4, "ADIGEST")),
|
||||||
|
tc("delete 1, create 1", ds("foo", 2, 13, 4, "ADIGEST")),
|
||||||
|
tc("add 2 more DS", ds("foo", 2, 13, 4, "ADIGEST"), ds("@", 65535, 5, 4, "ADIGEST"), ds("@", 65535, 253, 4, "ADIGEST")),
|
||||||
|
),
|
||||||
|
|
||||||
//
|
//
|
||||||
// Pseudo rtypes:
|
// Pseudo rtypes:
|
||||||
//
|
//
|
||||||
|
22
integrationTest/testing.txt
Normal file
22
integrationTest/testing.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
go test -v -verbose -provider BIND
|
||||||
|
go test -v -verbose -provider AZURE_DNS
|
||||||
|
go test -v -verbose -provider ROUTE53
|
||||||
|
go test -v -verbose -provider GCLOUD
|
||||||
|
go test -v -verbose -provider DIGITALOCEAN
|
||||||
|
go test -v -verbose -provider GANDI_V5
|
||||||
|
|
||||||
|
-run TestDNSProviders -start 5 -end 6
|
||||||
|
|
||||||
|
DONE go test -v -provider BIND
|
||||||
|
DONE go test -v -provider AZURE_DNS
|
||||||
|
DONE go test -v -provider ROUTE53
|
||||||
|
DONE go test -v -provider GCLOUD
|
||||||
|
REPORTED go test -v -provider NAMEDOTCOM
|
||||||
|
REPORTED go test -v -provider CLOUDFLAREAPI
|
||||||
|
DONE go test -v -provider DIGITALOCEAN
|
||||||
|
DONE go test -v -provider GANDI_V5
|
||||||
|
|
||||||
|
go test -v -verbose -provider NAMEDOTCOM -run TestDNSProviders -start 5 -end 6
|
||||||
|
go test -v -verbose -provider CLOUDFLAREAPI -run TestDNSProviders -start 5 -end 6
|
@ -71,6 +71,8 @@ func RRtoRC(rr dns.RR, origin string) RecordConfig {
|
|||||||
panicInvalid(rc.SetTargetCAA(v.Flag, v.Tag, v.Value))
|
panicInvalid(rc.SetTargetCAA(v.Flag, v.Tag, v.Value))
|
||||||
case *dns.CNAME:
|
case *dns.CNAME:
|
||||||
panicInvalid(rc.SetTarget(v.Target))
|
panicInvalid(rc.SetTarget(v.Target))
|
||||||
|
case *dns.DS:
|
||||||
|
panicInvalid(rc.SetTargetDS(v.KeyTag, v.Algorithm, v.DigestType, v.Digest))
|
||||||
case *dns.MX:
|
case *dns.MX:
|
||||||
panicInvalid(rc.SetTargetMX(v.Preference, v.Mx))
|
panicInvalid(rc.SetTargetMX(v.Preference, v.Mx))
|
||||||
case *dns.NS:
|
case *dns.NS:
|
||||||
|
@ -79,7 +79,7 @@ func (dc *DomainConfig) Punycode() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "A", "AAAA", "CAA", "NAPTR", "SOA", "SSHFP", "TXT", "TLSA", "AZURE_ALIAS":
|
case "A", "AAAA", "CAA", "DS", "NAPTR", "SOA", "SSHFP", "TXT", "TLSA", "AZURE_ALIAS":
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
default:
|
default:
|
||||||
msg := fmt.Sprintf("Punycode rtype %v unimplemented", rec.Type)
|
msg := fmt.Sprintf("Punycode rtype %v unimplemented", rec.Type)
|
||||||
|
@ -77,6 +77,10 @@ type RecordConfig struct {
|
|||||||
SrvPort uint16 `json:"srvport,omitempty"`
|
SrvPort uint16 `json:"srvport,omitempty"`
|
||||||
CaaTag string `json:"caatag,omitempty"`
|
CaaTag string `json:"caatag,omitempty"`
|
||||||
CaaFlag uint8 `json:"caaflag,omitempty"`
|
CaaFlag uint8 `json:"caaflag,omitempty"`
|
||||||
|
DsKeyTag uint16 `json:"dskeytag,omitempty"`
|
||||||
|
DsAlgorithm uint8 `json:"dsalgorithm,omitempty"`
|
||||||
|
DsDigestType uint8 `json:"dsdigesttype,omitempty"`
|
||||||
|
DsDigest string `json:"dsdigest,omitempty"`
|
||||||
NaptrOrder uint16 `json:"naptrorder,omitempty"`
|
NaptrOrder uint16 `json:"naptrorder,omitempty"`
|
||||||
NaptrPreference uint16 `json:"naptrpreference,omitempty"`
|
NaptrPreference uint16 `json:"naptrpreference,omitempty"`
|
||||||
NaptrFlags string `json:"naptrflags,omitempty"`
|
NaptrFlags string `json:"naptrflags,omitempty"`
|
||||||
@ -242,6 +246,11 @@ func (rc *RecordConfig) ToRR() dns.RR {
|
|||||||
rr.(*dns.AAAA).AAAA = rc.GetTargetIP()
|
rr.(*dns.AAAA).AAAA = rc.GetTargetIP()
|
||||||
case dns.TypeCNAME:
|
case dns.TypeCNAME:
|
||||||
rr.(*dns.CNAME).Target = rc.GetTargetField()
|
rr.(*dns.CNAME).Target = rc.GetTargetField()
|
||||||
|
case dns.TypeDS:
|
||||||
|
rr.(*dns.DS).Algorithm = rc.DsAlgorithm
|
||||||
|
rr.(*dns.DS).DigestType = rc.DsDigestType
|
||||||
|
rr.(*dns.DS).Digest = rc.DsDigest
|
||||||
|
rr.(*dns.DS).KeyTag = rc.DsKeyTag
|
||||||
case dns.TypePTR:
|
case dns.TypePTR:
|
||||||
rr.(*dns.PTR).Ptr = rc.GetTargetField()
|
rr.(*dns.PTR).Ptr = rc.GetTargetField()
|
||||||
case dns.TypeNAPTR:
|
case dns.TypeNAPTR:
|
||||||
@ -388,7 +397,7 @@ func downcase(recs []*RecordConfig) {
|
|||||||
r.Name = strings.ToLower(r.Name)
|
r.Name = strings.ToLower(r.Name)
|
||||||
r.NameFQDN = strings.ToLower(r.NameFQDN)
|
r.NameFQDN = strings.ToLower(r.NameFQDN)
|
||||||
switch r.Type { // #rtype_variations
|
switch r.Type { // #rtype_variations
|
||||||
case "ANAME", "CNAME", "MX", "NS", "PTR", "NAPTR", "SRV":
|
case "ANAME", "CNAME", "DS", "MX", "NS", "PTR", "NAPTR", "SRV":
|
||||||
// These record types have a target that is case insensitive, so we downcase it.
|
// These record types have a target that is case insensitive, so we downcase it.
|
||||||
r.Target = strings.ToLower(r.Target)
|
r.Target = strings.ToLower(r.Target)
|
||||||
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TLSA", "TXT", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT":
|
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TLSA", "TXT", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT":
|
||||||
|
54
models/t_ds.go
Normal file
54
models/t_ds.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetTargetDS sets the DS fields.
|
||||||
|
func (rc *RecordConfig) SetTargetDS(keytag uint16, algorithm, digesttype uint8, digest string) error {
|
||||||
|
rc.DsKeyTag = keytag
|
||||||
|
rc.DsAlgorithm = algorithm
|
||||||
|
rc.DsDigestType = digesttype
|
||||||
|
rc.DsDigest = digest
|
||||||
|
|
||||||
|
if rc.Type == "" {
|
||||||
|
rc.Type = "DS"
|
||||||
|
}
|
||||||
|
if rc.Type != "DS" {
|
||||||
|
panic("assertion failed: SetTargetDS called when .Type is not DS")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTargetDSStrings is like SetTargetDS but accepts strings.
|
||||||
|
func (rc *RecordConfig) SetTargetDSStrings(keytag, algorithm, digesttype, digest string) error {
|
||||||
|
u16keytag, err := strconv.ParseUint(keytag, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "DS KeyTag can't fit in 16 bits")
|
||||||
|
}
|
||||||
|
u8algorithm, err := strconv.ParseUint(algorithm, 10, 8)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "DS Algorithm can't fit in 8 bits")
|
||||||
|
}
|
||||||
|
u8digesttype, err := strconv.ParseUint(digesttype, 10, 8)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "DS DigestType can't fit in 8 bits")
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc.SetTargetDS(uint16(u16keytag), uint8(u8algorithm), uint8(u8digesttype), digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTargetDSString is like SetTargetDS but accepts one big string.
|
||||||
|
func (rc *RecordConfig) SetTargetDSString(s string) error {
|
||||||
|
part := strings.Fields(s)
|
||||||
|
if len(part) != 4 {
|
||||||
|
return errors.Errorf("DS value does not contain 5 fields: (%#v)", s)
|
||||||
|
}
|
||||||
|
fmt.Println(part)
|
||||||
|
return rc.SetTargetDSStrings(part[0], part[1], part[2], part[3])
|
||||||
|
}
|
@ -37,6 +37,8 @@ func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error
|
|||||||
return r.SetTarget(contents)
|
return r.SetTarget(contents)
|
||||||
case "CAA":
|
case "CAA":
|
||||||
return r.SetTargetCAAString(contents)
|
return r.SetTargetCAAString(contents)
|
||||||
|
case "DS":
|
||||||
|
return r.SetTargetDSString(contents)
|
||||||
case "MX":
|
case "MX":
|
||||||
return r.SetTargetMXString(contents)
|
return r.SetTargetMXString(contents)
|
||||||
case "NAPTR":
|
case "NAPTR":
|
||||||
|
@ -88,6 +88,8 @@ func (rc *RecordConfig) GetTargetDebug() string {
|
|||||||
switch rc.Type { // #rtype_variations
|
switch rc.Type { // #rtype_variations
|
||||||
case "A", "AAAA", "CNAME", "NS", "PTR", "TXT":
|
case "A", "AAAA", "CNAME", "NS", "PTR", "TXT":
|
||||||
// Nothing special.
|
// Nothing special.
|
||||||
|
case "DS":
|
||||||
|
content += fmt.Sprintf(" ds_algorithm=%d ds_keytag=%d ds_digesttype=%d ds_digest=%s", rc.DsAlgorithm, rc.DsKeyTag, rc.DsDigestType, rc.DsDigest)
|
||||||
case "NAPTR":
|
case "NAPTR":
|
||||||
content += fmt.Sprintf(" naptrorder=%d naptrpreference=%d naptrflags=%s naptrservice=%s naptrregexp=%s", rc.NaptrOrder, rc.NaptrPreference, rc.NaptrFlags, rc.NaptrService, rc.NaptrRegexp)
|
content += fmt.Sprintf(" naptrorder=%d naptrpreference=%d naptrflags=%s naptrservice=%s naptrregexp=%s", rc.NaptrOrder, rc.NaptrPreference, rc.NaptrFlags, rc.NaptrService, rc.NaptrRegexp)
|
||||||
case "MX":
|
case "MX":
|
||||||
|
@ -260,6 +260,25 @@ var CAA = recordBuilder('CAA', {
|
|||||||
// CNAME(name,target, recordModifiers...)
|
// CNAME(name,target, recordModifiers...)
|
||||||
var CNAME = recordBuilder('CNAME');
|
var CNAME = recordBuilder('CNAME');
|
||||||
|
|
||||||
|
// DS(name, keytag, algorithm, digestype, digest)
|
||||||
|
var DS = recordBuilder("DS", {
|
||||||
|
args: [
|
||||||
|
['name', _.isString],
|
||||||
|
['keytag', _.isNumber],
|
||||||
|
['algorithm', _.isNumber],
|
||||||
|
['digesttype', _.isNumber],
|
||||||
|
['digest', _.isString]
|
||||||
|
],
|
||||||
|
transform: function(record, args, modifiers) {
|
||||||
|
record.name = args.name;
|
||||||
|
record.dskeytag = args.keytag;
|
||||||
|
record.dsalgorithm = args.algorithm;
|
||||||
|
record.dsdigesttype = args.digesttype;
|
||||||
|
record.dsdigest = args.digest;
|
||||||
|
record.target = args.target;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// PTR(name,target, recordModifiers...)
|
// PTR(name,target, recordModifiers...)
|
||||||
var PTR = recordBuilder('PTR');
|
var PTR = recordBuilder('PTR');
|
||||||
|
|
||||||
|
4
pkg/js/parse_tests/027-ds.js
Normal file
4
pkg/js/parse_tests/027-ds.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
D("foo.com","none",
|
||||||
|
DS("@", 1000, 13, 2, "AABBCCDDEEFF"),
|
||||||
|
DS("@", 1, 1, 1, "FFFF")
|
||||||
|
);
|
31
pkg/js/parse_tests/027-ds.json
Normal file
31
pkg/js/parse_tests/027-ds.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"registrars": [],
|
||||||
|
"dns_providers": [],
|
||||||
|
"domains": [
|
||||||
|
{
|
||||||
|
"name": "foo.com",
|
||||||
|
"registrar": "none",
|
||||||
|
"dnsProviders": {},
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"type": "DS",
|
||||||
|
"name": "@",
|
||||||
|
"target": "",
|
||||||
|
"dskeytag": 1000,
|
||||||
|
"dsalgorithm": 13,
|
||||||
|
"dsdigesttype": 2,
|
||||||
|
"dsdigest": "AABBCCDDEEFF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "DS",
|
||||||
|
"name": "@",
|
||||||
|
"target": "",
|
||||||
|
"dskeytag": 1,
|
||||||
|
"dsalgorithm": 1,
|
||||||
|
"dsdigesttype": 1,
|
||||||
|
"dsdigest": "FFFF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
189
pkg/js/static.go
189
pkg/js/static.go
@ -212,105 +212,106 @@ 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: 22817,
|
size: 23384,
|
||||||
modtime: 0,
|
modtime: 0,
|
||||||
compressed: `
|
compressed: `
|
||||||
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
|
||||||
Ef83AAD//yJmQYUhWQAA
|
F+YaT/l52b8fvP0Obu85dr4V+tPZRQfR8kMy81WRfhiRX4WDOHj7tvpK37C1ttyIjyj1iAyv+hXSSvqh
|
||||||
|
OWCkXZaQOe6QSMBaoO6e8FCI+L8BAAD//5AbCdFYWwAA
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
|
|||||||
"AAAA": true,
|
"AAAA": true,
|
||||||
"CNAME": true,
|
"CNAME": true,
|
||||||
"CAA": true,
|
"CAA": true,
|
||||||
|
"DS": true,
|
||||||
"TLSA": true,
|
"TLSA": true,
|
||||||
"IMPORT_TRANSFORM": false,
|
"IMPORT_TRANSFORM": false,
|
||||||
"MX": true,
|
"MX": true,
|
||||||
@ -185,7 +186,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
case "SRV":
|
case "SRV":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
case "TXT", "IMPORT_TRANSFORM", "CAA", "SSHFP", "TLSA":
|
case "TXT", "IMPORT_TRANSFORM", "CAA", "SSHFP", "TLSA", "DS":
|
||||||
default:
|
default:
|
||||||
if rec.Metadata["orig_custom_type"] != "" {
|
if rec.Metadata["orig_custom_type"] != "" {
|
||||||
// it is a valid custom type. We perform no validation on target
|
// it is a valid custom type. We perform no validation on target
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
|
|
||||||
var features = providers.DocumentationNotes{
|
var features = providers.DocumentationNotes{
|
||||||
providers.CanUseCAA: providers.Can(),
|
providers.CanUseCAA: providers.Can(),
|
||||||
|
providers.CanUseDS: providers.Can(),
|
||||||
providers.CanUsePTR: providers.Can(),
|
providers.CanUsePTR: providers.Can(),
|
||||||
providers.CanUseNAPTR: providers.Can(),
|
providers.CanUseNAPTR: providers.Can(),
|
||||||
providers.CanUseSRV: providers.Can(),
|
providers.CanUseSRV: providers.Can(),
|
||||||
|
@ -18,6 +18,9 @@ const (
|
|||||||
// CanUseCAA indicates the provider can handle CAA records
|
// CanUseCAA indicates the provider can handle CAA records
|
||||||
CanUseCAA
|
CanUseCAA
|
||||||
|
|
||||||
|
// CanUseDs indicates that the provider can handle DS record types
|
||||||
|
CanUseDS
|
||||||
|
|
||||||
// CanUsePTR indicates the provider can handle PTR records
|
// CanUsePTR indicates the provider can handle PTR records
|
||||||
CanUsePTR
|
CanUsePTR
|
||||||
|
|
||||||
|
@ -10,25 +10,26 @@ func _() {
|
|||||||
var x [1]struct{}
|
var x [1]struct{}
|
||||||
_ = x[CanUseAlias-0]
|
_ = x[CanUseAlias-0]
|
||||||
_ = x[CanUseCAA-1]
|
_ = x[CanUseCAA-1]
|
||||||
_ = x[CanUsePTR-2]
|
_ = x[CanUseDS-2]
|
||||||
_ = x[CanUseNAPTR-3]
|
_ = x[CanUsePTR-3]
|
||||||
_ = x[CanUseSRV-4]
|
_ = x[CanUseNAPTR-4]
|
||||||
_ = x[CanUseSSHFP-5]
|
_ = x[CanUseSRV-5]
|
||||||
_ = x[CanUseTLSA-6]
|
_ = x[CanUseSSHFP-6]
|
||||||
_ = x[CanUseTXTMulti-7]
|
_ = x[CanUseTLSA-7]
|
||||||
_ = x[CanAutoDNSSEC-8]
|
_ = x[CanUseTXTMulti-8]
|
||||||
_ = x[CantUseNOPURGE-9]
|
_ = x[CanAutoDNSSEC-9]
|
||||||
_ = x[DocOfficiallySupported-10]
|
_ = x[CantUseNOPURGE-10]
|
||||||
_ = x[DocDualHost-11]
|
_ = x[DocOfficiallySupported-11]
|
||||||
_ = x[DocCreateDomains-12]
|
_ = x[DocDualHost-12]
|
||||||
_ = x[CanUseRoute53Alias-13]
|
_ = x[DocCreateDomains-13]
|
||||||
_ = x[CanGetZones-14]
|
_ = x[CanUseRoute53Alias-14]
|
||||||
_ = x[CanUseAzureAlias-15]
|
_ = x[CanGetZones-15]
|
||||||
|
_ = x[CanUseAzureAlias-16]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Capability_name = "CanUseAliasCanUseCAACanUsePTRCanUseNAPTRCanUseSRVCanUseSSHFPCanUseTLSACanUseTXTMultiCanAutoDNSSECCantUseNOPURGEDocOfficiallySupportedDocDualHostDocCreateDomainsCanUseRoute53AliasCanGetZonesCanUseAzureAlias"
|
const _Capability_name = "CanUseAliasCanUseCAACanUseDSCanUsePTRCanUseNAPTRCanUseSRVCanUseSSHFPCanUseTLSACanUseTXTMultiCanAutoDNSSECCantUseNOPURGEDocOfficiallySupportedDocDualHostDocCreateDomainsCanUseRoute53AliasCanGetZonesCanUseAzureAlias"
|
||||||
|
|
||||||
var _Capability_index = [...]uint8{0, 11, 20, 29, 40, 49, 60, 70, 84, 97, 111, 133, 144, 160, 178, 189, 205}
|
var _Capability_index = [...]uint8{0, 11, 20, 28, 37, 48, 57, 68, 78, 92, 105, 119, 141, 152, 168, 186, 197, 213}
|
||||||
|
|
||||||
func (i Capability) String() string {
|
func (i Capability) String() string {
|
||||||
if i >= Capability(len(_Capability_index)-1) {
|
if i >= Capability(len(_Capability_index)-1) {
|
||||||
|
@ -44,6 +44,7 @@ var features = providers.DocumentationNotes{
|
|||||||
providers.CanUseSRV: providers.Can(),
|
providers.CanUseSRV: providers.Can(),
|
||||||
providers.CanUseTLSA: providers.Can(),
|
providers.CanUseTLSA: providers.Can(),
|
||||||
providers.CanUseSSHFP: providers.Can(),
|
providers.CanUseSSHFP: providers.Can(),
|
||||||
|
providers.CanUseDS: providers.Can(),
|
||||||
providers.DocCreateDomains: providers.Can(),
|
providers.DocCreateDomains: providers.Can(),
|
||||||
providers.DocDualHost: providers.Cannot("Cloudflare will not work well in situations where it is not the only DNS server"),
|
providers.DocDualHost: providers.Cannot("Cloudflare will not work well in situations where it is not the only DNS server"),
|
||||||
providers.DocOfficiallySupported: providers.Can(),
|
providers.DocOfficiallySupported: providers.Can(),
|
||||||
@ -473,9 +474,12 @@ type cfRecData struct {
|
|||||||
Selector uint8 `json:"selector"` // TLSA
|
Selector uint8 `json:"selector"` // TLSA
|
||||||
Matching_Type uint8 `json:"matching_type"` // TLSA
|
Matching_Type uint8 `json:"matching_type"` // TLSA
|
||||||
Certificate string `json:"certificate"` // TLSA
|
Certificate string `json:"certificate"` // TLSA
|
||||||
Algorithm uint8 `json:"algorithm"` // SSHFP
|
Algorithm uint8 `json:"algorithm"` // SSHFP/DS
|
||||||
Hash_Type uint8 `json:"type"` // SSHFP
|
Hash_Type uint8 `json:"type"` // SSHFP
|
||||||
Fingerprint string `json:"fingerprint"` // SSHFP
|
Fingerprint string `json:"fingerprint"` // SSHFP
|
||||||
|
KeyTag uint16 `json:"key_tag"` // DS
|
||||||
|
DigestType uint8 `json:"digest_type"` // DS
|
||||||
|
Digest string `json:"digest"` // DS
|
||||||
}
|
}
|
||||||
|
|
||||||
// cfTarget is a SRV target. A null target is represented by an empty string, but
|
// cfTarget is a SRV target. A null target is represented by an empty string, but
|
||||||
|
@ -127,6 +127,15 @@ func (c *CloudflareApi) createZone(domainName string) (string, error) {
|
|||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cfDSData(rec *models.RecordConfig) *cfRecData {
|
||||||
|
return &cfRecData{
|
||||||
|
KeyTag: rec.DsKeyTag,
|
||||||
|
Algorithm: rec.DsAlgorithm,
|
||||||
|
DigestType: rec.DsDigestType,
|
||||||
|
Digest: rec.DsDigest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func cfSrvData(rec *models.RecordConfig) *cfRecData {
|
func cfSrvData(rec *models.RecordConfig) *cfRecData {
|
||||||
serverParts := strings.Split(rec.GetLabelFQDN(), ".")
|
serverParts := strings.Split(rec.GetLabelFQDN(), ".")
|
||||||
c := &cfRecData{
|
c := &cfRecData{
|
||||||
@ -184,6 +193,9 @@ func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*
|
|||||||
if rec.Type == "MX" {
|
if rec.Type == "MX" {
|
||||||
prio = fmt.Sprintf(" %d ", rec.MxPreference)
|
prio = fmt.Sprintf(" %d ", rec.MxPreference)
|
||||||
}
|
}
|
||||||
|
if rec.Type == "DS" {
|
||||||
|
content = fmt.Sprintf("%d %d %d %s", rec.DsKeyTag, rec.DsAlgorithm, rec.DsDigestType, rec.DsDigest)
|
||||||
|
}
|
||||||
arr := []*models.Correction{{
|
arr := []*models.Correction{{
|
||||||
Msg: fmt.Sprintf("CREATE record: %s %s %d%s %s", rec.GetLabel(), rec.Type, rec.TTL, prio, content),
|
Msg: fmt.Sprintf("CREATE record: %s %s %d%s %s", rec.GetLabel(), rec.Type, rec.TTL, prio, content),
|
||||||
F: func() error {
|
F: func() error {
|
||||||
@ -208,6 +220,8 @@ func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*
|
|||||||
} else if rec.Type == "SSHFP" {
|
} else if rec.Type == "SSHFP" {
|
||||||
cf.Data = cfSshfpData(rec)
|
cf.Data = cfSshfpData(rec)
|
||||||
cf.Name = rec.GetLabelFQDN()
|
cf.Name = rec.GetLabelFQDN()
|
||||||
|
} else if rec.Type == "DS" {
|
||||||
|
cf.Data = cfDSData(rec)
|
||||||
}
|
}
|
||||||
endpoint := fmt.Sprintf(recordsURL, domainID)
|
endpoint := fmt.Sprintf(recordsURL, domainID)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
@ -270,6 +284,9 @@ func (c *CloudflareApi) modifyRecord(domainID, recID string, proxied bool, rec *
|
|||||||
} else if rec.Type == "SSHFP" {
|
} else if rec.Type == "SSHFP" {
|
||||||
r.Data = cfSshfpData(rec)
|
r.Data = cfSshfpData(rec)
|
||||||
r.Name = rec.GetLabelFQDN()
|
r.Name = rec.GetLabelFQDN()
|
||||||
|
} else if rec.Type == "DS" {
|
||||||
|
r.Data = cfDSData(rec)
|
||||||
|
r.Content = ""
|
||||||
}
|
}
|
||||||
endpoint := fmt.Sprintf(singleRecordURL, domainID, recID)
|
endpoint := fmt.Sprintf(singleRecordURL, domainID, recID)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
@ -40,6 +40,7 @@ var features = providers.DocumentationNotes{
|
|||||||
providers.DocCreateDomains: providers.Can(),
|
providers.DocCreateDomains: providers.Can(),
|
||||||
providers.CanUseAlias: providers.Cannot(),
|
providers.CanUseAlias: providers.Cannot(),
|
||||||
providers.CanUseSRV: providers.Can(),
|
providers.CanUseSRV: providers.Can(),
|
||||||
|
providers.CanUseDS: providers.Can(),
|
||||||
providers.CanUseSSHFP: providers.Can(),
|
providers.CanUseSSHFP: providers.Can(),
|
||||||
providers.CanUseCAA: providers.Can(),
|
providers.CanUseCAA: providers.Can(),
|
||||||
providers.CanUseTLSA: providers.Can(),
|
providers.CanUseTLSA: providers.Can(),
|
||||||
|
@ -20,6 +20,7 @@ var features = providers.DocumentationNotes{
|
|||||||
providers.CanUseAlias: providers.Can(),
|
providers.CanUseAlias: providers.Can(),
|
||||||
providers.CanUseCAA: providers.Can(),
|
providers.CanUseCAA: providers.Can(),
|
||||||
providers.CanUseNAPTR: providers.Can(),
|
providers.CanUseNAPTR: providers.Can(),
|
||||||
|
providers.CanUseDS: providers.Can(),
|
||||||
providers.CanUsePTR: providers.Can(),
|
providers.CanUsePTR: providers.Can(),
|
||||||
providers.CanUseSSHFP: providers.Can(),
|
providers.CanUseSSHFP: providers.Can(),
|
||||||
providers.CanUseSRV: providers.Can(),
|
providers.CanUseSRV: providers.Can(),
|
||||||
@ -94,6 +95,10 @@ func (client *DnsimpleApi) GetZoneRecords(domain string) (models.Records, error)
|
|||||||
if err := rec.SetTarget(r.Content); err != nil {
|
if err := rec.SetTarget(r.Content); err != nil {
|
||||||
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
}
|
}
|
||||||
|
case "DS":
|
||||||
|
if err := rec.SetTargetDSString(r.Content); err != nil {
|
||||||
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
|
}
|
||||||
case "MX":
|
case "MX":
|
||||||
if err := rec.SetTargetMX(uint16(r.Priority), r.Content); err != nil {
|
if err := rec.SetTargetMX(uint16(r.Priority), r.Content); err != nil {
|
||||||
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
@ -563,6 +568,8 @@ func getTargetRecordContent(rc *models.RecordConfig) string {
|
|||||||
return rc.GetTargetCombined()
|
return rc.GetTargetCombined()
|
||||||
case "SSHFP":
|
case "SSHFP":
|
||||||
return fmt.Sprintf("%d %d %s", rc.SshfpAlgorithm, rc.SshfpFingerprint, rc.GetTargetField())
|
return fmt.Sprintf("%d %d %s", rc.SshfpAlgorithm, rc.SshfpFingerprint, rc.GetTargetField())
|
||||||
|
case "DS":
|
||||||
|
return fmt.Sprintf("%d %d %d %s", rc.DsKeyTag, rc.DsAlgorithm, rc.DsDigestType, rc.DsDigest)
|
||||||
case "SRV":
|
case "SRV":
|
||||||
return fmt.Sprintf("%d %d %s", rc.SrvWeight, rc.SrvPort, rc.GetTargetField())
|
return fmt.Sprintf("%d %d %s", rc.SrvWeight, rc.SrvPort, rc.GetTargetField())
|
||||||
case "TXT":
|
case "TXT":
|
||||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -235,6 +235,7 @@ github.com/philhug/opensrs-go/opensrs
|
|||||||
github.com/pierrec/lz4
|
github.com/pierrec/lz4
|
||||||
github.com/pierrec/lz4/internal/xxh32
|
github.com/pierrec/lz4/internal/xxh32
|
||||||
# github.com/pkg/errors v0.9.1
|
# github.com/pkg/errors v0.9.1
|
||||||
|
## explicit
|
||||||
github.com/pkg/errors
|
github.com/pkg/errors
|
||||||
# github.com/pmezard/go-difflib v1.0.0
|
# github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/pmezard/go-difflib/difflib
|
github.com/pmezard/go-difflib/difflib
|
||||||
|
Reference in New Issue
Block a user