Newer
Older
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
package metrics
import "strings"
// treeNode is used for domain whitelisting.
type treeNode struct {
Leaf bool
Value string
FullValue string
SubNodes []*treeNode
}
func (t *treeNode) findOrCreateSubNode(v string) *treeNode {
if t.SubNodes == nil {
t.SubNodes = []*treeNode{}
}
for _, n := range t.SubNodes {
if !n.Leaf && n.Value == v {
return n
}
}
node := &treeNode{Value: v}
t.SubNodes = append(t.SubNodes, node)
return node
}
func (t *treeNode) getMatch(s []string) string {
if t.Leaf || len(t.SubNodes) == 0 || len(s) == 0 {
return ""
}
for _, node := range t.SubNodes {
if node.Value == "*" || node.Value == s[0] {
if node.Leaf {
return node.FullValue
}
if match := node.getMatch(s[1:]); match != "" {
return match
}
}
}
return ""
}
func parseWhitelistSlice(hostnameWhitelist []string) *treeNode {
// NOTE: using arrays because the provided order is important (maps would be a check if part in in map,
// then check for *, which works but doesn't maintain order)
tree := &treeNode{SubNodes: []*treeNode{}}
for _, d := range hostnameWhitelist {
split := strings.Split(d, ".")
currentNode := tree
for i, s := range split {
currentNode = currentNode.findOrCreateSubNode(s)
if i+1 == len(split) {
currentNode.Leaf = true
currentNode.FullValue = d
continue
}
if currentNode.SubNodes == nil {
currentNode.SubNodes = []*treeNode{}
}
}
}
return tree
}