-
Notifications
You must be signed in to change notification settings - Fork 7
/
dns.go
355 lines (328 loc) · 10.7 KB
/
dns.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
342
343
344
345
346
347
348
349
350
351
352
353
354
355
package cmd
import (
"encoding/json"
"fmt"
"log"
"strconv"
"strings"
"github.com/bizflycloud/bizflyctl/formatter"
"github.com/bizflycloud/gobizfly"
"github.com/spf13/cobra"
)
var (
zoneID string
required bool
zoneDescription string
recordData string
recordName string
recordType string
httpHealthCheck string
tcpHealthCheck string
ipv4RoutingPolicy []string
ipv6RoutingPolicy []string
TTL int
domainData []string
NormalTypes = []string{"A", "AAAA", "TXT"}
NormalDataHeader = []string{"Data"}
MXDataHeader = []string{"Domain", "Priority"}
PolicyRoutingHeader = []string{"Region", "IPv4", "IPv6"}
zonesHeader = []string{"ID", "Name", "Deleted", "NameServer", "TTL", "Active", "Created At", "Update At"}
recordSetHeader = []string{"ID", "Name", "Type", "TTL"}
)
type recordPayload struct {
Record interface{} `json:"record"`
}
var dnsComnmand = &cobra.Command{
Use: "dns",
Short: "Bizfly Cloud DNS Interaction",
Long: "Bizfly Cloud DNS Action: List zones, Create zone, Get zone, Delete zone, Create record, Get record, Delete record",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("dns called")
},
}
var listZonesCommand = &cobra.Command{
Use: "list-zones",
Short: "List all zones",
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
resp, err := client.DNS.ListZones(ctx, &gobizfly.ListOptions{})
if err != nil {
log.Fatalln(err)
}
zones := resp.Zones
var data [][]string
for _, zone := range zones {
nameserverString := strings.Join(zone.NameServer, "\n")
data = append(data, []string{zone.ID, zone.Name, strconv.Itoa(zone.Deleted),
nameserverString, strconv.Itoa(zone.TTL), strconv.FormatBool(zone.Active),
zone.CreatedAt, zone.UpdatedAt})
}
formatter.Output(zonesHeader, data)
},
}
var getZoneCommand = &cobra.Command{
Use: "get-zone",
Short: "Get a zone",
Long: `Get a zone
Usage: ./bizfly dns get-zone <zone-id>`,
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
if len(args) != 1 {
log.Fatal("Invalid argument")
}
resp, err := client.DNS.GetZone(ctx, args[0])
if err != nil {
log.Fatal(err)
}
zone := resp.Zone
recordSets := resp.RecordsSet
nameserverString := strings.Join(zone.NameServer, "\n")
var zoneData [][]string
zoneData = append(zoneData, []string{zone.ID, zone.Name, strconv.Itoa(zone.Deleted),
nameserverString, strconv.Itoa(zone.TTL), strconv.FormatBool(zone.Active),
zone.CreatedAt, zone.UpdatedAt})
var recordSetData [][]string
for _, recordSet := range recordSets {
recordSetData = append(recordSetData, []string{recordSet.ID, recordSet.Name,
recordSet.Type, strconv.Itoa(recordSet.TTL)})
}
formatter.Output(zonesHeader, zoneData)
formatter.Output(recordSetHeader, recordSetData)
},
}
var createZoneCommand = &cobra.Command{
Use: "create-zone",
Short: "Create DNS Zone",
Long: `Create DNS Zone
Usage: ./bizfly dns create-zone <zone-name> [flags]`,
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
if len(args) != 1 {
log.Fatal("Invalid argument")
}
payload := &gobizfly.CreateZonePayload{
Name: args[0],
Required: required,
Description: description,
}
resp, err := client.DNS.CreateZone(ctx, payload)
if err != nil {
log.Fatal(err)
}
zone := resp.Zone
recordSets := resp.RecordsSet
nameserverString := strings.Join(zone.NameServer, "\n")
var zoneData [][]string
zoneData = append(zoneData, []string{zone.ID, zone.Name, strconv.Itoa(zone.Deleted),
nameserverString, strconv.Itoa(zone.TTL), strconv.FormatBool(zone.Active),
zone.CreatedAt, zone.UpdatedAt})
var recordSetData [][]string
for _, recordSet := range recordSets {
recordSetData = append(recordSetData, []string{recordSet.ID, recordSet.Name,
recordSet.Type, strconv.Itoa(recordSet.TTL)})
}
formatter.Output(zonesHeader, zoneData)
formatter.Output(recordSetHeader, recordSetData)
},
}
var deleteZoneCommand = &cobra.Command{
Use: "delete-zone",
Short: "Delete zone",
Long: `Delete zone
Usage: ./bizfly dns delete zone <zone-id>`,
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
if len(args) != 1 {
log.Fatal("Invalid argument")
}
err := client.DNS.DeleteZone(ctx, args[0])
if err != nil {
log.Fatal(err)
}
fmt.Println("Deleted Zone ", zoneID)
},
}
var getRecordCommand = &cobra.Command{
Use: "get-record",
Short: "Get record via ID",
Long: `Get DNS record in a zone
Usage: ./bizfly dns get-record <record-id>`,
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
if len(args) != 1 {
log.Fatal("Invalid argument")
}
recordSet, err := client.DNS.GetRecord(ctx, args[0])
if err != nil {
log.Fatal(err)
}
var recordSetData [][]string
recordSetData = append(recordSetData, []string{recordSet.ID, recordSet.Name,
recordSet.Type, strconv.Itoa(recordSet.TTL)})
formatter.Output(recordSetHeader, recordSetData)
outputRecordData(recordSet)
},
}
var createRecordCommand = &cobra.Command{
Use: "create-record",
Short: "Create new record in a zone",
Long: `Create DNS record in a zone
General arguments:
- record-name: Name of the record
- record-type: Type of the record
- ttl: Time to live
Type arguments:
- Type: Normal (A, AAAA, TXT)
+ data: IPv4/v6 addresses or domains depends on its type
Example: ./bizfly dns create-record --zone-id zone-123 --name test_a_1 --ttl 600 --type A --data "123.123.123.123;7.7.7.7
- Type: MX
+ domain-data: specify the domains and its priority. Format: --domain-data domain:priority
Example: ./bizfly dns create-record --zone-id 123-zone --name test_mx_1 --ttl 600 --type MX --domain-data test.com:10 --domain-data test1.com:49
`,
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
if checkValidType(recordType, NormalTypes) { // Normal type case
stringRecordData := fmt.Sprintf("%v", recordData)
data := parseNormalRecord(stringRecordData)
if len(data) == 0 {
log.Fatal("Invalid argument")
}
payloadData := gobizfly.CreateNormalRecordPayload{
BaseCreateRecordPayload: gobizfly.BaseCreateRecordPayload{
Name: recordName,
Type: recordType,
TTL: TTL,
},
Data: data,
}
payload := recordPayload{
Record: payloadData,
}
fmt.Printf("%+v\n", payload)
json_data, _ := json.Marshal(payload)
fmt.Println(string(json_data))
recordSet, err := client.DNS.CreateRecord(ctx, zoneID, payload)
if err != nil {
log.Fatal(err)
}
var recordSetData [][]string
stringData := ""
for _, ip := range recordSet.Data {
stringData += fmt.Sprintf("%v", ip) + "\n"
}
recordSetData = append(recordSetData, []string{recordSet.ID, recordSet.Name,
recordSet.Type, strconv.Itoa(recordSet.TTL), stringData})
formatter.Output(recordSetHeader, recordSetData)
outputRecordData(recordSet)
} else if recordType == "MX" {
mxData := parseMXRecord(domainData)
payloadData := gobizfly.CreateMXRecordPayload{
BaseCreateRecordPayload: gobizfly.BaseCreateRecordPayload{
Name: recordName,
TTL: TTL,
Type: recordType,
},
Data: mxData,
}
payload := recordPayload{
Record: payloadData,
}
recordSet, err := client.DNS.CreateRecord(ctx, zoneID, payload)
if err != nil {
log.Fatal(err)
}
var recordSetData [][]string
recordSetData = append(recordSetData, []string{recordSet.ID, recordSet.Name,
recordSet.Type, strconv.Itoa(recordSet.TTL)})
formatter.Output(recordSetHeader, recordSetData)
outputRecordData(recordSet)
}
},
}
var deleteRecordCommand = &cobra.Command{
Use: "delete-record",
Short: "Delete DNS record",
Long: `Delete DNS record
Usage: ./bizfly dns delete-record <record-id>`,
Run: func(cmd *cobra.Command, args []string) {
client, ctx := getApiClient(cmd)
if len(args) != 1 {
log.Fatal("Invalid argument")
}
err := client.DNS.DeleteRecord(ctx, args[0])
if err != nil {
log.Fatal(err)
}
fmt.Println("Deleted record successfully")
},
}
func outputRecordData(record *gobizfly.Record) {
if checkValidType(record.Type, NormalTypes) {
var IPs [][]string
for _, ip := range record.Data {
IPs = append(IPs, []string{ip.(string)})
}
formatter.Output(NormalDataHeader, IPs)
} else if record.Type == "MX" {
var mxDatas [][]string
for _, domainData := range record.Data {
domainMap := domainData.(map[string]interface{})
priority := strconv.Itoa(int(domainMap["priority"].(float64)))
mxDatas = append(mxDatas, []string{domainMap["value"].(string), priority})
}
formatter.Output(MXDataHeader, mxDatas)
}
}
func checkValidType(recordType string, validTypes []string) bool {
var result bool
for _, validType := range validTypes {
if recordType == validType {
result = true
}
}
return result
}
func parseNormalRecord(data string) []string {
return strings.Split(data, ";")
}
func parseMXRecord(data []string) []gobizfly.MXData {
var mxData []gobizfly.MXData
for _, recordString := range data {
fragments := strings.Split(recordString, ":")
domain := fragments[0]
priority, err := strconv.Atoi(fragments[1])
if err != nil {
log.Fatal(err)
}
mxData = append(mxData, gobizfly.MXData{Value: domain, Priority: priority})
}
return mxData
}
func init() {
rootCmd.AddCommand(dnsComnmand)
dnsComnmand.AddCommand(listZonesCommand)
dnsComnmand.AddCommand(getZoneCommand)
czpf := createZoneCommand.PersistentFlags()
czpf.BoolVar(&required, "required", false, "Is required")
czpf.StringVar(&zoneDescription, "description", "", "Zone description")
dnsComnmand.AddCommand(createZoneCommand)
dnsComnmand.AddCommand(deleteZoneCommand)
crpf := createRecordCommand.PersistentFlags()
crpf.StringVar(&zoneID, "zone-id", "", "Zone ID")
crpf.StringVar(&recordName, "name", "", "Name of record")
crpf.StringVar(&recordType, "type", "", "Record type")
crpf.IntVar(&TTL, "ttl", 0, "TTL of record")
crpf.StringVar(&recordData, "data", "", "Data of record")
crpf.StringArrayVar(&ipv4RoutingPolicy, "ipv4-policy", []string{}, "IPv4 policies")
crpf.StringArrayVar(&ipv6RoutingPolicy, "ipv6-policy", []string{}, "IPv6 policies")
crpf.StringVar(&tcpHealthCheck, "tcp-healthcheck", "", "TCP Health Check Configuration")
crpf.StringVar(&httpHealthCheck, "http-healthcheck", "", "HTTP Health Check Configuration")
crpf.StringArrayVar(&domainData, "domain-data", []string{}, "Domain with its priority")
_ = cobra.MarkFlagRequired(crpf, "zone-id")
_ = cobra.MarkFlagRequired(crpf, "name")
_ = cobra.MarkFlagRequired(crpf, "type")
_ = cobra.MarkFlagRequired(crpf, "ttl")
dnsComnmand.AddCommand(createRecordCommand)
dnsComnmand.AddCommand(deleteRecordCommand)
dnsComnmand.AddCommand(getRecordCommand)
}