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