forked from abh/geodns-config
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlabels.go
160 lines (130 loc) · 3.21 KB
/
labels.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
package dnsconfig
import (
"fmt"
"net"
"sync"
)
type labelsMap map[string]*Label
// Labels map hostnames to nodes or groups
type Labels struct {
labels labelsMap
mutex sync.Mutex
}
type labelNode struct {
Name string
Active bool
IP net.IP
}
// Label has a name (hostname) and either a group name or a map of nodes
type Label struct {
Name string
LabelNodes map[string]labelNode
GroupName string
}
// NewLabels return a new Labels struct
func NewLabels() Labels {
ls := Labels{}
ls.Clear()
return ls
}
// All returns a slice of the labels
func (ls *Labels) All() (r []*Label) {
ls.mutex.Lock()
defer ls.mutex.Unlock()
for _, label := range ls.labels {
r = append(r, label)
}
return
}
// Clear resets the labels map
func (ls *Labels) Clear() {
ls.mutex.Lock()
defer ls.mutex.Unlock()
ls.labels = labelsMap{}
}
// SetGroup sets the label to be a particular group
func (ls *Labels) SetGroup(name, groupName string) {
ls.mutex.Lock()
defer ls.mutex.Unlock()
label, ok := ls.labels[name]
if !ok {
label = &Label{Name: name, LabelNodes: make(map[string]labelNode)}
ls.labels[name] = label
}
label.GroupName = groupName
}
// SetNode adds a node to a label
func (ls *Labels) SetNode(name string, node labelNode) {
ls.mutex.Lock()
defer ls.mutex.Unlock()
label, ok := ls.labels[name]
if !ok {
label = &Label{Name: name, LabelNodes: make(map[string]labelNode)}
ls.labels[name] = label
}
label.LabelNodes[node.Name] = node
}
// Get returns a named label
func (ls *Labels) Get(name string) *Label {
ls.mutex.Lock()
defer ls.mutex.Unlock()
if label, ok := ls.labels[name]; ok {
return label
}
return nil
}
// Count returns the number of labels
func (ls *Labels) Count() int {
ls.mutex.Lock()
defer ls.mutex.Unlock()
return len(ls.labels)
}
// LoadFile loads a labels.json file into the data structure. It is not currently
// cleared first.
func (ls *Labels) LoadFile(fileName string) error {
objmap := make(objMap)
return jsonLoader(fileName, objmap, func() error {
var newLabels = NewLabels()
for name, v := range objmap {
data := v.(map[string]interface{})
for labelName, labelTarget := range data {
if labelName == "group" {
newLabels.SetGroup(name, labelTarget.(string))
continue
}
node := labelNode{Name: labelName, Active: true}
var ipStr string
switch labelTarget.(type) {
case string:
ipStr = labelTarget.(string)
case map[string]interface{}:
v := labelTarget.(map[string]interface{})
if ipV, ok := v["ip"]; ok {
ipStr = ipV.(string)
}
if activeV, ok := v["active"]; ok {
active, err := toBool(activeV)
node.Active = active
if err != nil {
fmt.Errorf("Invalid active flag for '%s'/'%s': %s", name, labelName, active)
}
}
default:
return fmt.Errorf("Invalid value type for '%s'/%s': %T (%#v)", name, labelName, labelTarget, labelTarget)
}
if len(ipStr) > 0 {
ip := net.ParseIP(ipStr)
if ip == nil {
return fmt.Errorf("Invalid IP address for '%s'/'%s': %s", name, labelName, ipStr)
}
node.IP = ip
}
newLabels.SetNode(name, node)
}
}
ls.mutex.Lock()
defer ls.mutex.Unlock()
ls.labels = newLabels.labels
return nil
})
}