zone.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package api
  2. import "context"
  3. // Task codes, from the AutoDNS documentation.
  4. const (
  5. // TaskZoneInquire reads one zone or lists all of them.
  6. TaskZoneInquire = "0205"
  7. // TaskZoneUpdateBulk adds and removes records in one job.
  8. TaskZoneUpdateBulk = "0202001"
  9. )
  10. // defaultListLimit is how many zones one list call asks for. A customer with
  11. // more zones than this needs paging, which Zones does transparently.
  12. const defaultListLimit = 500
  13. // ZoneSummary is a zone without its records.
  14. type ZoneSummary struct {
  15. // Name is the zone itself, for example example.com.
  16. Name string
  17. // SystemNS is the name server that serves the zone. It is mandatory on
  18. // update tasks, so it is carried through from the list.
  19. SystemNS string
  20. }
  21. // Zones lists every zone the account can see. It pages until the gateway
  22. // returns fewer zones than requested.
  23. func (c *Client) Zones(ctx context.Context) ([]ZoneSummary, error) {
  24. var out []ZoneSummary
  25. for offset := 0; ; offset += defaultListLimit {
  26. task := Task{
  27. Code: TaskZoneInquire,
  28. View: &View{Offset: offset, Limit: defaultListLimit, Children: 1},
  29. Key: []string{"name", "system_ns"},
  30. }
  31. _, result, err := c.run(ctx, task)
  32. if err != nil {
  33. return nil, err
  34. }
  35. if result.Data == nil || len(result.Data.Zone) == 0 {
  36. return out, nil
  37. }
  38. for _, z := range result.Data.Zone {
  39. out = append(out, ZoneSummary{Name: z.Name, SystemNS: z.SystemNS})
  40. }
  41. if len(result.Data.Zone) < defaultListLimit {
  42. return out, nil
  43. }
  44. }
  45. }
  46. // Zone returns one zone including every record in it.
  47. func (c *Client) Zone(ctx context.Context, name string) (*Zone, error) {
  48. task := Task{
  49. Code: TaskZoneInquire,
  50. Zone: &ZoneRef{Name: name},
  51. Key: []string{"name", "system_ns", "soa"},
  52. }
  53. _, result, err := c.run(ctx, task)
  54. if err != nil {
  55. return nil, err
  56. }
  57. if result.Data == nil || len(result.Data.Zone) == 0 {
  58. return nil, &APIError{Code: "EF02020", Text: "no such zone exists", Object: "zone " + name}
  59. }
  60. zone := result.Data.Zone[0]
  61. return &zone, nil
  62. }
  63. // Records returns the records of a zone, optionally filtered by type. An empty
  64. // type returns every record.
  65. func (c *Client) Records(ctx context.Context, zone, recordType string) ([]Record, error) {
  66. z, err := c.Zone(ctx, zone)
  67. if err != nil {
  68. return nil, err
  69. }
  70. if recordType == "" {
  71. return z.RRs, nil
  72. }
  73. out := make([]Record, 0, len(z.RRs))
  74. for _, rr := range z.RRs {
  75. if equalFold(rr.Type, recordType) {
  76. out = append(out, rr)
  77. }
  78. }
  79. return out, nil
  80. }