dns.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package cloudflare
  2. import (
  3. "encoding/json"
  4. "net/url"
  5. "strconv"
  6. "time"
  7. "github.com/pkg/errors"
  8. )
  9. // DNSRecord represents a DNS record in a zone.
  10. type DNSRecord struct {
  11. ID string `json:"id,omitempty"`
  12. Type string `json:"type,omitempty"`
  13. Name string `json:"name,omitempty"`
  14. Content string `json:"content,omitempty"`
  15. Proxiable bool `json:"proxiable,omitempty"`
  16. Proxied bool `json:"proxied"`
  17. TTL int `json:"ttl,omitempty"`
  18. Locked bool `json:"locked,omitempty"`
  19. ZoneID string `json:"zone_id,omitempty"`
  20. ZoneName string `json:"zone_name,omitempty"`
  21. CreatedOn time.Time `json:"created_on,omitempty"`
  22. ModifiedOn time.Time `json:"modified_on,omitempty"`
  23. Data interface{} `json:"data,omitempty"` // data returned by: SRV, LOC
  24. Meta interface{} `json:"meta,omitempty"`
  25. Priority int `json:"priority"`
  26. }
  27. // DNSRecordResponse represents the response from the DNS endpoint.
  28. type DNSRecordResponse struct {
  29. Result DNSRecord `json:"result"`
  30. Response
  31. ResultInfo `json:"result_info"`
  32. }
  33. // DNSListResponse represents the response from the list DNS records endpoint.
  34. type DNSListResponse struct {
  35. Result []DNSRecord `json:"result"`
  36. Response
  37. ResultInfo `json:"result_info"`
  38. }
  39. // CreateDNSRecord creates a DNS record for the zone identifier.
  40. //
  41. // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
  42. func (api *API) CreateDNSRecord(zoneID string, rr DNSRecord) (*DNSRecordResponse, error) {
  43. uri := "/zones/" + zoneID + "/dns_records"
  44. res, err := api.makeRequest("POST", uri, rr)
  45. if err != nil {
  46. return nil, errors.Wrap(err, errMakeRequestError)
  47. }
  48. var recordResp *DNSRecordResponse
  49. err = json.Unmarshal(res, &recordResp)
  50. if err != nil {
  51. return nil, errors.Wrap(err, errUnmarshalError)
  52. }
  53. return recordResp, nil
  54. }
  55. // DNSRecords returns a slice of DNS records for the given zone identifier.
  56. //
  57. // This takes a DNSRecord to allow filtering of the results returned.
  58. //
  59. // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
  60. func (api *API) DNSRecords(zoneID string, rr DNSRecord) ([]DNSRecord, error) {
  61. // Construct a query string
  62. v := url.Values{}
  63. // Request as many records as possible per page - API max is 50
  64. v.Set("per_page", "50")
  65. if rr.Name != "" {
  66. v.Set("name", rr.Name)
  67. }
  68. if rr.Type != "" {
  69. v.Set("type", rr.Type)
  70. }
  71. if rr.Content != "" {
  72. v.Set("content", rr.Content)
  73. }
  74. var query string
  75. var records []DNSRecord
  76. page := 1
  77. // Loop over makeRequest until what we've fetched all records
  78. for {
  79. v.Set("page", strconv.Itoa(page))
  80. query = "?" + v.Encode()
  81. uri := "/zones/" + zoneID + "/dns_records" + query
  82. res, err := api.makeRequest("GET", uri, nil)
  83. if err != nil {
  84. return []DNSRecord{}, errors.Wrap(err, errMakeRequestError)
  85. }
  86. var r DNSListResponse
  87. err = json.Unmarshal(res, &r)
  88. if err != nil {
  89. return []DNSRecord{}, errors.Wrap(err, errUnmarshalError)
  90. }
  91. records = append(records, r.Result...)
  92. if r.ResultInfo.Page >= r.ResultInfo.TotalPages {
  93. break
  94. }
  95. // Loop around and fetch the next page
  96. page++
  97. }
  98. return records, nil
  99. }
  100. // DNSRecord returns a single DNS record for the given zone & record
  101. // identifiers.
  102. //
  103. // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-dns-record-details
  104. func (api *API) DNSRecord(zoneID, recordID string) (DNSRecord, error) {
  105. uri := "/zones/" + zoneID + "/dns_records/" + recordID
  106. res, err := api.makeRequest("GET", uri, nil)
  107. if err != nil {
  108. return DNSRecord{}, errors.Wrap(err, errMakeRequestError)
  109. }
  110. var r DNSRecordResponse
  111. err = json.Unmarshal(res, &r)
  112. if err != nil {
  113. return DNSRecord{}, errors.Wrap(err, errUnmarshalError)
  114. }
  115. return r.Result, nil
  116. }
  117. // UpdateDNSRecord updates a single DNS record for the given zone & record
  118. // identifiers.
  119. //
  120. // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
  121. func (api *API) UpdateDNSRecord(zoneID, recordID string, rr DNSRecord) error {
  122. rec, err := api.DNSRecord(zoneID, recordID)
  123. if err != nil {
  124. return err
  125. }
  126. // Populate the record name from the existing one if the update didn't
  127. // specify it.
  128. if rr.Name == "" {
  129. rr.Name = rec.Name
  130. }
  131. rr.Type = rec.Type
  132. uri := "/zones/" + zoneID + "/dns_records/" + recordID
  133. res, err := api.makeRequest("PATCH", uri, rr)
  134. if err != nil {
  135. return errors.Wrap(err, errMakeRequestError)
  136. }
  137. var r DNSRecordResponse
  138. err = json.Unmarshal(res, &r)
  139. if err != nil {
  140. return errors.Wrap(err, errUnmarshalError)
  141. }
  142. return nil
  143. }
  144. // DeleteDNSRecord deletes a single DNS record for the given zone & record
  145. // identifiers.
  146. //
  147. // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-delete-dns-record
  148. func (api *API) DeleteDNSRecord(zoneID, recordID string) error {
  149. uri := "/zones/" + zoneID + "/dns_records/" + recordID
  150. res, err := api.makeRequest("DELETE", uri, nil)
  151. if err != nil {
  152. return errors.Wrap(err, errMakeRequestError)
  153. }
  154. var r DNSRecordResponse
  155. err = json.Unmarshal(res, &r)
  156. if err != nil {
  157. return errors.Wrap(err, errUnmarshalError)
  158. }
  159. return nil
  160. }