forked from G-Core/gcore-dns-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client_dto.go
341 lines (298 loc) · 7.52 KB
/
client_dto.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
package dnssdk
import (
"fmt"
"net"
"strconv"
"strings"
)
// ListZones dto to read list of zones from API
type ListZones struct {
Zones []Zone `json:"zones"`
}
// Zone dto to read info from API
type Zone struct {
Name string `json:"name"`
Records []ZoneRecord `json:"records"`
}
// AddZone dto to create new zone
type AddZone struct {
Name string `json:"name"`
}
// CreateResponse dto to create new zone
type CreateResponse struct {
ID uint64 `json:"id,omitempty"`
Error string `json:"error,omitempty"`
}
// RRSet dto as part of zone info from API
type RRSet struct {
TTL int `json:"ttl"`
Records []ResourceRecord `json:"resource_records"`
Filters []RecordFilter `json:"filters"`
}
// ResourceRecord dto describe records in RRSet
type ResourceRecord struct {
Content []interface{} `json:"content"`
Meta map[string]interface{} `json:"meta"`
Enabled bool `json:"enabled"`
}
// ContentToString as short value
func (r ResourceRecord) ContentToString() string {
parts := make([]string, len(r.Content))
for i := range r.Content {
parts[i] = fmt.Sprint(r.Content[i])
}
return strings.Join(parts, " ")
}
// RecordFilter describe Filters in RRSet
type RecordFilter struct {
Limit uint `json:"limit"`
Type string `json:"type"`
Strict bool `json:"strict"`
}
// NewGeoDNSFilter for RRSet
func NewGeoDNSFilter(limit uint, strict bool) RecordFilter {
return RecordFilter{
Limit: limit,
Type: "geodns",
Strict: strict,
}
}
// NewGeoDistanceFilter for RRSet
func NewGeoDistanceFilter(limit uint, strict bool) RecordFilter {
return RecordFilter{
Limit: limit,
Type: "geodistance",
Strict: strict,
}
}
// NewDefaultFilter for RRSet
func NewDefaultFilter(limit uint, strict bool) RecordFilter {
return RecordFilter{
Limit: limit,
Type: "default",
Strict: strict,
}
}
// NewFirstNFilter for RRSet
func NewFirstNFilter(limit uint, strict bool) RecordFilter {
return RecordFilter{
Limit: limit,
Type: "first_n",
Strict: strict,
}
}
// RecordType contract
type RecordType interface {
ToContent() []interface{}
}
// RecordTypeMX as type of record
type RecordTypeMX string
// ToContent convertor
func (mx RecordTypeMX) ToContent() []interface{} {
parts := strings.Split(string(mx), " ")
// nolint: gomnd
if len(parts) != 2 {
return nil
}
content := make([]interface{}, len(parts))
// nolint: gomnd
content[1] = parts[1]
// nolint: gomnd
content[0], _ = strconv.ParseInt(parts[0], 10, 64)
return content
}
// RecordTypeCAA as type of record
type RecordTypeCAA string
// ToContent convertor
func (caa RecordTypeCAA) ToContent() []interface{} {
parts := strings.Split(string(caa), " ")
// nolint: gomnd
if len(parts) < 3 {
return nil
}
content := make([]interface{}, len(parts))
// nolint: gomnd
content[1] = parts[1]
// nolint: gomnd
content[2] = strings.Join(parts[2:], " ")
// nolint: gomnd
content[0], _ = strconv.ParseInt(parts[0], 10, 64)
return content
}
// RecordTypeSRV as type of record
type RecordTypeSRV string
// ToContent convertor
func (srv RecordTypeSRV) ToContent() []interface{} {
parts := strings.Split(string(srv), " ")
// nolint: gomnd
if len(parts) != 4 {
return nil
}
content := make([]interface{}, len(parts))
// nolint: gomnd
content[0], _ = strconv.ParseInt(parts[0], 10, 64)
// nolint: gomnd
content[1], _ = strconv.ParseInt(parts[1], 10, 64)
// nolint: gomnd
content[2], _ = strconv.ParseInt(parts[2], 10, 64)
// nolint: gomnd
content[3] = parts[3]
return content
}
// RecordTypeAny as type of record
type RecordTypeAny string
// ToContent convertor
func (any RecordTypeAny) ToContent() []interface{} {
return []interface{}{string(any)}
}
// ToRecordType builder
func ToRecordType(rType, content string) RecordType {
switch strings.ToLower(rType) {
case "mx":
return RecordTypeMX(content)
case "caa":
return RecordTypeCAA(content)
case "srv":
return RecordTypeSRV(content)
}
return RecordTypeAny(content)
}
// ContentFromValue convertor from flat value to valid for api
func ContentFromValue(recordType, content string) []interface{} {
rt := ToRecordType(recordType, content)
if rt == nil {
return nil
}
return rt.ToContent()
}
// ResourceMeta for ResourceRecord
type ResourceMeta struct {
name string
value interface{}
validErr error
}
// Valid error
func (rm ResourceMeta) Valid() error {
return rm.validErr
}
// NewResourceMetaIP for ip meta
func NewResourceMetaIP(ips ...string) ResourceMeta {
for _, v := range ips {
ip := net.ParseIP(v)
if ip == nil {
// nolint: goerr113
return ResourceMeta{validErr: fmt.Errorf("wrong ip")}
}
}
return ResourceMeta{
name: "ip",
value: ips,
}
}
// NewResourceMetaAsn for asn meta
func NewResourceMetaAsn(asn ...uint64) ResourceMeta {
return ResourceMeta{
name: "asn",
value: asn,
}
}
// NewResourceMetaLatLong for lat long meta
func NewResourceMetaLatLong(latlong string) ResourceMeta {
latlong = strings.TrimLeft(latlong, "(")
latlong = strings.TrimLeft(latlong, "[")
latlong = strings.TrimLeft(latlong, "{")
latlong = strings.TrimRight(latlong, ")")
latlong = strings.TrimRight(latlong, "]")
latlong = strings.TrimRight(latlong, "}")
parts := strings.Split(strings.ReplaceAll(latlong, " ", ""), ",")
// nolint: gomnd
if len(parts) != 2 {
// nolint: goerr113
return ResourceMeta{validErr: fmt.Errorf("latlong invalid format")}
}
lat, err := strconv.ParseFloat(parts[0], 64)
if err != nil {
// nolint: goerr113
return ResourceMeta{validErr: fmt.Errorf("lat is invalid: %w", err)}
}
long, err := strconv.ParseFloat(parts[1], 64)
// nolint: goerr113
if err != nil {
return ResourceMeta{validErr: fmt.Errorf("long is invalid: %w", err)}
}
return ResourceMeta{
name: "latlong",
value: []float64{lat, long},
}
}
// NewResourceMetaNotes for notes meta
func NewResourceMetaNotes(notes ...string) ResourceMeta {
return ResourceMeta{
name: "notes",
value: notes,
}
}
// NewResourceMetaCountries for Countries meta
func NewResourceMetaCountries(countries ...string) ResourceMeta {
return ResourceMeta{
name: "countries",
value: countries,
}
}
// NewResourceMetaContinents for continents meta
func NewResourceMetaContinents(continents ...string) ResourceMeta {
return ResourceMeta{
name: "continents",
value: continents,
}
}
// NewResourceMetaDefault for default meta
func NewResourceMetaDefault() ResourceMeta {
return ResourceMeta{
name: "default",
value: true,
}
}
// SetContent to ResourceRecord
func (r *ResourceRecord) SetContent(recordType, val string) *ResourceRecord {
r.Content = ContentFromValue(recordType, val)
return r
}
// AddMeta to ResourceRecord
func (r *ResourceRecord) AddMeta(meta ResourceMeta) *ResourceRecord {
if meta.validErr != nil {
return r
}
if meta.name == "" || meta.value == "" {
return r
}
if r.Meta == nil {
r.Meta = map[string]interface{}{}
}
r.Meta[meta.name] = meta.value
return r
}
// AddFilter to RRSet
func (rr *RRSet) AddFilter(filters ...RecordFilter) *RRSet {
if rr.Filters == nil {
rr.Filters = make([]RecordFilter, 0)
}
rr.Filters = append(rr.Filters, filters...)
return rr
}
// ZoneRecord dto describe records in Zone
type ZoneRecord struct {
Name string `json:"name"`
Type string `json:"type"`
TTL uint `json:"ttl"`
ShortAnswers []string `json:"short_answers"`
}
// APIError customization for API calls
type APIError struct {
StatusCode int `json:"-"`
Message string `json:"error,omitempty"`
}
// Error implementation
func (a APIError) Error() string {
return fmt.Sprintf("%d: %s", a.StatusCode, a.Message)
}