1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00
Files
stackexchange-dnscontrol/providers/namedotcom/nameservers.go
Tom Limoncelli 9812ecd9ff BIND: Improve SOA serial number handling (#651)
* github.com/miekg/dns
* Greatly simplify the logic for handling serial numbers. Related code was all over the place. Now it is abstracted into one testable method makeSoa. This simplifies code in many other places.
* Update docs/_providers/bind.md: Edit old text. Add SOA description.
* SOA records are now treated like any other record internally. You still can't specify them in dnsconfig.js, but that's by design.
* The URL for issue 491 was wrong in many places
* BIND: Clarify GENERATE_ZONEFILE message
2020-02-23 13:58:49 -05:00

87 lines
2.5 KiB
Go

package namedotcom
import (
"fmt"
"regexp"
"sort"
"strings"
"github.com/StackExchange/dnscontrol/v2/models"
"github.com/namedotcom/go/namecom"
)
var nsRegex = regexp.MustCompile(`ns([1-4])[a-z]{3}\.name\.com`)
// GetNameservers gets the nameservers set on a domain.
func (n *NameCom) GetNameservers(domain string) ([]*models.Nameserver, error) {
// This is an interesting edge case. Name.com expects you to SET the nameservers to ns[1-4].name.com,
// but it will internally set it to ns1xyz.name.com, where xyz is a uniqueish 3 letters.
// In order to avoid endless loops, we will use the unique nameservers if present, or else the generic ones if not.
nss, err := n.getNameserversRaw(domain)
if err != nil {
return nil, err
}
toUse := []string{"ns1.name.com", "ns2.name.com", "ns3.name.com", "ns4.name.com"}
for _, ns := range nss {
if matches := nsRegex.FindStringSubmatch(ns); len(matches) == 2 && len(matches[1]) == 1 {
idx := matches[1][0] - '1' // regex ensures proper range
toUse[idx] = matches[0]
}
}
return models.StringsToNameservers(toUse), nil
}
func (n *NameCom) getNameserversRaw(domain string) ([]string, error) {
request := &namecom.GetDomainRequest{
DomainName: domain,
}
response, err := n.client.GetDomain(request)
if err != nil {
return nil, err
}
sort.Strings(response.Nameservers)
return response.Nameservers, nil
}
// GetRegistrarCorrections gathers corrections that would being n to match dc.
func (n *NameCom) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
nss, err := n.getNameserversRaw(dc.Name)
if err != nil {
return nil, err
}
foundNameservers := strings.Join(nss, ",")
expected := []string{}
for _, ns := range dc.Nameservers {
expected = append(expected, ns.Name)
// FIXME(tlim): This should store a FQDN with no trailing ".".
// See pkg/nameservers/nameservers.go for details.
// Bug https://github.com/StackExchange/dnscontrol/issues/491
}
sort.Strings(expected)
expectedNameservers := strings.Join(expected, ",")
if foundNameservers != expectedNameservers {
return []*models.Correction{
{
Msg: fmt.Sprintf("Update nameservers %s -> %s", foundNameservers, expectedNameservers),
F: n.updateNameservers(expected, dc.Name),
},
}, nil
}
return nil, nil
}
func (n *NameCom) updateNameservers(ns []string, domain string) func() error {
return func() error {
request := &namecom.SetNameserversRequest{
DomainName: domain,
Nameservers: ns,
}
_, err := n.client.SetNameservers(request)
return err
}
}