github.com/pmoroney/dnscontrol@v0.2.4-0.20171024134423-fad98f73f44a/providers/namedotcom/namedotcomProvider.go (about) 1 //Package namedotcom implements a registrar that uses the name.com api to set name servers. It will self register it's providers when imported. 2 package namedotcom 3 4 import ( 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io/ioutil" 9 "net/http" 10 11 "github.com/StackExchange/dnscontrol/providers" 12 ) 13 14 const defaultApiBase = "https://api.name.com/api" 15 16 type nameDotCom struct { 17 APIUrl string `json:"apiurl"` 18 APIUser string `json:"apiuser"` 19 APIKey string `json:"apikey"` 20 } 21 22 var docNotes = providers.DocumentationNotes{ 23 providers.DocDualHost: providers.Cannot("Apex NS records not editable"), 24 providers.DocCreateDomains: providers.Cannot("New domains require registration"), 25 providers.DocOfficiallySupported: providers.Can(), 26 providers.CanUsePTR: providers.Cannot("PTR records are not supported (See Link)", "https://www.name.com/support/articles/205188508-Reverse-DNS-records"), 27 } 28 29 func newReg(conf map[string]string) (providers.Registrar, error) { 30 return newProvider(conf) 31 } 32 33 func newDsp(conf map[string]string, meta json.RawMessage) (providers.DNSServiceProvider, error) { 34 return newProvider(conf) 35 } 36 37 func newProvider(conf map[string]string) (*nameDotCom, error) { 38 api := &nameDotCom{} 39 api.APIUser, api.APIKey, api.APIUrl = conf["apiuser"], conf["apikey"], conf["apiurl"] 40 if api.APIKey == "" || api.APIUser == "" { 41 return nil, fmt.Errorf("Name.com apikey and apiuser must be provided.") 42 } 43 if api.APIUrl == "" { 44 api.APIUrl = defaultApiBase 45 } 46 return api, nil 47 } 48 49 func init() { 50 providers.RegisterRegistrarType("NAMEDOTCOM", newReg) 51 providers.RegisterDomainServiceProviderType("NAMEDOTCOM", newDsp, providers.CanUseAlias, providers.CanUseSRV, docNotes) 52 } 53 54 /// 55 //various http helpers for interacting with api 56 /// 57 58 func (n *nameDotCom) addAuth(r *http.Request) { 59 r.Header.Add("Api-Username", n.APIUser) 60 r.Header.Add("Api-Token", n.APIKey) 61 } 62 63 type apiResult struct { 64 Result struct { 65 Code int `json:"code"` 66 Message string `json:"message"` 67 } `json:"result"` 68 } 69 70 func (r *apiResult) getErr() error { 71 if r == nil { 72 return nil 73 } 74 if r.Result.Code != 100 { 75 if r.Result.Message == "" { 76 return fmt.Errorf("Unknown error from name.com") 77 } 78 return fmt.Errorf(r.Result.Message) 79 } 80 return nil 81 } 82 83 //perform http GET and unmarshal response json into target struct 84 func (n *nameDotCom) get(url string, target interface{}) error { 85 req, err := http.NewRequest("GET", url, nil) 86 if err != nil { 87 return err 88 } 89 n.addAuth(req) 90 resp, err := http.DefaultClient.Do(req) 91 if err != nil { 92 return err 93 } 94 defer resp.Body.Close() 95 data, err := ioutil.ReadAll(resp.Body) 96 if err != nil { 97 return err 98 } 99 return json.Unmarshal(data, target) 100 } 101 102 // perform http POST, json marshalling the given data into the body 103 func (n *nameDotCom) post(url string, data interface{}) (*apiResult, error) { 104 buf := &bytes.Buffer{} 105 enc := json.NewEncoder(buf) 106 if err := enc.Encode(data); err != nil { 107 return nil, err 108 } 109 req, err := http.NewRequest("POST", url, buf) 110 if err != nil { 111 return nil, err 112 } 113 n.addAuth(req) 114 resp, err := http.DefaultClient.Do(req) 115 if err != nil { 116 return nil, err 117 } 118 defer resp.Body.Close() 119 text, err := ioutil.ReadAll(resp.Body) 120 if err != nil { 121 return nil, err 122 } 123 result := &apiResult{} 124 if err = json.Unmarshal(text, result); err != nil { 125 return nil, err 126 } 127 return result, nil 128 }