diff --git a/docs/_functions/domain/AUTODNSSEC.md b/docs/_functions/domain/AUTODNSSEC.md deleted file mode 100644 index 152f8830e..000000000 --- a/docs/_functions/domain/AUTODNSSEC.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: AUTODNSSEC ---- - -AUTODNSSEC indicates that the DNS provider can automatically manage -DNSSEC for a domain and we should ask it to do so. - -At this time, AUTODNSSEC takes no parameters. -There is no ability to tune what the DNS provider sets, no algorithm choice. -We simply ask that they follow their defaults when enabling a no-fuss DNSSEC -data model. - -{% include startExample.html %} -{% highlight js %} -D("example.com", .... , - AUTODNSSEC, -); -{%endhighlight%} -{% include endExample.html %} diff --git a/docs/_functions/domain/AUTODNSSEC_OFF.md b/docs/_functions/domain/AUTODNSSEC_OFF.md new file mode 100644 index 000000000..c2e91fe5c --- /dev/null +++ b/docs/_functions/domain/AUTODNSSEC_OFF.md @@ -0,0 +1,8 @@ +--- +name: AUTODNSSEC_OFF +--- + +AUTODNSSEC_OFF tells the provider to disable AutoDNSSEC. It takes no +parameters. + +See `AUTODNSSEC_ON` for further details. diff --git a/docs/_functions/domain/AUTODNSSEC_ON.md b/docs/_functions/domain/AUTODNSSEC_ON.md new file mode 100644 index 000000000..a1f77f194 --- /dev/null +++ b/docs/_functions/domain/AUTODNSSEC_ON.md @@ -0,0 +1,35 @@ +--- +name: AUTODNSSEC_ON +--- + +AUTODNSSEC_ON tells the provider to enable AutoDNSSEC. + +AUTODNSSEC_OFF tells the provider to disable AutoDNSSEC. + +AutoDNSSEC is a feature where a DNS provider can automatically manage +DNSSEC for a domain. Not all providers support this. + +At this time, AUTODNSSEC_ON takes no parameters. There is no ability +to tune what the DNS provider sets, no algorithm choice. We simply +ask that they follow their defaults when enabling a no-fuss DNSSEC +data model. + +NOTE: No parenthesis should follow these keywords. That is, the +correct syntax is `AUTODNSSEC_ON` not `AUTODNSSEC_ON()` + +{% include startExample.html %} +{% highlight js %} +D("example.com", .... , + AUTODNSSEC_ON, // Enable AutoDNSSEC. + A("@", "10.1.1.1") +); + +D("insecure.com", .... , + AUTODNSSEC_OFF, // Disable AutoDNSSEC. + A("@", "10.2.2.2") +); +{%endhighlight%} +{% include endExample.html %} + +If neither `AUTODNSSEC_ON` or `AUTODNSSEC_OFF` is specified for a +domain no changes will be requested. diff --git a/docs/_providers/axfrddns.md b/docs/_providers/axfrddns.md index 54338f557..219ea81ca 100644 --- a/docs/_providers/axfrddns.md +++ b/docs/_providers/axfrddns.md @@ -191,6 +191,8 @@ The AXFR+DDNS provider is not able to create domain. The AXFR+DDNS provider is not able to ask the DNS server to sign the zone. But, it is able to check whether the server seems to do so or not. -When AutoDNSSEC is set, the AXFR+DDNS provider will emit a warning when no RRSIG, DNSKEY or NSEC records are found in the zone. +When AutoDNSSEC is enabled, the AXFR+DDNS provider will emit a warning when no RRSIG, DNSKEY or NSEC records are found in the zone. -When AutoDNSSEC is not set, the AXFR+DDNS provider will emit a warning when RRSIG, DNSKEY or NSEC records are found in the zone. +When AutoDNSSEC is disabled, the AXFR+DDNS provider will emit a warning when RRSIG, DNSKEY or NSEC records are found in the zone. + +When AutoDNSSEC is not enabled or disabled, no checking is done. diff --git a/models/domain.go b/models/domain.go index 2e0084693..eb547bfcb 100644 --- a/models/domain.go +++ b/models/domain.go @@ -18,7 +18,7 @@ type DomainConfig struct { KeepUnknown bool `json:"keepunknown,omitempty"` IgnoredNames []string `json:"ignored_names,omitempty"` IgnoredTargets []*IgnoreTarget `json:"ignored_targets,omitempty"` - AutoDNSSEC bool `json:"auto_dnssec,omitempty"` + AutoDNSSEC string `json:"auto_dnssec,omitempty"` // "", "on", "off" //DNSSEC bool `json:"dnssec,omitempty"` // These fields contain instantiated provider instances once everything is linked up. diff --git a/models/record.go b/models/record.go index 2bd1165a3..ed5d2be3f 100644 --- a/models/record.go +++ b/models/record.go @@ -28,7 +28,6 @@ import ( // TXT // Pseudo-Types: // ALIAS -// AUTODNSSEC // CF_REDIRECT // CF_TEMP_REDIRECT // FRAME diff --git a/pkg/js/helpers.js b/pkg/js/helpers.js index 76cb95eda..2053bb62c 100644 --- a/pkg/js/helpers.js +++ b/pkg/js/helpers.js @@ -2,6 +2,7 @@ // If you edit this file, you must run `go generate` to embed this // file in the source code. + // If you are heavily debugging this code, the "-dev" flag will // read this file directly instead of using the output of // `go generate`. You'll still need to run `go generate` before @@ -535,9 +536,21 @@ function NO_PURGE(d) { d.KeepUnknown = true; } -// AUTODNSSEC() +// AUTODNSSEC +// Permitted values are: +// "" Do not modify the setting (the default) +// "on" Enable AUTODNSSEC for this domain +// "off" Disable AUTODNSSEC for this domain +function AUTODNSSEC_ON(d) { + d.auto_dnssec = "on"; +} +function AUTODNSSEC_OFF(d) { + d.auto_dnssec = "off"; +} function AUTODNSSEC(d) { - d.auto_dnssec = true; + console.log( + "WARNING: AUTODNSSEC is deprecated. It is now a no-op. Please use AUTODNSSEC_ON or AUTODNSSEC_OFF. The default is to make no modifications. This message will disappear in a future release." + ); } /** diff --git a/pkg/js/parse_tests/025-autodnssec.js b/pkg/js/parse_tests/025-autodnssec.js index 3b2cb5288..68184a518 100644 --- a/pkg/js/parse_tests/025-autodnssec.js +++ b/pkg/js/parse_tests/025-autodnssec.js @@ -1,3 +1,8 @@ -D("foo.com","none", - AUTODNSSEC +D("nothing.com","none" +); +D("with.com","none", + AUTODNSSEC_ON +); +D("without.com","none", + AUTODNSSEC_OFF ); diff --git a/pkg/js/parse_tests/025-autodnssec.json b/pkg/js/parse_tests/025-autodnssec.json index dd8f5a2d6..07706e0df 100644 --- a/pkg/js/parse_tests/025-autodnssec.json +++ b/pkg/js/parse_tests/025-autodnssec.json @@ -3,11 +3,24 @@ "dns_providers": [], "domains": [ { - "name": "foo.com", + "name": "nothing.com", "registrar": "none", "dnsProviders": {}, - "records":[], - "auto_dnssec": true + "records": [] + }, + { + "name": "with.com", + "registrar": "none", + "dnsProviders": {}, + "records": [], + "auto_dnssec": "on" + }, + { + "name": "without.com", + "registrar": "none", + "dnsProviders": {}, + "records": [], + "auto_dnssec": "off" } ] } diff --git a/pkg/js/static.go b/pkg/js/static.go index b9be4028f..a099616a4 100644 --- a/pkg/js/static.go +++ b/pkg/js/static.go @@ -212,122 +212,124 @@ var _escData = map[string]*_escFile{ "/helpers.js": { name: "helpers.js", local: "pkg/js/helpers.js", - size: 26104, + size: 26563, modtime: 0, compressed: ` -H4sIAAAAAAAC/+x9aXcbN7Lod/2Kis+bNGm3qcWxZw4VzhtGkjN6o+2QVMYzerociA2SsJtAXwAtmkmU -334Ptm6gF0rWyfLl6oPDBgqFQqFQC1BAolxgEJKTmYwOd3Z2d+F0DhuWA06IBLkkAuYkxbEuW+VCAs8p -/GfBYIEp5kji/4BkgFd3ONHgCoVqAYSCXGIQLOczDDOW4J6HHnEMS4zuSbqBBN/liwWhC9OfAo112xev -E3z/AuYpWsCapKlqzzFKSrogIRzPZLoBQoVUVWwOuTC4MLBcZrkENlctA6J78C+WR2kKQpI0BYoV+axh -cHd4zjhW7RXZM7Zaab5gmC0RXWDR29m5RxxmjM5hAD/tAABwvCBCcsRFH25uY12WUDHNOLsnCQ6K2QoR -WiuYUrTCtvTh0HSR4DnKUznkCwEDuLk93NmZ53QmCaNAKJEEpeRH3OlaIgKK2qjaQlkjdQ+HhsgaKQ9a -dkZY5pwKQBQQ52ijZsPigPWSzJawxhxbSjDHCQgGczW2nKs54zmVZKW5fbmmUAxvzhSHVxmS5I6kRG6U -GAhGBTAOZA6CrTAkaAMiwzOCUsg4m2Gh5WDN8jSBO9Xrf+eE46RXsm2B5RGjc7LIOU6ODaEFA7kejOZj -z58VPdgCxQVejxxjO6o+BrnJcAwrLJFDRebQUaVdbzrUNwwGEJ0PL66HZ5Hh7IP+V003xws1faBw9qHE -3Pfw9/W/blY0peUs97JcLDscL7qH/ngUptoQjqm4siLw6CDY3PQ6UMSzu494JiP4+muISDadMXqPuSCM -ikhpAL+9+lPfvRAOBmp6V0hOpew01HerjElE9hzGBGJueJOI7DHeULw2cmHZUrC3IiXlED2y6kuvX/6M -A6b04acHH37GeFJfp1flMvXB7XKcTM76sBcHlAjM72vLmiwo4zjxlUy1SiK+wDJc+T5f7AI7RnwhOqvY -rnLHFGUDGAeMZktYsYTMCeaxEiAigQhAvV6vgLMY+zBDaaoA1kQuLT4HpJVJ33Wq2JNzQe5xunEQRg7V -tPMF1t1QyTRnEyRRIb/THhHvbY+dVTcQzY4dg5U3wKnARaOhoqDSQg2xoyTyoxZ1v0r9hSy6+XhbcOmw -gHto6utSj6XS2bSHP0tME0tlTw0thlVIraddlpytIfrncHRxevF93/ZcTIbRPjkVeZYxLnHShwheBeS7 -pV4pjsCsh3oDS5hZQ2Zwxiocm7VTLp0+HHGMJAYExxdji7AH1wJry5ohjlZYYi4ACbcWANFEkS889X3c -tii1mjAjHmxZwobMYhoJDGDvEAh86xu4XorpQi4Pgbx65U9IML0e/A2pTvRDvZsD0w3ii3yFqWztRMGv -YFAC3pDbw2YSVo29KpmqWbAeoQn+fDnXDOnCV4MBvN7v1qRH1cIriNSSTfAsRcpgrxhXs4QoMDrDgdXy -+nEK1ieoToaG0TQ4B+L42nz34TpLtIRQQKny+TaAkgQnnsAYRXHc6foSMT35MDm5OLYja5CG6QJL094u -M9u/Y5YDHADN03QLU9ZIAGWy5MwGSy2kcom5dhphhqiCuMOQ69EkRsaPO13rVvaiVgn5VQWxx+4+tgvj -/m8ojLWefSG5sTAkuYWB1+BQafQUy0gAu8d8zYk0msFo+Z4Vluap7MNERQfKzIBYKZuyxGmGeelNSuXf -Gyfezvb/G1vU1pwHTmJzN5Yvc8arUxYsgxZWVpal4uRNpPBGt1r0vB5Kn8A4GhFJoj6QWPteUR8qaB5q -xiVwcPI0Ldbayfvh9dlkDNYr0gzDUvvsRorKmVY8Q1mWbvSPNIV5LnPu+Cd0ZHeirL024pKVyFXcBrMU -Iw6IbiDj+J6wXMA9SnMsVIf+8rWtCh+8Hmi0LZRHpddfSVrx+GLcDS3WZHLWue/2YWzFZDI5050ae2Us -kke2AffcZGXFx1KFNJ37wIrfw0BH23QxYcc5R9oPuQ8WiJ0ph7zD/fa8J2UKA7g/bHLKGjB7KnCF5GyJ -FR/ve/p3Z/e/Ov8/edXt3IjVMlnTze3/7f6fXU8XFi3alOG9Mw9KzSE1pyRRsRzyyAlUXE6JhAFEIqr1 -cnNw63dgIcvKIAyAgfISBD6lsmi/72ZRDTbXIYLow34Mqz6824th2Yc37/b2XFCQ30SJWm2Q95bwEg6+ -KYrXtjiBl/DnopR6pW/2iuKNX/zuraUAXg4gv1FjuA0CjPti8RUueyBobuE5gSt1lL9K/La/kdQlwdLp -lRFGq/Ct0Cd8NBy+T9Gioxd3JUIqBVovn0CqzYKaIaS3en4eGO3gd7O7C0fD4fRodDo5PRqeKQ+SSDJD -qSrWO0R6j8SH0dJT0rQP334Lf+6aTS4/3n3hosILtMIvYtjrKggqjlhOtTbcgxVGVEDCaCQhFxgYL/Yw -tFbzIq2e31gtC4fdIlHNUZr601mLvW3zhsDbIdaxd04TPCcUJ5HPzAIEXu9/yQx70eWNIkOJtcVVmYih -IZNksZ25cxtViF6v19XzMISBrfsuJ6kaWTSMLO+Hw+FTMAyHTUiGwxLP2elwbBCZaHULMgXagE0VF+j+ -fT06mXpI7XbCo7jLdg09lJVRbPmtHKQ+3BS8t4Y/hnL9egH5TaTIiGKjXJHEwx9zjocpQWKyyXAIqUlt -wmT/IzmiYs74ql9djrEmKy4CxIblqT1f7f0JL8jzAEz3DsR8HQYujxfd2jZIjWaK1HC6dY+nCmKZcVv0 -sck8MmpBcDMSbRnMhlGBBOpuU7zz0PW3WJv5H6o6NcavfDWsK0NemlWIUoEbVudNNIxiMGIeQ3R0MTw/ -iW6LeM12ZgK2YtP17ZtQbK3AGvFtE9uiVV1oi6pfS2RHb9/85gIrfi+J5W/fbJfXAuD50lqg+DJZtcLw -78uLk86PjOIpSbqlANeq2uxzNVDxebBt+P7IbR968Pb3Y0OvjNq26rsfDcMOHZAmafuVl2enlN1wU2wY -xZUCvYLDMrOaq4V1uPMP1ZLJh0m16GoyqhaNr97XikY/VIsuhmHTFu2i67ue7+Us7SLWcO2a5ajJcOth -lrvDk8vjy45Myarbh1MJYukOaRAFzLk51dH9uOhiTzld+wd/6T1PIaFFe6Xu549TQjOEJFqUSmjxiJry -fWNDoOv+Il/dYd5AZbAK6h63qLrcpT7RMvs0J0uDNsy8lnrndzsj9QlvlCgBSheME7lcxZCQBRbGaJmf -Bu1x3UK9OB6/eK5pMh3besOwoL4gqB3EUGdt3FaYkIzfUaYSYcbpgMxXA1gxXAdZFDQAlwN30GVJK3gI -+gUm2JPCq8noaTJ4NRnVJVDpO4tIKz+DivEE8zjjeI45pjMc65UQqzCOzPRpBf6cPdqhRljv0irZZ8qo -Jq1dtkqa22H0YNp7sKNsBzDD36ZQ/1jPjaJMcs0nB6Y/muFKhjngsqS5hdGKFlh/NMNZPjpI+9kMa1jq -QM3X85bDePSDkeGME7VYN/Eak8VSxhnj8lGRHY9+qAusdhSeKa6OinZpNORtkWjGt9T+0bIm+L0bYik/ -5rsJ1gzWQZqvRpyMF1Dq9zNlYfz391dGGkpbqq3oI26abtggCKr42aLwBOs5J3SBecYJ3TLlf7BLJsRy -nn2BadTw3sAKzVEWfZFT5ybX+Eq5QAscg8ApnknGY7MpTujCOEszzCWZkxmSWE/s5Gzc4ICr0mdPq6ag -fbYcZe0QPsVfuNBBJ/15Y9HJegIQvDDwL4qzn99z5yAVSHPFQemPRjDHndJImO9GYJ9RroFf9gwlUSYJ -Wp5ecpPN8rmyA+BFxp+78PPPUCa+fC4iwcmHydNcscmHSYMUqkD2uZtKTjoq4/h9NINStdLkPmB7mCJA -rskM930YADcjRGjQOeFC2gZVwM/SIbLAhCbkniQ5Sl0XvbDNxeXkpA+nc5NkoLNoy4SMfdsoLs4chIus -GU03gGYzLEQrETHIZS6ASEgYFjSSSs9IzGG9RBLWatSqK0LdECu0/Z2t8T3mMdxtNKhLwvU5YOiOdYLW -SlGJBdyh2ac14kmFsjDfc73EJp84xbSj08G6MBjAvs646BAqMVVTjdJ004U7jtGnCro7zj5h6nEGI67T -hi3jJV7YY0uJhfT4XjlZ85ZZ2wbg9l1FH7AUgAHceNC3T9smbOroZu/28b4aCavtJZ5/qHiZjy358w/1 -FX/+4Tf0K/9oz3D1uSm0aHENn+TOXTzxROuiYd/+YlyGuecn45PRDydB2OztBVcA/A3SaiIFfDWAhuSw -qERRapdMCmAUFwZZn2GrDsJEp0eOIv3TVJ2p4ef6wkO3chxZEjJty9vwaLXphL0mXkx/iyP1n4CKqZRp -H+57kllk3ermdZkCXYjsVKK7FHsptRN9QnSTsrVOa1iSxbIPBzFQvP4OCdyHN7cxmOpvXPVbXX161Yd3 -t7cOkc6NfbEPv8AB/AJv4JdD+AZ+gbfwC8Av8O5FkUWREoofS7yp0LsteYyo6LcCH+SQKSBNLgyAZD39 -MzyP0UVVvRsm6RqQKow+Greop70VygxcXEohaWoS5E6tDhImO6R7WAN76PY+MkI7URxVahv1t0+MQ2vI -rjTeqf+yPFIzXnBJfdT4pAof5ZQGauGV7aLglvr+Q/llCfI4psl/Gs+U0hrATUFV1kvZuhuDV6CWTLdY -T3bleOKpl4O9VsHWdgTwC0TdpoVvoC3QIUSFC336/cXlyGyqeyrZLy3XfIIzjlVol8Q6dcRATZXO8vvy -isOE2lpFtUOvquU8sKKdg8sDQQpvoJUt9slw9P3JpFMzQE3VMfCJd0nmiXTYmwrWUmTaZaX94BS8bxCH -lkMTeX51OZpMJ6Phxfj95ejcKN9Ua3Ojnoqkam11q/B1G1yFqDo/N1Gti0hp7ch0Y35LmYY+z6/pzUR/ -ix5xTQwpdWcHS2TJL9W3PuAtjZdxbaoj7NY71FmMBlqm9f3+69H3Jx1PXExBIQFJ7x8YZ9f0E2Vrqggw -57XWH7ic1toXZa0oJM8LDMPryeXxxXh8cuTj8Eo9LCiXbJpQIfAswPLy5Q68hL+V63cHXu4GN88Kp65j -5k5IxGWQsMmSVuOrgYvM19akV31hwmW7Bomu3gpTQD7RIz1H5orInRFsPRZ9LwN+Mm7Pg6n3YJtgWCZF -T3d9e7N3C0PnFypZ9OEdXwZhk/1buMxMXOeO9xnf1q6QTnjvZXubzOUgmdnl8MJLx6oJ+oShNRsKCS/D -GIZ0Uy41k+J8hz1cqkOCE5vlb6+rWoJ63oH3KpfIprYvyD2mPlmtrFGDcbLTMMySLsk0ZoMzFL9Qa5l9 -RIXdyY76rU2/TfwUnZ8eDETsSVeh0xriuDI6U9qrDB6ep8KsNTSQhuFLdI+9wRa3RAzrqy0VbjdRgKhL -91dryrtuZPMpm+Ln9ljQ96uMvt66SdCkdp0P4rd7olv05D0Hzy/y5iOQpoY5aZ2NplCgAG5TR8FNEpbA -oGyi44AaYP3OHku6bX7niiUuubjB42y+Y7cF3e4umGuospRavajsPkpjI53QzhJPEX39tbePGlS19mwH -4yEJ7sgGOA4bMTw0lhZ3CD2Lrqe4nV/NBNotgJPR6HLUB2dEg8uFUQPKdnk0MYEVgKrjVw0jdeZ/Yu+E -/PQQho+lRrB35P2Zqe1tfFuaG1tUnROFs2h2RnQ+Q9GmNkQdKpURksSrR4IkBVLbsjPcqCO3IRNUYyYz -Hdoev6q1ipzWtPffRe3iplP4PhsaEZUWtNOEI2RTA4JuDy5puoGtjbcRoF8PELlR8dFhw/0ofztzJ1jJ -aaoUftHNzjZFVuVGoyKzknGsbAbRVtWTjGBbw0GbhLa2C3SekJY4HTf+Gu7B+TYxp6VvpB9DyBtMYJH+ -GGC/2b9tSIJ8smjVRCzaAhR2vHe7FV+xgWhHprfIEElrs75Nr+hbiYWuuKkSoCIX79i1XWYKldIsMw3C -8pT7aH7iXvuNtApVW2Pi8uUIPRmDhin13kmo1dWfIShaybQfXAIKQR4qhrvupja4E4f1JoVRK8DL2Qub -hvfOe25P1z540eABWL6ZOo+zwabFIyEbShIT7XQSl1wfJtyrOMrbuiFzKI8CqXYMY0BC5CsMJFPoOBai -VzgZxB6oVXzJBjey5jcGLqP/hMgskIKm2W96rsKgK/ZQdp4gB+7UI3iAIpQoy+zmtyESPCMJhjskcAIq -nFGkOvjXRZjjXokQ5vJ3Gd6oAE19BakAuull48sQCjZ4HULDugTa0/dw/qHEbKZMz6Mb547n7InGRyFC -v/hRS7IyznCzSdjybEX5fAXHs+agYeu7Es/2dvXgW/3cJ3i5qzb/dqt3W/dsfa+28izGF4K1+rwzRgVL -cS9li07jWMqHNs5bX9iI4mYLa9/ZaK6NOuNPJMsIXXzVjWoQj2x9P+w068fw0RuOZ27ji2RQvrxTWBkB -c85WsJQy6+/uColmn9g95vOUrXszttpFu3/Z33v752/2dvcP9t+921OY7glyDT6ieyRmnGSyh+5YLnWb -lNxxxDe7dynJrNz1lnLlbRBfdRIWbIcl+o0A2RNZSmQn6jkveHcXMo6lJJi/NpvCwZUN/fcqudm77cJL -OHj7rguvQBXs33YrJQe1kje33cp7QO7sIV/554Q0X+k7mcWVzIZLJVFUfZjDO11U+Bra0HxVe/7I6H34 -k6KzYWfwjdI5f9Wq5/Xr4GKoohHOkVz25iljXBO9q0dbipHC3inQKzZEvQheQdKwb5gUt0NSlifzFHEM -+v4OFn2TQIClflJA6rQDRaWX4FIcxOq7A++nV6PLD/+aXr5/r2//zAqU04yzz5s+RGw+j+BBvw1xpYog -IQLdpTiporhoxUBDBJg2tX9/fXbWhmGep2mA49UIkXSR0xKXqsH8tXtwx2dBf6ek3V70ZvO5MYdUkuI9 -Beh4d8G7/ZA8+0ZCK6emtl3JsYZeab3Ttm4uHu2Fuk6uKVG6A6Xj8VnzyIpOri9OfzgZjYdn4/FZ01By -h0qINBxJ2Al9ch8Xj3VhhqHl+Xo8uTyP4Wp0+cPp8ckIxlcnR6fvT49gdHJ0OTqGyb+uTsaeVpi6u2fl -Shhh8zThr3wDTTcobmxFcdTVesfeBrUDH50cn45Ojhry77zKLWk55s3GKN42rvC2CxaSUB2mPanV73ue -ZZ+gfAVRrFSZOeMqKQ5PnywLJyfnV9v5GED8LzNbmXk9Oqvz73p0psy3rX+zt98I8mZv30G9HzVeLtPF -LutpfPV++t316ZlasRJ9wqLc6NeaN0Ncij5MzBNjUgDTeZSqnfP1O5LBHYaPTNlwE2NEEHW1Vk/RHU5N -8+OLsfksHunIOFkhvvFw9aBT6si/RfpRCY7WffinTt3smPcwNZau8bMZ10cTOUWpeRzTOWIenc6UaIp0 -PKbokWSFNSkqJjPJjJgD49Z590kxT1ZpHyW2L6WW74loIrV/ZfHiVZYiaXCjJCH2LM69yWa4NdOPuSX+ -eKcim/8pMYOep0hKTPswhJQI6b8JatpbAGs8lWu5xCjZ78NwxfTrrfDiLp/PMQfO2OqFOb7TCWI6UixS -TInEq+LZ2WwOs6V+N0Ux6rM8R5/H5EdsxrVCn8kqX4EgP+IyGp18mBQM+8E8T6SIgYO3b83REcdCWU9l -1vNUkiwtM4G9sR+8fRt1PePgiWWDMTAK3cjjzz+D91nuUR80pN/5wl7s7CIJKUZCwgHgFOutpJrTaXu0 -gufvrBfFviKoNeRorWK98uOrwQCiqI5K1Q0gmnK0Ftm8QGesmdmd11ltS1zIhSdXxt6ZHZHM7PM7aOVT -eYd2au1g6URB+09qJoujVNWdJsHt91n22sycqFsgLldeuNRcmHE6d7Kqlg0RmvFY6OQc92IwIK93b5cC -rStIHVsNSRZvyVlbUO7/7gVvvhUNBhX4hrSq3V2z7Y6SpKBFscPS6J7lpJHU169XmdxUE9ZLQptnPISR -Mm089TQB6OTDpMQV27mJzSNaRfPuk88/tyDtPhofezPrQlo1r/oZ4TlR82r8eqMU1cxVJ841C2dHgxdz -42CCJRCi0BovxFEUB3h0SQuiUs2FmMryAlVZdFhhxffbBTlcfFVuVGa+NjlavZRznrVNe226H8VUpuAF -exv+41HbfIOtxv1oONxi1AlL8Nw0nTEq0UwqJZSWG7wdZnNYSvDpzD5f1YfvGEsxovrkBtNEP4ON9d1A -q2AIx8mug+8pUVU2vNhXCi6AeS8pcDzPBU5q3QuR4z6cWY17NHQvc5voPWVr8xK6hvNRi8qDZNAxdt9k -fFsxcbbUeEwax5qkSR+GFnPZ30yNWXeiIGaIJ029EeHeP9ven2dvvalutbdPt34VATcUF1rafCp1SBnF -UTcshpvoMLo9bEKhxlxBo4uaUZkqh67AV1DvhlVQ91WlcRd+/rmEDoErW9FFlTM9gwHsbQGzI9lW7WMy -x9oNDo2/QusOjZpzTCXfqCJDOeOlgD3Xu6hOjVqb1edvvKpi2dbfvtHq6Wg4DNVTpJtFMXhI4uCVOt9G -tbyL83TU3frT0o0C3G05rogh9VwKXwrMQUaKqTnAeCKFCkFJofq6Ibfd7uFO25L4AsI8wXo+cVp24ipa -n8iqIRlry47g+B+n5+5SW/Gw+V8P3n4DdxuJg1eq/3F63kG8eFZptszpJ2uMD96+Ld+sHLXetHDDR5w3 -DBleDUqk5ehH7lCZ90RKZrhDYgXrgYbnACM3xCKncM1Rpl/OZRwWKbvrdPVP7/l1SBnSJmtOUmyC0qEo -/fCCBx1C4XvWVTwiFFiu/4cZkrMUEN2s0SbWj8qqdvZd2OJ6o8vrE4gSuXk9W+LZJxspXjCJ+44wIuw1 -JKrjX67C1JwmbKaPA3FSfQW4B2OmM+qJDh02iia2psCJ+NTzEyW1JpraXopNHntOf3ALA3jxUbw4tOea -M6zUi6aE0FmaJxh6H4Vjj5tp/QkDTbs5Ke/QPE3jErP/Nrl3kmjwtBwlWlo7Gqgl11fX7Tzs/E8AAAD/ -/3My09H4ZQAA +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 `, }, } diff --git a/pkg/normalize/validate.go b/pkg/normalize/validate.go index 86b495529..0707d3e9b 100644 --- a/pkg/normalize/validate.go +++ b/pkg/normalize/validate.go @@ -392,11 +392,20 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) { errs = append(errs, fmt.Errorf("record named '%s' does not have correct FQDN for domain '%s'. FQDN: %s", r.Name, d.Name, r.NameFQDN)) } } + // Verify AutoDNSSEC is valid. + errs = append(errs, checkAutoDNSSEC(d)...) } return errs } +func checkAutoDNSSEC(dc *models.DomainConfig) (errs []error) { + if dc.AutoDNSSEC != "" && dc.AutoDNSSEC != "on" && dc.AutoDNSSEC != "off" { + errs = append(errs, fmt.Errorf("Domain %q AutoDNSSEC=%q is invalid (expecting \"\", \"off\", or \"on\")", dc.Name, dc.AutoDNSSEC)) + } + return +} + func checkCNAMEs(dc *models.DomainConfig) (errs []error) { cnames := map[string]bool{} for _, r := range dc.Records { @@ -510,7 +519,7 @@ func checkProviderCapabilities(dc *models.DomainConfig) error { hasAny := false switch ty.rType { case "AUTODNSSEC": - if dc.AutoDNSSEC { + if dc.AutoDNSSEC != "" { hasAny = true } default: diff --git a/providers/axfrddns/axfrddnsProvider.go b/providers/axfrddns/axfrddnsProvider.go index 51546d60b..ecdbc2884 100644 --- a/providers/axfrddns/axfrddnsProvider.go +++ b/providers/axfrddns/axfrddnsProvider.go @@ -279,10 +279,12 @@ func (c *AxfrDdns) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Corr } } - if dc.AutoDNSSEC && !hasDnssecRecords { - fmt.Printf("Warning: AUTODNSSEC is set, but no DNSKEY or RRSIG record was found in the AXFR answer!\n") - } else if !dc.AutoDNSSEC && hasDnssecRecords { - fmt.Printf("Warning: AUTODNSSEC is not set, but DNSKEY or RRSIG records were found in the AXFR answer!\n") + // TODO(tlim): This check should be done on all providers. Move to the global validation code. + if dc.AutoDNSSEC == "on" && !hasDnssecRecords { + fmt.Printf("Warning: AUTODNSSEC is enabled, but no DNSKEY or RRSIG record was found in the AXFR answer!\n") + } + if dc.AutoDNSSEC == "off" && hasDnssecRecords { + fmt.Printf("Warning: AUTODNSSEC is disabled, but DNSKEY or RRSIG records were found in the AXFR answer!\n") } // Normalize diff --git a/providers/bind/bindProvider.go b/providers/bind/bindProvider.go index dbd23e1b9..4cdab9932 100644 --- a/providers/bind/bindProvider.go +++ b/providers/bind/bindProvider.go @@ -177,7 +177,11 @@ func (c *Bind) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correcti comments = append(comments, fmt.Sprintf("generated with dnscontrol %s", time.Now().Format(time.RFC3339)), ) - if dc.AutoDNSSEC { + if dc.AutoDNSSEC == "on" { + // This does nothing but reminds the user to add the correct + // auto-dnssecc zone statement to named.conf. + // While it is a no-op, it is useful for situations where a zone + // has multiple providers. comments = append(comments, "Automatic DNSSEC signing requested") } diff --git a/providers/dnsimple/dnsimpleProvider.go b/providers/dnsimple/dnsimpleProvider.go index 190d2594a..e972e48d8 100644 --- a/providers/dnsimple/dnsimpleProvider.go +++ b/providers/dnsimple/dnsimpleProvider.go @@ -228,7 +228,7 @@ func (c *DnsimpleAPI) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.C return nil, err } - if enabled && !dc.AutoDNSSEC { + if enabled && dc.AutoDNSSEC == "off" { return []*models.Correction{ { Msg: "Disable DNSSEC", @@ -237,7 +237,7 @@ func (c *DnsimpleAPI) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.C }, nil } - if !enabled && dc.AutoDNSSEC { + if !enabled && dc.AutoDNSSEC == "on" { return []*models.Correction{ { Msg: "Enable DNSSEC", diff --git a/providers/powerdns/dnssec.go b/providers/powerdns/dnssec.go index bd1a41874..d3c5ff7f6 100644 --- a/providers/powerdns/dnssec.go +++ b/providers/powerdns/dnssec.go @@ -2,6 +2,7 @@ package powerdns import ( "context" + "github.com/StackExchange/dnscontrol/v3/models" "github.com/mittwald/go-powerdns/apis/cryptokeys" ) @@ -28,7 +29,7 @@ func (api *PowerDNS) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.Co } // dnssec is enabled, we want it to be disabled - if hasEnabledKey && !dc.AutoDNSSEC { + if hasEnabledKey && dc.AutoDNSSEC == "off" { return []*models.Correction{ { Msg: "Disable DNSSEC", @@ -38,7 +39,7 @@ func (api *PowerDNS) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.Co } // dnssec is disabled, we want it to be enabled - if !hasEnabledKey && dc.AutoDNSSEC { + if !hasEnabledKey && dc.AutoDNSSEC == "on" { return []*models.Correction{ { Msg: "Enable DNSSEC",