-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlabels.go
188 lines (155 loc) · 3.86 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
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
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
Cname string
}
// 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
}
// Get all nodes for a label
func (l *Label) GetNodes() []labelNode {
lbls := make([]labelNode, 0)
for _, lbl := range l.labelNodes {
lbls = append(lbls, lbl)
}
return lbls
}
func (l *Label) GetNode(name string) *labelNode {
lbl := l.labelNodes[name]
if lbl.Name != "" {
return &lbl
}
for nodeName, node := range l.labelNodes {
if matchWildcard(nodeName, name) {
return &labelNode{Name: name, Active: node.Active, IP: node.IP, Cname: node.Cname}
}
}
return nil
}
// 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
}
// fmt.Printf("labelName '%s', labelTarget '%#v'\n", labelName, labelTarget)
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 cnameV, ok := v["cname"]; ok {
node.Cname = cnameV.(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
})
}