1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

Add AUTODNSSEC, implement for DNSimple (#640)

* Add AUTODNSSEC, implement for DNSimple

There are two models for DNSSEC in DNS management: either dnscontrol
manages all the DNSSEC records and has to be invoked regularly for
re-signing, or the provider manages DNSSEC automatically and dnscontrol
is not involved beyond saying "yeah, do that".

This implements the latter, as a model, and for one provider.

Potentially we could tune/configure options for DNSSEC such as
algorithm, but DNSimple don't expose that API so I haven't implemented
it.

This minimal model should be something which maps into other providers
cleanly.

* Fix missing CanAutoDNSSEC on provider

* Validation fix for master broken

This is broken in master and causing Travis in my branch to fail.  The
validation tool runs with `gofmt -s` to require "simplify", and so
rejects an ignored second bound variable to range iteration.

* Correct wire in the AUTODNSSEC validation step
This commit is contained in:
Phil Pennock
2020-02-22 07:09:31 -05:00
committed by GitHub
parent b360ddd1e9
commit 9b239f41a3
13 changed files with 292 additions and 103 deletions

View File

@@ -34,6 +34,10 @@ const (
// CanUseTXTMulti indicates the provider can handle TXT records with multiple strings
CanUseTXTMulti
// CanAutoDNSSEC indicates that the provider can automatically handle DNSSEC,
// so folks can ask for that.
CanAutoDNSSEC
// CantUseNOPURGE indicates NO_PURGE is broken for this provider. To make it
// work would require complex emulation of an incremental update mechanism,
// so it is easier to simply mark this feature as not working for this

View File

@@ -23,6 +23,7 @@ var features = providers.DocumentationNotes{
providers.CanUseSSHFP: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseTXTMulti: providers.Can(),
providers.CanAutoDNSSEC: providers.Can(),
providers.CanUseTLSA: providers.Cannot(),
providers.DocCreateDomains: providers.Cannot(),
providers.DocDualHost: providers.Cannot("DNSimple does not allow sufficient control over the apex NS records"),
@@ -85,6 +86,8 @@ func (client *DnsimpleApi) GetZoneRecords(domain string) (models.Records, error)
}
rec.SetLabel(r.Name, domain)
switch rtype := r.Type; rtype {
case "DNSKEY", "CDNSKEY", "CDS":
continue
case "ALIAS", "URL":
rec.Type = r.Type
rec.SetTarget(r.Content)
@@ -119,6 +122,12 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
return nil, err
}
dnssecFixes, err := c.getDNSSECCorrections(dc)
if err != nil {
return nil, err
}
corrections = append(corrections, dnssecFixes...)
records, err := c.GetZoneRecords(dc.Name)
if err != nil {
return nil, err
@@ -201,6 +210,34 @@ func (c *DnsimpleApi) GetRegistrarCorrections(dc *models.DomainConfig) ([]*model
return corrections, nil
}
// getDNSSECCorrections returns corrections that update a domain's DNSSEC state.
func (c *DnsimpleApi) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
enabled, err := c.getDnssec(dc.Name)
if err != nil {
return nil, err
}
if enabled && !dc.AutoDNSSEC {
return []*models.Correction{
{
Msg: "Disable DNSSEC",
F: func() error { _, err := c.disableDnssec(dc.Name); return err },
},
}, nil
}
if !enabled && dc.AutoDNSSEC {
return []*models.Correction{
{
Msg: "Enable DNSSEC",
F: func() error { _, err := c.enableDnssec(dc.Name); return err },
},
}, nil
}
return []*models.Correction{}, nil
}
// DNSimple calls
func (c *DnsimpleApi) getClient() *dnsimpleapi.Client {
@@ -258,6 +295,69 @@ func (c *DnsimpleApi) getRecords(domainName string) ([]dnsimpleapi.ZoneRecord, e
return recs, nil
}
func (c *DnsimpleApi) getDnssec(domainName string) (bool, error) {
var (
client *dnsimpleapi.Client
accountID string
err error
)
client = c.getClient()
if accountID, err = c.getAccountID(); err != nil {
return false, err
}
dnssecResponse, err := client.Domains.GetDnssec(accountID, domainName)
if err != nil {
return false, err
}
if dnssecResponse.Data == nil {
return false, nil
}
return dnssecResponse.Data.Enabled, nil
}
func (c *DnsimpleApi) enableDnssec(domainName string) (bool, error) {
var (
client *dnsimpleapi.Client
accountID string
err error
)
client = c.getClient()
if accountID, err = c.getAccountID(); err != nil {
return false, err
}
dnssecResponse, err := client.Domains.EnableDnssec(accountID, domainName)
if err != nil {
return false, err
}
if dnssecResponse.Data == nil {
return false, nil
}
return dnssecResponse.Data.Enabled, nil
}
func (c *DnsimpleApi) disableDnssec(domainName string) (bool, error) {
var (
client *dnsimpleapi.Client
accountID string
err error
)
client = c.getClient()
if accountID, err = c.getAccountID(); err != nil {
return false, err
}
dnssecResponse, err := client.Domains.DisableDnssec(accountID, domainName)
if err != nil {
return false, err
}
if dnssecResponse.Data == nil {
return false, nil
}
return dnssecResponse.Data.Enabled, nil
}
// Returns the name server names that should be used. If the domain is registered
// then this method will return the delegation name servers. If this domain
// is hosted only, then it will return the default DNSimple name servers.

View File

@@ -108,7 +108,7 @@ func (g *gcloud) loadZoneInfo() error {
// ListZones returns the list of zones (domains) in this account.
func (g *gcloud) ListZones() ([]string, error) {
var zones []string
for i, _ := range g.zones {
for i := range g.zones {
zones = append(zones, strings.TrimSuffix(i, "."))
}
return zones, nil