rrsetManager.go raw

   1  package v2
   2  
   3  import (
   4  	"bytes"
   5  	"context"
   6  	"encoding/json"
   7  	"fmt"
   8  	"io"
   9  	"net/http"
  10  )
  11  
  12  // Types of domain name.
  13  const (
  14  	A     RecordType = "A"
  15  	AAAA  RecordType = "AAAA"
  16  	ALIAS RecordType = "ALIAS"
  17  	CAA   RecordType = "CAA"
  18  	CNAME RecordType = "CNAME"
  19  	MX    RecordType = "MX"
  20  	NS    RecordType = "NS"
  21  	SOA   RecordType = "SOA"
  22  	SRV   RecordType = "SRV"
  23  	SSHFP RecordType = "SSHFP"
  24  	TXT   RecordType = "TXT"
  25  )
  26  
  27  type (
  28  	// RecordType contains record types supported by target DNS api.
  29  	RecordType string
  30  
  31  	// RRSet is list of records grouped by their name and type.
  32  	RRSet struct {
  33  		ID        string       `json:"id"`
  34  		ZoneID    string       `json:"zone_id"`
  35  		Name      string       `json:"name"`
  36  		TTL       int          `json:"ttl"`
  37  		Type      RecordType   `json:"type"`
  38  		Comment   string       `json:"comment"`
  39  		ManagedBy string       `json:"managed_by"`
  40  		Records   []RecordItem `json:"records"`
  41  	}
  42  
  43  	// RecordItem represents single record from RRSet.
  44  	RecordItem struct {
  45  		Content  string `json:"content"`
  46  		Disabled bool   `json:"disabled"`
  47  	}
  48  
  49  	rrsetCreationForm struct {
  50  		Name      string       `json:"name"`
  51  		TTL       int          `json:"ttl"`
  52  		Type      RecordType   `json:"type"`
  53  		Records   []RecordItem `json:"records"`
  54  		Comment   string       `json:"comment,omitempty"`
  55  		ManagedBy string       `json:"managed_by,omitempty"`
  56  	}
  57  
  58  	rrsetUpdateForm struct {
  59  		TTL       int          `json:"ttl"`
  60  		Records   []RecordItem `json:"records"`
  61  		Comment   string       `json:"comment,omitempty"`
  62  		ManagedBy string       `json:"managed_by,omitempty"`
  63  	}
  64  )
  65  
  66  func (s *RRSet) CreationForm() (io.Reader, error) {
  67  	form := rrsetCreationForm{
  68  		Name:      s.Name,
  69  		TTL:       s.TTL,
  70  		Type:      s.Type,
  71  		Records:   s.Records,
  72  		Comment:   s.Comment,
  73  		ManagedBy: s.ManagedBy,
  74  	}
  75  	body, err := json.Marshal(form)
  76  
  77  	return bytes.NewReader(body), err
  78  }
  79  
  80  func (s *RRSet) UpdateForm() (io.Reader, error) {
  81  	form := rrsetUpdateForm{
  82  		TTL:       s.TTL,
  83  		Records:   s.Records,
  84  		Comment:   s.Comment,
  85  		ManagedBy: s.ManagedBy,
  86  	}
  87  	body, err := json.Marshal(form)
  88  
  89  	return bytes.NewReader(body), err
  90  }
  91  
  92  // CreateRRSet request to create a new rrset for the zone.
  93  func (c *Client) CreateRRSet(ctx context.Context, zoneID string, rrset Creatable) (*RRSet, error) {
  94  	form, err := rrset.CreationForm()
  95  	if err != nil {
  96  		return nil, fmt.Errorf("rrset creation form: %w", err)
  97  	}
  98  	r, e := c.prepareRequest(
  99  		ctx, http.MethodPost, fmt.Sprintf(rrsetPath, zoneID), form, nil, nil,
 100  	)
 101  
 102  	return processRequest[RRSet](c.httpClient, r, e)
 103  }
 104  
 105  // DeleteRRSet request to delete the rrset from zone by zoneID and rrsetID.
 106  func (c *Client) DeleteRRSet(ctx context.Context, zoneID, rrsetID string) error {
 107  	r, e := c.prepareRequest(
 108  		ctx, http.MethodDelete, fmt.Sprintf(singleRRSetPath, zoneID, rrsetID), nil, nil, nil,
 109  	)
 110  	_, err := processRequest[RRSet](c.httpClient, r, e)
 111  
 112  	return err
 113  }
 114  
 115  // GetRRSet returns a single rrset from zone by zoneID and rrsetID.
 116  func (c *Client) GetRRSet(ctx context.Context, zoneID, rrsetID string) (*RRSet, error) {
 117  	r, e := c.prepareRequest(
 118  		ctx, http.MethodGet, fmt.Sprintf(singleRRSetPath, zoneID, rrsetID), nil, nil, nil,
 119  	)
 120  
 121  	return processRequest[RRSet](c.httpClient, r, e)
 122  }
 123  
 124  // ListRRSets returns a list of rrsets by zoneID and options.
 125  func (c *Client) ListRRSets(ctx context.Context, zoneID string, options *map[string]string) (Listable[RRSet], error) {
 126  	r, e := c.prepareRequest(
 127  		ctx, http.MethodGet, fmt.Sprintf(rrsetPath, zoneID), nil, options, nil,
 128  	)
 129  
 130  	return processRequest[List[RRSet]](c.httpClient, r, e)
 131  }
 132  
 133  // UpdateRRSet request to update the rrset for zone by zoneID and rrsetID.
 134  func (c *Client) UpdateRRSet(ctx context.Context, zoneID, rrsetID string, rrset Updatable) error {
 135  	form, err := rrset.UpdateForm()
 136  	if err != nil {
 137  		return fmt.Errorf("rrset update form: %w", err)
 138  	}
 139  	r, e := c.prepareRequest(
 140  		ctx, http.MethodPatch, fmt.Sprintf(singleRRSetPath, zoneID, rrsetID), form, nil, nil,
 141  	)
 142  	_, err = processRequest[RRSet](c.httpClient, r, e)
 143  
 144  	return err
 145  }
 146