domains.go raw
1 package govultr
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7
8 "github.com/google/go-querystring/query"
9 )
10
11 const domainPath = "/v2/domains"
12
13 // DomainService is the interface to interact with the DNS endpoints on the Vultr API
14 // https://www.vultr.com/api/#tag/dns
15 type DomainService interface {
16 Create(ctx context.Context, domainReq *DomainReq) (*Domain, *http.Response, error)
17 Get(ctx context.Context, domain string) (*Domain, *http.Response, error)
18 Update(ctx context.Context, domain, dnsSec string) error
19 Delete(ctx context.Context, domain string) error
20 List(ctx context.Context, options *ListOptions) ([]Domain, *Meta, *http.Response, error)
21
22 GetSoa(ctx context.Context, domain string) (*Soa, *http.Response, error)
23 UpdateSoa(ctx context.Context, domain string, soaReq *Soa) error
24
25 GetDNSSec(ctx context.Context, domain string) ([]string, *http.Response, error)
26 }
27
28 // DomainServiceHandler handles interaction with the DNS methods for the Vultr API
29 type DomainServiceHandler struct {
30 client *Client
31 }
32
33 // Domain represents a Domain entry on Vultr
34 type Domain struct {
35 Domain string `json:"domain,omitempty"`
36 DateCreated string `json:"date_created,omitempty"`
37 DNSSec string `json:"dns_sec,omitempty"`
38 }
39
40 // DomainReq is the struct to create a domain
41 // If IP is omitted then an empty DNS entry will be created. If supplied the domain will be pre populated with entries
42 type DomainReq struct {
43 Domain string `json:"domain,omitempty"`
44 IP string `json:"ip,omitempty"`
45 DNSSec string `json:"dns_sec,omitempty"`
46 }
47
48 type domainsBase struct {
49 Domains []Domain `json:"domains"`
50 Meta *Meta `json:"meta"`
51 }
52
53 type domainBase struct {
54 Domain *Domain `json:"domain"`
55 }
56
57 // Soa information for the Domain
58 type Soa struct {
59 NSPrimary string `json:"nsprimary,omitempty"`
60 Email string `json:"email,omitempty"`
61 }
62
63 type soaBase struct {
64 DNSSoa *Soa `json:"dns_soa,omitempty"`
65 }
66
67 type dnsSecBase struct {
68 DNSSec []string `json:"dns_sec,omitempty"`
69 }
70
71 // Create a domain entry
72 func (d *DomainServiceHandler) Create(ctx context.Context, domainReq *DomainReq) (*Domain, *http.Response, error) {
73 req, err := d.client.NewRequest(ctx, http.MethodPost, domainPath, domainReq)
74 if err != nil {
75 return nil, nil, err
76 }
77
78 domain := new(domainBase)
79 resp, err := d.client.DoWithContext(ctx, req, domain)
80 if err != nil {
81 return nil, resp, err
82 }
83
84 return domain.Domain, resp, nil
85 }
86
87 // Get a domain from your Vultr account.
88 func (d *DomainServiceHandler) Get(ctx context.Context, domain string) (*Domain, *http.Response, error) {
89 req, err := d.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s", domainPath, domain), nil)
90 if err != nil {
91 return nil, nil, err
92 }
93
94 dBase := new(domainBase)
95 resp, err := d.client.DoWithContext(ctx, req, dBase)
96 if err != nil {
97 return nil, resp, err
98 }
99
100 return dBase.Domain, resp, nil
101 }
102
103 // Update allows you to enable or disable DNS Sec on the domain.
104 // The two valid options for dnsSec are "enabled" or "disabled"
105 func (d *DomainServiceHandler) Update(ctx context.Context, domain, dnsSec string) error {
106 body := &RequestBody{"dns_sec": dnsSec}
107 req, err := d.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s", domainPath, domain), body)
108 if err != nil {
109 return err
110 }
111
112 _, err = d.client.DoWithContext(ctx, req, nil)
113 return err
114 }
115
116 // Delete a domain with all associated records.
117 func (d *DomainServiceHandler) Delete(ctx context.Context, domain string) error {
118 req, err := d.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s", domainPath, domain), nil)
119 if err != nil {
120 return err
121 }
122 _, err = d.client.DoWithContext(ctx, req, nil)
123 return err
124 }
125
126 // List gets all domains associated with the current Vultr account.
127 func (d *DomainServiceHandler) List(ctx context.Context, options *ListOptions) ([]Domain, *Meta, *http.Response, error) { //nolint:dupl
128 req, err := d.client.NewRequest(ctx, http.MethodGet, domainPath, nil)
129 if err != nil {
130 return nil, nil, nil, err
131 }
132
133 newValues, err := query.Values(options)
134 if err != nil {
135 return nil, nil, nil, err
136 }
137
138 req.URL.RawQuery = newValues.Encode()
139
140 domains := new(domainsBase)
141 resp, err := d.client.DoWithContext(ctx, req, domains)
142 if err != nil {
143 return nil, nil, resp, err
144 }
145
146 return domains.Domains, domains.Meta, resp, nil
147 }
148
149 // GetSoa gets the SOA record information for a domain
150 func (d *DomainServiceHandler) GetSoa(ctx context.Context, domain string) (*Soa, *http.Response, error) {
151 req, err := d.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/soa", domainPath, domain), nil)
152 if err != nil {
153 return nil, nil, err
154 }
155
156 soa := new(soaBase)
157 resp, err := d.client.DoWithContext(ctx, req, soa)
158 if err != nil {
159 return nil, resp, err
160 }
161
162 return soa.DNSSoa, resp, nil
163 }
164
165 // UpdateSoa will update the SOA record information for a domain.
166 func (d *DomainServiceHandler) UpdateSoa(ctx context.Context, domain string, soaReq *Soa) error {
167 req, err := d.client.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s/%s/soa", domainPath, domain), soaReq)
168 if err != nil {
169 return err
170 }
171
172 _, err = d.client.DoWithContext(ctx, req, nil)
173 return err
174 }
175
176 // GetDNSSec gets the DNSSec keys for a domain (if enabled)
177 func (d *DomainServiceHandler) GetDNSSec(ctx context.Context, domain string) ([]string, *http.Response, error) {
178 req, err := d.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/dnssec", domainPath, domain), nil)
179 if err != nil {
180 return nil, nil, err
181 }
182
183 dnsSec := new(dnsSecBase)
184 resp, err := d.client.DoWithContext(ctx, req, dnsSec)
185 if err != nil {
186 return nil, resp, err
187 }
188
189 return dnsSec.DNSSec, resp, nil
190 }
191