github.com/StackExchange/DNSControl@v0.2.8/providers/opensrs/opensrsProvider.go (about) 1 package opensrs 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "sort" 8 "strings" 9 10 "github.com/StackExchange/dnscontrol/models" 11 "github.com/StackExchange/dnscontrol/providers" 12 13 opensrs "github.com/philhug/opensrs-go/opensrs" 14 ) 15 16 var docNotes = providers.DocumentationNotes{ 17 providers.DocCreateDomains: providers.Cannot(), 18 providers.DocOfficiallySupported: providers.Cannot(), 19 providers.CanUseTLSA: providers.Cannot(), 20 } 21 22 func init() { 23 providers.RegisterRegistrarType("OPENSRS", newReg) 24 } 25 26 var defaultNameServerNames = []string{ 27 "ns1.systemdns.com", 28 "ns2.systemdns.com", 29 "ns3.systemdns.com", 30 } 31 32 type OpenSRSApi struct { 33 UserName string // reseller user name 34 ApiKey string // API Key 35 36 BaseURL string // An alternate base URI 37 client *opensrs.Client // Client 38 } 39 40 func (c *OpenSRSApi) GetNameservers(domainName string) ([]*models.Nameserver, error) { 41 return models.StringsToNameservers(defaultNameServerNames), nil 42 } 43 44 func (c *OpenSRSApi) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { 45 corrections := []*models.Correction{} 46 47 nameServers, err := c.getNameservers(dc.Name) 48 if err != nil { 49 return nil, err 50 } 51 52 sort.Strings(nameServers) 53 actual := strings.Join(nameServers, ",") 54 55 expectedSet := []string{} 56 for _, ns := range dc.Nameservers { 57 expectedSet = append(expectedSet, ns.Name) 58 } 59 sort.Strings(expectedSet) 60 expected := strings.Join(expectedSet, ",") 61 62 if actual != expected { 63 return []*models.Correction{ 64 { 65 Msg: fmt.Sprintf("Update nameservers %s -> %s", actual, expected), 66 F: c.updateNameserversFunc(expectedSet, dc.Name), 67 }, 68 }, nil 69 } 70 71 return corrections, nil 72 } 73 74 // OpenSRS calls 75 76 func (c *OpenSRSApi) getClient() *opensrs.Client { 77 return c.client 78 } 79 80 // Returns the name server names that should be used. If the domain is registered 81 // then this method will return the delegation name servers. If this domain 82 // is hosted only, then it will return the default OpenSRS name servers. 83 func (c *OpenSRSApi) getNameservers(domainName string) ([]string, error) { 84 client := c.getClient() 85 86 status, err := client.Domains.GetDomain(domainName, "status", 1) 87 if err != nil { 88 return nil, err 89 } 90 91 if status.Attributes.LockState == "0" { 92 dom, err := client.Domains.GetDomain(domainName, "nameservers", 1) 93 if err != nil { 94 return nil, err 95 } 96 return dom.Attributes.NameserverList.ToString(), nil 97 } else { 98 return nil, errors.New("Domain is locked") 99 } 100 } 101 102 // Returns a function that can be invoked to change the delegation of the domain to the given name server names. 103 func (c *OpenSRSApi) updateNameserversFunc(nameServerNames []string, domainName string) func() error { 104 return func() error { 105 client := c.getClient() 106 107 _, err := client.Domains.UpdateDomainNameservers(domainName, nameServerNames) 108 if err != nil { 109 return err 110 } 111 return nil 112 } 113 } 114 115 // constructors 116 117 func newReg(conf map[string]string) (providers.Registrar, error) { 118 return newProvider(conf, nil) 119 } 120 121 func newProvider(m map[string]string, metadata json.RawMessage) (*OpenSRSApi, error) { 122 api := &OpenSRSApi{} 123 api.ApiKey = m["apikey"] 124 125 if api.ApiKey == "" { 126 return nil, fmt.Errorf("OpenSRS apikey must be provided.") 127 } 128 129 api.UserName = m["username"] 130 if api.UserName == "" { 131 return nil, fmt.Errorf("OpenSRS username key must be provided.") 132 } 133 134 if m["baseurl"] != "" { 135 api.BaseURL = m["baseurl"] 136 } 137 138 api.client = opensrs.NewClient(opensrs.NewApiKeyMD5Credentials(api.UserName, api.ApiKey)) 139 if api.BaseURL != "" { 140 api.client.BaseURL = api.BaseURL 141 } 142 143 return api, nil 144 }