diff --git a/docs/_includes/matrix.html b/docs/_includes/matrix.html
index c815e095e..1d359bbcb 100644
--- a/docs/_includes/matrix.html
+++ b/docs/_includes/matrix.html
@@ -922,8 +922,8 @@
|
-
-
+ |
+
|
diff --git a/docs/writing-providers.md b/docs/writing-providers.md
index fddb7052a..8a357ea94 100644
--- a/docs/writing-providers.md
+++ b/docs/writing-providers.md
@@ -92,14 +92,14 @@ Pick a similar provider as your base. Providers basically fall
into three general categories:
* **zone:** The API requires you to upload the entire zone every time. (BIND).
-* **incremental-record:** The API lets you add/change/delete individual DNS records. (ACTIVEDIR, CLOUDFLARE, NAMEDOTCOM, GCLOUD, ROUTE53)
+* **incremental-record:** The API lets you add/change/delete individual DNS records. (ACTIVEDIR, CLOUDFLARE, DNSIMPLE, NAMEDOTCOM, GCLOUD, ROUTE53)
* **incremental-label:** Like incremental-record, but if there are
multiple records on a label (for example, example www.example.com
has A and MX records), you have to replace all the records at that
label. (GANDI_V5)
* **incremental-label-type:** Like incremental-record, but updates to any records at a label have to be done by type. For example, if a label (www.example.com) has many A and MX records, even the smallest change to one of the A records requires replacing all the A records. Any changes to the MX records requires replacing all the MX records. If an A record is converted to a CNAME, one must remove all the A records in one call, and add the CNAME record with another call. This is deceptively difficult to get right; if you have the voice between incremental-label-type and incremental-label, pick incremental-label.
-TODO: Categorize DNSIMPLE, NAMECHEAP
+TODO: Categorize NAMECHEAP
All providers use the "diff" module to detect differences. It takes
two zones and returns records that are unchanged, created, deleted,
diff --git a/go.mod b/go.mod
index 1f3349d51..d8a149137 100644
--- a/go.mod
+++ b/go.mod
@@ -16,7 +16,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible // indirect
github.com/digitalocean/godo v1.30.0
- github.com/dnsimple/dnsimple-go v0.20.1-0.20181001130357-234ec949d37c
+ github.com/dnsimple/dnsimple-go v0.31.0
github.com/exoscale/egoscale v0.10.5
github.com/go-acme/lego v2.7.2+incompatible
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe
diff --git a/go.sum b/go.sum
index 81ebf5819..c6d7a6ef8 100644
--- a/go.sum
+++ b/go.sum
@@ -35,7 +35,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DisposaBoy/JsonConfigReader v0.0.0-20171218180944-5ea4d0ddac55 h1:jbGlDKdzAZ92NzK65hUP98ri0/r50vVVvmZsFP/nIqo=
github.com/DisposaBoy/JsonConfigReader v0.0.0-20171218180944-5ea4d0ddac55/go.mod h1:GCzqZQHydohgVLSIqRKZeTt8IGb1Y4NaFfim3H40uUI=
-github.com/StackExchange/dnscontrol v0.2.8 h1:7jviqDH9cIqRSRpH0UxgmpT7a8CwEhs9mLHBhoYhXo8=
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d h1:WtAMR0fPCOfK7TPGZ8ZpLLY18HRvL7XJ3xcs0wnREgo=
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d/go.mod h1:WML6KOYjeU8N6YyusMjj2qRvaPNUEvrQvaxuFcMRFJY=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
@@ -66,8 +65,8 @@ github.com/digitalocean/godo v1.30.0 h1:4Zb+xBlKMXKg772eyQk6px3sk9RhWj/CR75tQ375
github.com/digitalocean/godo v1.30.0/go.mod h1:iJnN9rVu6K5LioLxLimlq0uRI+y/eAQjROUmeU/r0hY=
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.20.1-0.20181001130357-234ec949d37c h1:Llo2tjvv1SspjFXiM8NJyxirMPTZvNPk3lLCPf61COo=
-github.com/dnsimple/dnsimple-go v0.20.1-0.20181001130357-234ec949d37c/go.mod h1:0FYu4qVNv/UcfZPNwa9zi68IkggJu3TIwM54D7rhmI4=
+github.com/dnsimple/dnsimple-go v0.31.0 h1:I1T+AxBQfhovyyfGSJ4CSUeH0iQejLArsUlhSQKw8WI=
+github.com/dnsimple/dnsimple-go v0.31.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/exoscale/egoscale v0.10.5 h1:pV1gDCsXPi9vfbZ1TIMz7mNGEDMiVHlQlbcJp1qxIaU=
diff --git a/providers/dnsimple/dnsimpleProvider.go b/providers/dnsimple/dnsimpleProvider.go
index 272e0536f..aaa458649 100644
--- a/providers/dnsimple/dnsimpleProvider.go
+++ b/providers/dnsimple/dnsimpleProvider.go
@@ -25,7 +25,7 @@ var features = providers.DocumentationNotes{
providers.DocCreateDomains: providers.Cannot(),
providers.DocDualHost: providers.Cannot("DNSimple does not allow sufficient control over the apex NS records"),
providers.DocOfficiallySupported: providers.Cannot(),
- providers.CanGetZones: providers.Unimplemented(),
+ providers.CanGetZones: providers.Can(),
}
func init() {
@@ -56,24 +56,14 @@ func (c *DnsimpleApi) GetNameservers(domainName string) ([]*models.Nameserver, e
// GetZoneRecords gets the records of a zone and returns them in RecordConfig format.
func (client *DnsimpleApi) GetZoneRecords(domain string) (models.Records, error) {
- return nil, fmt.Errorf("not implemented")
- // This enables the get-zones subcommand.
- // Implement this by extracting the code from GetDomainCorrections into
- // a single function. For most providers this should be relatively easy.
-}
-
-// GetDomainCorrections returns corrections that update a domain.
-func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
- corrections := []*models.Correction{}
- dc.Punycode()
- records, err := c.getRecords(dc.Name)
+ records, err := client.getRecords(domain)
if err != nil {
return nil, err
}
- var actual []*models.RecordConfig
+ var cleanedRecords models.Records
for _, r := range records {
- if r.Type == "SOA" || r.Type == "NS" {
+ if r.Type == "SOA" {
continue
}
if r.Name == "" {
@@ -82,8 +72,8 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
if r.Type == "CNAME" || r.Type == "MX" || r.Type == "ALIAS" {
r.Content += "."
}
- // dnsimple adds these odd txt records that mirror the alias records.
- // they seem to manage them on deletes and things, so we'll just pretend they don't exist
+ // DNSimple adds TXT records that mirror the alias records.
+ // They manage them on ALIAS updates, so pretend they don't exist
if r.Type == "TXT" && strings.HasPrefix(r.Content, "ALIAS for ") {
continue
}
@@ -91,7 +81,7 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
TTL: uint32(r.TTL),
Original: r,
}
- rec.SetLabel(r.Name, dc.Name)
+ rec.SetLabel(r.Name, domain)
switch rtype := r.Type; rtype {
case "ALIAS", "URL":
rec.Type = r.Type
@@ -109,12 +99,29 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
}
default:
- if err := rec.PopulateFromString(r.Type, r.Content, dc.Name); err != nil {
+ if err := rec.PopulateFromString(r.Type, r.Content, domain); err != nil {
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
}
}
- actual = append(actual, rec)
+ cleanedRecords = append(cleanedRecords, rec)
}
+
+ return cleanedRecords, nil
+}
+
+// GetDomainCorrections returns corrections that update a domain.
+func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
+ corrections := []*models.Correction{}
+ err := dc.Punycode()
+ if err != nil {
+ return nil, err
+ }
+
+ records, err := c.GetZoneRecords(dc.Name)
+ if err != nil {
+ return nil, err
+ }
+ actual := removeNS(records)
removeOtherNS(dc)
// Normalize
@@ -151,6 +158,16 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
return corrections, nil
}
+func removeNS(records models.Records) models.Records {
+ var noNameServers models.Records
+ for _, r := range records {
+ if r.Type != "NS" {
+ noNameServers = append(noNameServers, r)
+ }
+ }
+ return noNameServers
+}
+
// GetRegistrarCorrections returns corrections that update a domain's registrar.
func (c *DnsimpleApi) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
corrections := []*models.Correction{}
@@ -360,6 +377,34 @@ func (c *DnsimpleApi) updateRecordFunc(old *dnsimpleapi.ZoneRecord, rc *models.R
}
}
+// Returns all the zones in an account
+func (c *DnsimpleApi) ListZones() ([]string, error) {
+ client := c.getClient()
+ accountID, err := c.getAccountID()
+ if err != nil {
+ return nil, err
+ }
+
+ var zones []string
+ opts := &dnsimpleapi.ZoneListOptions{}
+ opts.Page = 1
+ for {
+ zonesResponse, err := client.Zones.ListZones(accountID, opts)
+ if err != nil {
+ return nil, err
+ }
+ for _, zone := range zonesResponse.Data {
+ zones = append(zones, zone.Name)
+ }
+ pg := zonesResponse.Pagination
+ if pg.CurrentPage == pg.TotalPages {
+ break
+ }
+ opts.Page++
+ }
+ return zones, nil
+}
+
// constructors
func newReg(conf map[string]string) (providers.Registrar, error) {
diff --git a/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt b/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt
index 3c2f300e1..0a39bd177 100644
--- a/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt
+++ b/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2014-2018 Aetrion LLC dba DNSimple
+Copyright (c) 2014-2020 DNSimple Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go
index 0c15b48e2..20878ef15 100644
--- a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go
+++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go
@@ -23,7 +23,7 @@ const (
// This is a pro-forma convention given that Go dependencies
// tends to be fetched directly from the repo.
// It is also used in the user-agent identify the client.
- Version = "0.20.0"
+ Version = "0.31.0"
// defaultBaseURL to the DNSimple production API.
defaultBaseURL = "https://api.dnsimple.com"
@@ -146,7 +146,7 @@ func formatUserAgent(customUserAgent string) string {
return defaultUserAgent
}
- return fmt.Sprintf("%s %s", defaultUserAgent, customUserAgent)
+ return fmt.Sprintf("%s %s", customUserAgent, defaultUserAgent)
}
func versioned(path string) string {
diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go
index 6cd8fd7fb..8ca687144 100644
--- a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go
+++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go
@@ -129,18 +129,10 @@ func (s *DomainsService) DeleteDomain(accountID string, domainIdentifier string)
return domainResponse, nil
}
-// ResetDomainToken resets the domain token.
+// DEPRECATED
//
// See https://developer.dnsimple.com/v2/domains/#reset-token
func (s *DomainsService) ResetDomainToken(accountID string, domainIdentifier string) (*domainResponse, error) {
- path := versioned(domainPath(accountID, domainIdentifier) + "/token")
- domainResponse := &domainResponse{}
-
- resp, err := s.client.post(path, nil, domainResponse)
- if err != nil {
- return nil, err
- }
-
- domainResponse.HttpResponse = resp
- return domainResponse, nil
+ // noop
+ return &domainResponse{}, nil
}
diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go
index 625bbb2dc..1013bd607 100644
--- a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go
+++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go
@@ -62,7 +62,7 @@ type DomainPremiumPriceOptions struct {
Action string `url:"action,omitempty"`
}
-// Gets the premium price for a domain.
+// GetDomainPremiumPrice gets the premium price for a domain.
//
// You must specify an action to get the price for. Valid actions are:
// - registration
diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go
index edf47b12a..730fd8a44 100644
--- a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go
+++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go
@@ -14,12 +14,30 @@ type WhoisPrivacy struct {
UpdatedAt string `json:"updated_at,omitempty"`
}
+// WhoisPrivacyRenewal represents a whois privacy renewal in DNSimple.
+type WhoisPrivacyRenewal struct {
+ ID int64 `json:"id,omitempty"`
+ DomainID int64 `json:"domain_id,omitempty"`
+ WhoisPrivacyID int64 `json:"whois_privacy_id,omitempty"`
+ State string `json:"string,omitempty"`
+ Enabled bool `json:"enabled,omitempty"`
+ ExpiresOn string `json:"expires_on,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+}
+
// whoisPrivacyResponse represents a response from an API method that returns a WhoisPrivacy struct.
type whoisPrivacyResponse struct {
Response
Data *WhoisPrivacy `json:"data"`
}
+// whoisPrivacyRenewalResponse represents a response from an API method that returns a WhoisPrivacyRenewal struct.
+type whoisPrivacyRenewalResponse struct {
+ Response
+ Data *WhoisPrivacyRenewal `json:"data"`
+}
+
// GetWhoisPrivacy gets the whois privacy for the domain.
//
// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#get
@@ -52,7 +70,7 @@ func (s *RegistrarService) EnableWhoisPrivacy(accountID string, domainName strin
return privacyResponse, nil
}
-// DisablePrivacy disables the whois privacy for the domain.
+// DisableWhoisPrivacy disables the whois privacy for the domain.
//
// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#enable
func (s *RegistrarService) DisableWhoisPrivacy(accountID string, domainName string) (*whoisPrivacyResponse, error) {
@@ -67,3 +85,19 @@ func (s *RegistrarService) DisableWhoisPrivacy(accountID string, domainName stri
privacyResponse.HttpResponse = resp
return privacyResponse, nil
}
+
+// RenewWhoisPrivacy renews the whois privacy for the domain.
+//
+// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#renew
+func (s *RegistrarService) RenewWhoisPrivacy(accountID string, domainName string) (*whoisPrivacyRenewalResponse, error) {
+ path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/whois_privacy/renewals", accountID, domainName))
+ privacyRenewalResponse := &whoisPrivacyRenewalResponse{}
+
+ resp, err := s.client.post(path, nil, privacyRenewalResponse)
+ if err != nil {
+ return nil, err
+ }
+
+ privacyRenewalResponse.HttpResponse = resp
+ return privacyRenewalResponse, nil
+}
diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go
index ee0da04fe..9c5c250dd 100644
--- a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go
+++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go
@@ -100,7 +100,7 @@ func (s *TldsService) GetTld(tld string) (*tldResponse, error) {
return tldResponse, nil
}
-// GetTld fetches the extended attributes of a TLD.
+// GetTldExtendedAttributes fetches the extended attributes of a TLD.
//
// See https://developer.dnsimple.com/v2/tlds/#get
func (s *TldsService) GetTldExtendedAttributes(tld string) (*tldExtendedAttributesResponse, error) {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 1aecb8216..c97ae15f4 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -77,7 +77,7 @@ github.com/dgrijalva/jwt-go
github.com/digitalocean/godo
# github.com/dimchansky/utfbom v1.1.0
github.com/dimchansky/utfbom
-# github.com/dnsimple/dnsimple-go v0.20.1-0.20181001130357-234ec949d37c
+# github.com/dnsimple/dnsimple-go v0.31.0
github.com/dnsimple/dnsimple-go/dnsimple
# github.com/exoscale/egoscale v0.10.5
github.com/exoscale/egoscale
|