DIGITALOCEAN: Support TXTMulti with caveats (#949)

* DIGITALOCEAN: Support TXTMulti with caveats
* go get github.com/digitalocean/godo
* DIGITALOCEAN: Enable CI tests
This commit is contained in:
Tom Limoncelli 2020-11-18 08:22:31 -05:00 committed by GitHub
parent 13a1360779
commit 1f471a15b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 24 deletions

View file

@ -31,8 +31,6 @@ jobs:
fail-fast: false
matrix:
provider: [AZURE_DNS, BIND, CLOUDFLAREAPI, DIGITALOCEAN, GANDI_V5, GCLOUD, HEXONET, NAMEDOTCOM, ROUTE53]
exclude:
- provider: DIGITALOCEAN # remove when #636 is fixed
steps:
- name: Checkout repo
uses: actions/checkout@v2

View file

@ -472,8 +472,8 @@
<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 class="success" data-toggle="tooltip" data-container="body" data-placement="top" title="Semicolons not supported in issue/issuewild fields.">
<a href="https://www.digitalocean.com/docs/networking/dns/how-to/create-caa-records"><i class="fa has-tooltip fa-check text-success" aria-hidden="true"></i></a>
</td>
<td class="success">
<i class="fa fa-check text-success" aria-hidden="true"></i>
@ -888,7 +888,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 class="success" data-toggle="tooltip" data-container="body" data-placement="top" title="A broken parser prevents TXTMulti strings from including double-quotes; The total length of all strings can&#39;t be longer than 512; and in reality must be shorter due to sloppy validation checks.">
<a href="https://github.com/StackExchange/dnscontrol/issues/370"><i class="fa has-tooltip fa-check text-success" aria-hidden="true"></i></a>
</td>
<td class="success">
<i class="fa fa-check text-success" aria-hidden="true"></i>
</td>

View file

@ -38,5 +38,8 @@ D("example.tld", REG_NONE, DnsProvider(DIGITALOCEAN),
## Limitations
- Digialocean DNS doesn't support `;` value with CAA-records ([DigitalOcean documentation](https://www.digitalocean.com/docs/networking/dns/how-to/create-caa-records/))
- No support for TXT records with multiple strings, as the API prevents espacing quotes.
- Digitalocean DNS doesn't support `;` value with CAA-records ([DigitalOcean documentation](https://www.digitalocean.com/docs/networking/dns/how-to/create-caa-records/))
- While Digitalocean DNS supports TXT records with multiple strings,
their implementation is lacking. It does not support strings that
include double-quotes nor many long strings. The length limits may
restrict your ability to use very long DKIM or SPF records.

7
go.mod
View file

@ -18,7 +18,7 @@ require (
github.com/billputer/go-namecheap v0.0.0-20170915210158-0c7adb0710f8
github.com/cenkalti/backoff v2.1.1+incompatible // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/digitalocean/godo v1.46.0
github.com/digitalocean/godo v1.52.0
github.com/dnsimple/dnsimple-go v0.62.0
github.com/exoscale/egoscale v0.23.0
github.com/go-acme/lego v2.7.2+incompatible
@ -54,12 +54,13 @@ require (
github.com/urfave/cli/v2 v2.2.0
github.com/vultr/govultr v1.0.0
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58
golang.org/x/sync v0.0.0-20201008141435-b3e1573b7520 // indirect
golang.org/x/sys v0.0.0-20201018121011-98379d014ca7 // indirect
golang.org/x/tools v0.0.0-20201017001424-6003fad69a88 // indirect
google.golang.org/api v0.33.0
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20201015140912-32ed001d685c // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/ini.v1 v1.42.0 // indirect

12
go.sum
View file

@ -105,8 +105,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/digitalocean/godo v1.46.0 h1:WRbwjATilgz2NE4NGMeSDpeicy9h4xSKNGuRJ/Nq/fA=
github.com/digitalocean/godo v1.46.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
github.com/digitalocean/godo v1.52.0 h1:1QSUC0w5T1wS1d/1uvPtG8GLeD0p/4zhx1Q+Fxtna+k=
github.com/digitalocean/godo v1.52.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dnsimple/dnsimple-go v0.62.0 h1:Lr4U8F08FBL90rMEtQMR547RebifgwTPGCRC/+6ZW4g=
@ -446,8 +446,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0 h1:5kGOVHlq0euqwzgTC9Vu15p6fV1Wi0ArVi8da2urnVg=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
@ -457,6 +457,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BG
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 h1:Mj83v+wSRNEar42a/MQgxk9X42TdEmrOl9i+y8WbxLo=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -606,6 +608,8 @@ google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpC
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=

View file

@ -680,9 +680,11 @@ func makeTests(t *testing.T) []*TestGroup {
tc("Change a TXT", txt("foo", "changed")),
clear(),
tc("Create a TXT with spaces", txt("foo", "with spaces")),
tc("Create 1 TXT as array", txtmulti("foo", []string{"simple"})),
tc("Create 1 TXT as array", txtmulti("foo", []string{"simple"})), // Same as non-TXTMulti
clear(),
tc("Create a 255-byte TXT", txt("foo", strings.Repeat("A", 255))),
clear(),
tc("Create TXT with single-quote", txt("foo", "blah`blah")),
),
testgroup("ws TXT",
@ -862,6 +864,42 @@ func makeTests(t *testing.T) []*TestGroup {
txtmulti("foo2", []string{"one", "two"}),
txtmulti("foo3", []string{"eh", "bee", "cee"}),
),
tc("Change TXTMulti",
txtmulti("foo1", []string{"dimple"}),
txtmulti("foo2", []string{"fun", "two"}),
txtmulti("foo3", []string{"eh", "bzz", "cee"}),
),
tc("Long TXTMulti",
// This isn't the longest a TXT record can be, but it is the
// longest DIGITALOCEAN permits.
txtmulti("foo4", []string{strings.Repeat("X", 255), strings.Repeat("Y", 252)}),
),
),
testgroup("TXTMulti tests that break DO",
// DO's implementation of TXTMulti is broken, thus we separate out
// tests that fail for it. Users are warned about these limits
// in docs/_providers/digitalocean.md
requires(providers.CanUseTXTMulti),
not("DIGITALOCEAN"),
// Digital Ocean's TXT record implementation checks size limits wrong.
// RFC 1035 Section 3.3.14 states that each substring can be 255
// octets, and there is no limit on the number of such
// substrings, aside from the usual packet length limits. DO's
// implementation restricts the total length to be 512 octets,
// including any backlashes used for escapes, quotes, and other
// metachars. In other words, they're doing the checking on the
// API protocol encoded data instead of on on the resulting TXT
// record.
// Proper TXT implementations can handle TXT records like this:
tc("3x255-byte TXTMulti",
txtmulti("foo3", []string{strings.Repeat("X", 255), strings.Repeat("Y", 255), strings.Repeat("Z", 255)})),
clear(),
// Digital Ocean's TXT record implementation handles quotes wrong.
// It craps out if your TXT record includes double-quotes.
// Someone doesn't understand how zonefile-style quoting is
// supposed to work.
// Proper TXT implementations can handle TXT records like these:
tc("Create TXTMulti with quotes",
txtmulti("foo1", []string{"simple"}),
txtmulti("foo2", []string{"o\"ne", "tw\"o"}),
@ -869,11 +907,9 @@ func makeTests(t *testing.T) []*TestGroup {
),
tc("Change TXTMulti",
txtmulti("foo1", []string{"dimple"}),
txtmulti("foo2", []string{"fun", "two"}),
txtmulti("foo2", []string{"fun", "t\"wo"}),
txtmulti("foo3", []string{"eh", "bzz", "cee"}),
),
tc("3x255-byte TXTMulti",
txtmulti("foo3", []string{strings.Repeat("X", 255), strings.Repeat("Y", 255), strings.Repeat("Z", 255)})),
),
testgroup("DS",

View file

@ -74,11 +74,9 @@ var features = providers.DocumentationNotes{
providers.DocCreateDomains: providers.Can(),
providers.DocOfficiallySupported: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
// Digitalocean support CAA records, except
// ";" value with issue/issuewild records:
// https://www.digitalocean.com/docs/networking/dns/how-to/create-caa-records/
providers.CanUseCAA: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanUseCAA: providers.Can("Semicolons not supported in issue/issuewild fields.", "https://www.digitalocean.com/docs/networking/dns/how-to/create-caa-records"),
providers.CanGetZones: providers.Can(),
providers.CanUseTXTMulti: providers.Can("A broken parser prevents TXTMulti strings from including double-quotes; The total length of all strings can't be longer than 512; and in reality must be shorter due to sloppy validation checks.", "https://github.com/StackExchange/dnscontrol/issues/370"),
}
func init() {
@ -329,7 +327,7 @@ func pauseAndRetry(resp *godo.Response) bool {
}
// a simple exponential back-off with a 3-minute max.
log.Printf("Pausing due to ratelimit: %v seconds\n", backoff)
log.Printf("Delaying %v due to ratelimit\n", backoff)
time.Sleep(backoff)
backoff = backoff + (backoff / 2)
if backoff > maxBackoff {