1package easydns 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "path" 10) 11 12const defaultEndpoint = "https://rest.easydns.net" 13 14type zoneRecord struct { 15 ID string `json:"id,omitempty"` 16 Domain string `json:"domain"` 17 Host string `json:"host"` 18 TTL string `json:"ttl"` 19 Prio string `json:"prio"` 20 Type string `json:"type"` 21 Rdata string `json:"rdata"` 22 LastMod string `json:"last_mod,omitempty"` 23 Revoked int `json:"revoked,omitempty"` 24 NewHost string `json:"new_host,omitempty"` 25} 26 27type addRecordResponse struct { 28 Msg string `json:"msg"` 29 Tm int `json:"tm"` 30 Data zoneRecord `json:"data"` 31 Status int `json:"status"` 32} 33 34func (d *DNSProvider) addRecord(domain string, record interface{}) (string, error) { 35 pathAdd := path.Join("/zones/records/add", domain, "TXT") 36 37 response := &addRecordResponse{} 38 err := d.doRequest(http.MethodPut, pathAdd, record, response) 39 if err != nil { 40 return "", err 41 } 42 43 recordID := response.Data.ID 44 45 return recordID, nil 46} 47 48func (d *DNSProvider) deleteRecord(domain, recordID string) error { 49 pathDelete := path.Join("/zones/records", domain, recordID) 50 51 return d.doRequest(http.MethodDelete, pathDelete, nil, nil) 52} 53 54func (d *DNSProvider) doRequest(method, resource string, requestMsg, responseMsg interface{}) error { 55 reqBody := &bytes.Buffer{} 56 if requestMsg != nil { 57 err := json.NewEncoder(reqBody).Encode(requestMsg) 58 if err != nil { 59 return err 60 } 61 } 62 63 endpoint, err := d.config.Endpoint.Parse(resource + "?format=json") 64 if err != nil { 65 return err 66 } 67 68 request, err := http.NewRequest(method, endpoint.String(), reqBody) 69 if err != nil { 70 return err 71 } 72 73 request.Header.Set("Content-Type", "application/json") 74 request.Header.Set("Accept", "application/json") 75 request.SetBasicAuth(d.config.Token, d.config.Key) 76 77 response, err := d.config.HTTPClient.Do(request) 78 if err != nil { 79 return err 80 } 81 defer response.Body.Close() 82 83 if response.StatusCode >= http.StatusBadRequest { 84 body, err := io.ReadAll(response.Body) 85 if err != nil { 86 return fmt.Errorf("%d: failed to read response body: %w", response.StatusCode, err) 87 } 88 89 return fmt.Errorf("%d: request failed: %v", response.StatusCode, string(body)) 90 } 91 92 if responseMsg != nil { 93 return json.NewDecoder(response.Body).Decode(responseMsg) 94 } 95 96 return nil 97} 98