client.go raw
1 package regfishapi
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "io"
8 "net/http"
9 )
10
11 // Client struct holds the API client configuration
12 // including the base URL and the API key for authentication.
13 type Client struct {
14 BaseURL string
15 APIKey string
16 Client *http.Client
17 }
18
19 // NewClient creates a new instance of the Regfish API client.
20 func NewClient(apiKey string) *Client {
21 return &Client{
22 BaseURL: "https://api.regfish.de",
23 APIKey: apiKey,
24 Client: &http.Client{},
25 }
26 }
27
28 // Request helper for making HTTP requests.
29 func (c *Client) Request(method, endpoint string, body interface{}, headers map[string]string) ([]byte, error) {
30 url := fmt.Sprintf("%s%s", c.BaseURL, endpoint)
31
32 // Marshal body if provided
33 var reqBody []byte
34 var err error
35 if body != nil {
36 reqBody, err = json.Marshal(body)
37 if err != nil {
38 return nil, fmt.Errorf("failed to marshal body: %w", err)
39 }
40 }
41
42 req, err := http.NewRequest(method, url, bytes.NewBuffer(reqBody))
43 if err != nil {
44 return nil, fmt.Errorf("failed to create request: %w", err)
45 }
46
47 req.Header.Set("x-api-key", c.APIKey)
48 req.Header.Set("Content-Type", "application/json")
49 for k, v := range headers {
50 req.Header.Set(k, v)
51 }
52
53 resp, err := c.Client.Do(req)
54 if err != nil {
55 return nil, fmt.Errorf("failed to make request: %w", err)
56 }
57 defer resp.Body.Close()
58
59 if resp.StatusCode >= 400 {
60 return nil, fmt.Errorf("request failed with status code %d", resp.StatusCode)
61 }
62
63 respBody, err := io.ReadAll(resp.Body)
64 if err != nil {
65 return nil, fmt.Errorf("failed to read response body: %w", err)
66 }
67
68 return respBody, nil
69 }
70
71 // Record represents a DNS record with common fields.
72 type Record struct {
73 ID int `json:"id"`
74 Name string `json:"name"`
75 Type string `json:"type"`
76 Data string `json:"data"`
77 TTL int `json:"ttl,omitempty"`
78 Priority *int `json:"priority,omitempty"`
79 Annotation *string `json:"annotation,omitempty"`
80 Tag *string `json:"tag,omitempty"`
81 Flags *int `json:"flags,omitempty"`
82 }
83
84 // GetRecord retrieves details about a specific DNS record by RRID.
85 func (c *Client) GetRecord(rrid int) (Record, error) {
86 endpoint := fmt.Sprintf("/dns/rr/%d", rrid)
87 respBody, err := c.Request("GET", endpoint, nil, nil)
88 if err != nil {
89 return Record{}, err
90 }
91
92 var response struct {
93 Response Record `json:"response"`
94 }
95
96 err = json.Unmarshal(respBody, &response)
97 if err != nil {
98 return Record{}, fmt.Errorf("failed to unmarshal response: %w", err)
99 }
100
101 return response.Response, nil
102 }
103
104 // CreateRecord creates a new DNS record.
105 func (c *Client) CreateRecord(record Record) (Record, error) {
106 respBody, err := c.Request("POST", "/dns/rr", record, nil)
107 if err != nil {
108 return Record{}, err
109 }
110
111 var response struct {
112 Response Record `json:"response"`
113 }
114
115 err = json.Unmarshal(respBody, &response)
116 if err != nil {
117 return Record{}, fmt.Errorf("failed to unmarshal response: %w", err)
118 }
119
120 return response.Response, nil
121 }
122
123 // UpdateRecord updates a DNS record by the records' name
124 func (c *Client) UpdateRecord(record Record) (Record, error) {
125 endpoint := fmt.Sprintf("/dns/rr")
126 respBody, err := c.Request("PATCH", endpoint, record, nil)
127 if err != nil {
128 return Record{}, err
129 }
130
131 var response struct {
132 Response Record `json:"response"`
133 }
134
135 err = json.Unmarshal(respBody, &response)
136 if err != nil {
137 return Record{}, fmt.Errorf("failed to unmarshal response: %w", err)
138 }
139
140 return response.Response, nil
141 }
142
143 // UpdateRecordById updates a DNS record by RRID.
144 func (c *Client) UpdateRecordById(rrid int, record Record) (Record, error) {
145 endpoint := fmt.Sprintf("/dns/rr/%d", rrid)
146 respBody, err := c.Request("PATCH", endpoint, record, nil)
147 if err != nil {
148 return Record{}, err
149 }
150
151 var response struct {
152 Response Record `json:"response"`
153 }
154
155 err = json.Unmarshal(respBody, &response)
156 if err != nil {
157 return Record{}, fmt.Errorf("failed to unmarshal response: %w", err)
158 }
159
160 return response.Response, nil
161 }
162
163 // DeleteRecord deletes a DNS record by RRID.
164 func (c *Client) DeleteRecord(rrid int) error {
165 endpoint := fmt.Sprintf("/dns/rr/%d", rrid)
166 _, err := c.Request("DELETE", endpoint, nil, nil)
167 return err
168 }
169
170 // GetRecordsByDomain retrieves all DNS records for a given domain.
171 func (c *Client) GetRecordsByDomain(domain string) ([]Record, error) {
172 endpoint := fmt.Sprintf("/dns/%s/rr", domain)
173 respBody, err := c.Request("GET", endpoint, nil, nil)
174 if err != nil {
175 return nil, err
176 }
177
178 var response struct {
179 Response []Record `json:"response"`
180 }
181
182 err = json.Unmarshal(respBody, &response)
183 if err != nil {
184 return nil, fmt.Errorf("failed to unmarshal response: %w", err)
185 }
186
187 return response.Response, nil
188 }
189