-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
137 lines (125 loc) · 3.78 KB
/
types.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
package main
// For the random() label function argument
import (
"fmt"
"strings"
"sync"
)
type labelfunction func() string
// Function ...
// Enum declaration
type Function int
// An enum for supported functions
const (
ImportValue Function = 0
AddLabel Function = 1
)
// ResolveData ...
// Type used to store the data needed to resolve each Fn::
// Creates a list of these in ParseJson
// JSONTreePath: this is the path into the json object sent by kubernetes api
// this is found recursively while we search the json object for Fn:: declarations.
// and then used later in Jsonpatch object. (it needs this to know where to replace)
// AnnotationPath: This is the path to the annotation stored in the data structure
// [Namespace]?.[Kind].[InstanceName].[outputVariable]
// used for the ImportValue functions
// Value:
// this is used for the addlabel functions since we don't need to use annotationpath
// as the value we will replace it with are provided in the val of key/val function
// FunctionType
// this is an enum of the functions we support for Fn:: in the yamls
type ResolveData struct {
JSONTreePath string
AnnotationPath string
FunctionType Function
Value string
}
// StringStack...
// This is a stack I implemented that we use when recursively parsing the json
// to track where we are in the json tree.
// We use this to populate the JSONTreePath variable.
type StringStack struct {
Data string
Mutex sync.Mutex
}
func (s *StringStack) Len() int {
s.Mutex.Lock()
defer s.Mutex.Unlock()
return len(s.Data)
}
func (s *StringStack) Push(key string) {
s.Mutex.Lock()
defer s.Mutex.Unlock()
s.Data = fmt.Sprintf("%s%s%s", s.Data, "/", key)
}
func (s *StringStack) Pop() {
s.Mutex.Lock()
defer s.Mutex.Unlock()
if len(s.Data) == 0 {
return
}
ind := strings.LastIndex(s.Data, "/")
s.Data = s.Data[:ind]
}
func (s *StringStack) Peek() string {
s.Mutex.Lock()
defer s.Mutex.Unlock()
return s.Data
}
// Entry ...
// This is a single Entry in our data structure: map[<CrdKind>]-> Entries
// we use this to store annotation data. Then we search each of these when
// doing Fn::ImportValue
type Entry struct {
InstanceName string
Namespace string
Key string
Value string
}
// StoredAnnotations ...
// data structure: map[<CrdKind>]-> Entries
// maps kind to list of entries
type StoredAnnotations struct {
KindToEntry map[string][]Entry
}
func (a *StoredAnnotations) Exists(e Entry, kind string) bool {
var entryList []Entry
var kindExists bool
if entryList, kindExists = annotations.KindToEntry[kind]; !kindExists {
return false
}
for i := 0; i < len(entryList); i++ {
entry := entryList[i]
if strings.EqualFold(entry.InstanceName, e.InstanceName) &&
strings.EqualFold(entry.Key, e.Key) &&
strings.EqualFold(entry.Value, e.Value) &&
strings.EqualFold(entry.Namespace, e.Namespace) {
return true
}
}
return false
}
func (a *StoredAnnotations) Delete(e Entry, kind string) bool {
var entryList []Entry
var kindExists bool
if entryList, kindExists = annotations.KindToEntry[kind]; !kindExists {
fmt.Println("Could not delete bc kind does not exist.")
return false
}
var indexToDelete int
for i := 0; i < len(entryList); i++ {
entry := entryList[i]
if strings.EqualFold(entry.InstanceName, e.InstanceName) &&
strings.EqualFold(entry.Value, e.Value) &&
strings.EqualFold(entry.Namespace, e.Namespace) &&
strings.EqualFold(entry.Key, e.Key) {
indexToDelete = i
break
}
}
le := len(annotations.KindToEntry[kind])
annotations.KindToEntry[kind][indexToDelete] = annotations.KindToEntry[kind][le-1] //swap to last
annotations.KindToEntry[kind][le-1] = Entry{} //write zero value
annotations.KindToEntry[kind] = annotations.KindToEntry[kind][:le-1] //truncate
return true
}