-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdata.go
135 lines (117 loc) · 3.55 KB
/
data.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
package main
import (
"hash/fnv"
"reflect"
"sort"
"strings"
tb "github.com/viant/toolbox"
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
// IngressifyRule is a denormalization of the Ingresses rules coming from k8s
type IngressifyRule struct {
Hash uint32
ServiceName string
ServicePort int32
Host string
Path string
Namespace string
Name string
IngressRaw v1beta1.Ingress
}
// ICxt holds data used for rendering.
type ICxt struct {
IngRules []IngressifyRule
}
func hash(s string) uint32 {
h := fnv.New32a()
h.Write([]byte(s))
return h.Sum32()
}
// AsMap returns a generic map. Useful for Sprig functions
func AsMap(sourceMap interface{}) map[string]interface{} {
return tb.AsMap(sourceMap)
}
// AsSlice returns a generic list. Useful for Sprig functions
func AsSlice(sourceSlice interface{}) []interface{} {
return tb.AsSlice(sourceSlice)
}
// ToIngressifyRule converts from *v1beta1.IngressList (normalized) to IngressifyRule (denormalized)
func ToIngressifyRule(il *v1beta1.IngressList) []IngressifyRule {
var ifyrules []IngressifyRule
for _, ing := range il.Items {
var ir IngressifyRule
ir.Namespace = ing.Namespace
ir.Name = ing.Name
for _, rule := range ing.Spec.Rules {
ir.Host = rule.Host
for _, path := range rule.HTTP.Paths {
ir.Path = path.Path
ir.ServiceName = path.Backend.ServiceName
ir.ServicePort = path.Backend.ServicePort.IntVal
ir.Hash = hash(ing.Namespace + ing.Name + path.Backend.ServiceName + ir.Host + ir.Path)
ir.IngressRaw = ing
ifyrules = append(ifyrules, ir)
}
}
}
return ifyrules
}
// IngRules is just an alias to be able to implement custom sorting.
type IngRules []IngressifyRule
func (ir IngRules) Len() int {
return len(ir)
}
func (ir IngRules) Swap(i, j int) {
ir[i], ir[j] = ir[j], ir[i]
}
func (ir IngRules) Less(i, j int) bool {
return (len(ir[i].Path) < len(ir[j].Path))
}
// OrderByPathLen order the rules by Path length in ascending or descending order
func OrderByPathLen(rules []IngressifyRule, asc bool) []IngressifyRule {
if asc {
sort.Sort(sort.Reverse(IngRules(rules)))
} else {
sort.Sort(IngRules(rules))
}
return rules
}
// GroupByHost returns a map of IngressifyRule grouped by ir.Host
func GroupByHost(rules []IngressifyRule) map[string][]IngressifyRule {
return groupByGeneric(rules, "Host")
}
// GroupByPath returns a map of IngressifyRule grouped by ir.Path
func GroupByPath(rules []IngressifyRule) map[string][]IngressifyRule {
return groupByGeneric(rules, "Path")
}
// GroupBySvcNs returns a map of IngressifyRule grouped by ir.ServiceName + ir.Namespace
func GroupBySvcNs(rules []IngressifyRule) map[string][]IngressifyRule {
return groupByGeneric(rules, "ServiceName", "Namespace")
}
/*
groupByGeneric - helper function to introspect on []IngressifyRule
to create a map which keys are the concatenation of fields present in
IngressifyRule structure
*/
func groupByGeneric(rules []IngressifyRule, fields ...string) map[string][]IngressifyRule {
m := make(map[string][]IngressifyRule)
for _, rule := range rules {
value := getGroupingKey(&rule, fields...)
if _, ok := m[value]; ok {
m[value] = append(m[value], rule)
} else {
m[value] = []IngressifyRule{rule}
}
}
return m
}
// getGroupingKey - helper function for groupByGeneric to create the grouping key
func getGroupingKey(ir *IngressifyRule, fields ...string) string {
r := reflect.ValueOf(ir)
var key string
for _, field := range fields {
f := reflect.Indirect(r).FieldByName(field)
key = key + "-" + f.String()
}
return strings.TrimPrefix(key, "-")
}