github.com/StackExchange/DNSControl@v0.2.8/providers/namedotcom/nameservers.go (about)

     1  package namedotcom
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/StackExchange/dnscontrol/models"
    10  	"github.com/namedotcom/go/namecom"
    11  )
    12  
    13  var nsRegex = regexp.MustCompile(`ns([1-4])[a-z]{3}\.name\.com`)
    14  
    15  // GetNameservers gets the nameservers set on a domain.
    16  func (n *NameCom) GetNameservers(domain string) ([]*models.Nameserver, error) {
    17  	// This is an interesting edge case. Name.com expects you to SET the nameservers to ns[1-4].name.com,
    18  	// but it will internally set it to ns1xyz.name.com, where xyz is a uniqueish 3 letters.
    19  	// In order to avoid endless loops, we will use the unique nameservers if present, or else the generic ones if not.
    20  	nss, err := n.getNameserversRaw(domain)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  	toUse := []string{"ns1.name.com", "ns2.name.com", "ns3.name.com", "ns4.name.com"}
    25  	for _, ns := range nss {
    26  		if matches := nsRegex.FindStringSubmatch(ns); len(matches) == 2 && len(matches[1]) == 1 {
    27  			idx := matches[1][0] - '1' // regex ensures proper range
    28  			toUse[idx] = matches[0]
    29  		}
    30  	}
    31  	return models.StringsToNameservers(toUse), nil
    32  }
    33  
    34  func (n *NameCom) getNameserversRaw(domain string) ([]string, error) {
    35  	request := &namecom.GetDomainRequest{
    36  		DomainName: domain,
    37  	}
    38  
    39  	response, err := n.client.GetDomain(request)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  
    44  	sort.Strings(response.Nameservers)
    45  	return response.Nameservers, nil
    46  }
    47  
    48  // GetRegistrarCorrections gathers corrections that would being n to match dc.
    49  func (n *NameCom) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
    50  	nss, err := n.getNameserversRaw(dc.Name)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	foundNameservers := strings.Join(nss, ",")
    55  	expected := []string{}
    56  	for _, ns := range dc.Nameservers {
    57  		name := strings.TrimRight(ns.Name, ".")
    58  		expected = append(expected, name)
    59  	}
    60  	sort.Strings(expected)
    61  	expectedNameservers := strings.Join(expected, ",")
    62  
    63  	if foundNameservers != expectedNameservers {
    64  		return []*models.Correction{
    65  			{
    66  				Msg: fmt.Sprintf("Update nameservers %s -> %s", foundNameservers, expectedNameservers),
    67  				F:   n.updateNameservers(expected, dc.Name),
    68  			},
    69  		}, nil
    70  	}
    71  	return nil, nil
    72  }
    73  
    74  func (n *NameCom) updateNameservers(ns []string, domain string) func() error {
    75  	return func() error {
    76  		request := &namecom.SetNameserversRequest{
    77  			DomainName:  domain,
    78  			Nameservers: ns,
    79  		}
    80  
    81  		_, err := n.client.SetNameservers(request)
    82  		return err
    83  	}
    84  }