-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathptr_update.go
More file actions
121 lines (106 loc) · 4.31 KB
/
ptr_update.go
File metadata and controls
121 lines (106 loc) · 4.31 KB
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
package main
import (
"strings"
. "github.com/dirtman/sitepkg"
)
// Implement the "update" command.
func upatePTR(invokedAs []string) error {
var input *UserInput
var ptrdname, ip, message string
var check bool
var err error
duo := true
SetStringOpt("view", "V", true, "default", "Specify the view of the record to update")
SetStringOpt("ptrdname", "n", false, "", "Update the record's ptrdname")
SetStringOpt("comment", "c", true, "", "Update the record's comment")
SetUintOpt("ttl", "", true, 0, "Update the the record's TTL")
SetStringOpt("disable", "D", true, "", "Disable the specified record")
SetStringOpt("ip", "i", false, "", "Update the record's IP address")
SetStringOpt("fields", "F", false, "", "Additional fields to be updated")
SetStringOpt("filename", "f", true, "", "Specify a name/data input file")
SetBoolOpt("checkRecords", "C", true, false, "Check for existing related records")
if input, err = subCommandInit(invokedAs[1], invokedAs[2], duo); err != nil {
return Error("failure initializing program and getting user input: %v", err)
} else if ip, err = GetStringOpt("ip"); err != nil {
return Error("failure getting IP option: %v", err)
} else if ptrdname, err = GetStringOpt("ptrdname"); err != nil {
return Error("failure getting ptrdname option: %v", err)
} else if check, err = GetBoolOpt("checkRecords"); err != nil {
return Error("failure getting checkcheckRecords option: %v", err)
}
if ptrdname != "" { // Append it to the list of field/values to be updated.
input.fields = append(input.fields, "ptrdname="+ptrdname)
}
if ip != "" { // Append it to the list of field/values to be updated.
if isIPv4(ip) {
input.fields = append(input.fields, "ipv4addr="+ip)
} else {
input.fields = append(input.fields, "ipv6addr="+ip)
}
}
// Query the record being updated, and check for errors.
states := make(StatesPTR)
f := []string{"view=" + input.view}
if err = getStates(states, input.ndList, f, nil, false, false); err != nil {
return Error("failure getting states: %v", err)
} else if errors := checkStateErrors(states, duo, true); len(errors) != 0 {
return Error("Aborting process; no records updated.")
}
space := input.maxNameLength + 8
// If we are updating the record's name itself, check for existing name conflicts
// once, before going into the loop. And if we are updating the record's IP, check
// for existing IP conflicts (if check). If a conflict is found, there is no need
// to go into the loop, since the conflict will exist for each user-specified host.
request := strings.TrimLeft(input.ndList[0], nameDataSep)
request = strings.TrimRight(request, nameDataSep)
var conflict string
if ptrdname != "" {
f := []string{"view=" + input.view, "name=" + ptrdname}
if conflict, err = checkConflict(f, true, check, check, true, true, "A"); err != nil {
return Error("failure checking host conflicts: %v", err)
}
}
if check && ip != "" && conflict == "" {
if isIPv4(ip) {
f := []string{"view=" + input.view, "ipv4addr=" + ip}
if conflict, err = checkConflict(f, true, true, false, false, false, ""); err != nil {
return Error("failure checking host conflicts: %v", err)
}
} else {
f := []string{"view=" + input.view, "ipv6addr=" + ip}
if conflict, err = checkConflict(f, true, false, true, false, false, ""); err != nil {
return Error("failure checking host conflicts: %v", err)
}
}
}
if conflict != "" {
return Error("%-*s NOT updated: %s\n", space, "PTR("+request+")", conflict)
}
// Loop through the user provided input (name/data) list.
var numNotFound, numFailed uint
for _, nameData := range input.ndList {
records := states[nameData].records
request := strings.TrimLeft(nameData, nameDataSep)
request = strings.TrimRight(request, nameDataSep)
if len(records) == 0 {
Print("%-*s NOTFOUND\n", space, "PTR("+request+")")
numNotFound++
continue
}
_, err = updateRecord(records[0].Ref, input.fields)
message = "(fields: " + strings.Join(input.fields, ",") + ")"
if err != nil {
Print("%-*s FAILED to update: %v\n", space, "PTR("+request+")", err)
numFailed++
continue
} else {
Print("%-*s Updated %s\n", space, "PTR("+request+")", message)
}
}
if numFailed != 0 {
return Error("One or more updates failed")
} else if numNotFound != 0 {
return Error("One or more records not found")
}
return nil
}