Skip to content

Commit a9eb6d4

Browse files
committed
add removal of roles, labels and annotations
Signed-off-by: Markus Blaschke <[email protected]>
1 parent 8137f43 commit a9eb6d4

File tree

5 files changed

+140
-80
lines changed

5 files changed

+140
-80
lines changed

config/config.go

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ type (
3131
}
3232

3333
PoolConfigNode struct {
34-
Roles *[]string `yaml:"roles"`
34+
Roles PoolConfigNodeValueMap `yaml:"roles"`
3535
ConfigSource *PoolConfigNodeConfigSource `yaml:"configSource"`
36-
Labels *map[string]string `yaml:"labels"`
37-
Annotations *map[string]string `yaml:"annotations"`
36+
Labels PoolConfigNodeValueMap `yaml:"labels"`
37+
Annotations PoolConfigNodeValueMap `yaml:"annotations"`
3838
}
3939

4040
PoolConfigNodeConfigSource struct {
@@ -44,8 +44,44 @@ type (
4444
KubeletConfigKey string `yaml:"kubeletConfigKey" json:"kubeletConfigKey"`
4545
} `yaml:"configMap" json:"configMap"`
4646
}
47+
48+
PoolConfigNodeValueMap struct {
49+
entries *map[string]*string
50+
}
4751
)
4852

53+
func (valueMap *PoolConfigNodeValueMap) Entries() map[string]*string {
54+
var mapList map[string]*string
55+
56+
if valueMap.entries != nil {
57+
mapList = *valueMap.entries
58+
}
59+
60+
return mapList
61+
}
62+
63+
func (valueMap *PoolConfigNodeValueMap) UnmarshalYAML(unmarshal func(interface{}) error) error {
64+
mapList := map[string]*string{}
65+
err := unmarshal(&mapList)
66+
if err != nil {
67+
var stringList []string
68+
err := unmarshal(&stringList)
69+
if err != nil {
70+
return err
71+
}
72+
if len(stringList) > 0 {
73+
emptyVal := ""
74+
for _, val := range stringList {
75+
mapList[val] = &emptyVal
76+
}
77+
valueMap.entries = &mapList
78+
}
79+
} else {
80+
valueMap.entries = &mapList
81+
}
82+
return nil
83+
}
84+
4985
func (p *PoolConfig) IsMatchingNode(node *corev1.Node) (bool, error) {
5086
for num, selector := range p.Selector {
5187
// auto compile regexp
@@ -104,16 +140,22 @@ func (p *PoolConfig) IsMatchingNode(node *corev1.Node) (bool, error) {
104140
return true, nil
105141
}
106142

107-
func (p *PoolConfig) CreateJsonPatchSet() (patchSet *k8s.JsonPatchSet) {
143+
func (p *PoolConfig) CreateJsonPatchSet(node *corev1.Node) (patchSet *k8s.JsonPatchSet) {
108144
patchSet = k8s.NewJsonPatchSet()
109145

110-
if p.Node.Roles != nil {
111-
for _, role := range *p.Node.Roles {
112-
label := fmt.Sprintf("node-role.kubernetes.io/%s", role)
146+
for roleName, roleValue := range p.Node.Roles.Entries() {
147+
label := fmt.Sprintf("node-role.kubernetes.io/%s", roleName)
148+
if roleValue != nil {
149+
value := *roleValue
113150
patchSet.Add(k8s.JsonPatchString{
114151
Op: "replace",
115152
Path: fmt.Sprintf("/metadata/labels/%s", k8s.PatchPathEsacpe(label)),
116-
Value: "",
153+
Value: &value,
154+
})
155+
} else if _, labelExists := node.Labels[label]; labelExists {
156+
patchSet.Add(k8s.JsonPatchString{
157+
Op: "remove",
158+
Path: fmt.Sprintf("/metadata/labels/%s", k8s.PatchPathEsacpe(label)),
117159
})
118160
}
119161
}
@@ -126,22 +168,34 @@ func (p *PoolConfig) CreateJsonPatchSet() (patchSet *k8s.JsonPatchSet) {
126168
})
127169
}
128170

129-
if p.Node.Labels != nil {
130-
for name, value := range *p.Node.Labels {
171+
for labelName, labelValue := range p.Node.Labels.Entries() {
172+
if labelValue != nil {
173+
value := *labelValue
131174
patchSet.Add(k8s.JsonPatchString{
132175
Op: "replace",
133-
Path: fmt.Sprintf("/metadata/labels/%s", k8s.PatchPathEsacpe(name)),
134-
Value: value,
176+
Path: fmt.Sprintf("/metadata/labels/%s", k8s.PatchPathEsacpe(labelName)),
177+
Value: &value,
178+
})
179+
} else if _, labelExists := node.Labels[labelName]; labelExists {
180+
patchSet.Add(k8s.JsonPatchString{
181+
Op: "remove",
182+
Path: fmt.Sprintf("/metadata/labels/%s", k8s.PatchPathEsacpe(labelName)),
135183
})
136184
}
137185
}
138186

139-
if p.Node.Annotations != nil {
140-
for name, value := range *p.Node.Annotations {
187+
for annotationName, annotationValue := range p.Node.Annotations.Entries() {
188+
if annotationValue != nil {
189+
value := *annotationValue
141190
patchSet.Add(k8s.JsonPatchString{
142191
Op: "replace",
143-
Path: fmt.Sprintf("/metadata/annotations/%s", k8s.PatchPathEsacpe(name)),
144-
Value: value,
192+
Path: fmt.Sprintf("/metadata/annotations/%s", k8s.PatchPathEsacpe(annotationName)),
193+
Value: &value,
194+
})
195+
} else if _, labelExists := node.Annotations[annotationName]; labelExists {
196+
patchSet.Add(k8s.JsonPatchString{
197+
Op: "remove",
198+
Path: fmt.Sprintf("/metadata/annotations/%s", k8s.PatchPathEsacpe(annotationName)),
145199
})
146200
}
147201
}

deployment/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ data:
2020
labels:
2121
webdevops.io/testing: true
2222
annotations:
23-
webdevops.io/testing: 2
23+
webdevops.io/testing: null

example.yaml

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,73 @@
11
pools:
2-
- pool: linux
3-
continue: true
4-
selector:
5-
- path: "{.metadata.labels.kubernetes\\.io/os}"
6-
match: "linux"
7-
node:
8-
# sets the kubernetes node role
9-
roles: [linux]
2+
- pool: linux
3+
continue: true
4+
selector:
5+
- path: "{.metadata.labels.kubernetes\\.io/os}"
6+
match: "linux"
7+
node:
8+
# sets the kubernetes node role
9+
roles: [linux]
1010

11-
- pool: windows
12-
continue: true
13-
selector:
14-
- path: "{.metadata.labels.kubernetes\\.io/os}"
15-
match: "windows"
16-
node:
17-
# sets the kubernetes node role
18-
role: [windows]
11+
- pool: windows
12+
continue: true
13+
selector:
14+
- path: "{.metadata.labels.kubernetes\\.io/os}"
15+
match: "windows"
16+
node:
17+
# sets the kubernetes node role
18+
role: [windows]
1919

20-
- pool: agents
21-
selector:
22-
- path: "{.spec.providerID}"
23-
# simple match
24-
match: "azure:///subscriptions/d86bcf13-ddf7-45ea-82f1-6f656767a318/resourceGroups/mc_k8s_mblaschke_westeurope/providers/Microsoft.Compute/virtualMachineScaleSets/aks-agents-35471996-vmss/virtualMachines/30"
25-
node:
26-
# sets the kubernetes node role
27-
roles: [agent,foobar]
20+
- pool: agents
21+
selector:
22+
- path: "{.spec.providerID}"
23+
# simple match
24+
match: "azure:///subscriptions/d86bcf13-ddf7-45ea-82f1-6f656767a318/resourceGroups/mc_k8s_mblaschke_westeurope/providers/Microsoft.Compute/virtualMachineScaleSets/aks-agents-35471996-vmss/virtualMachines/30"
25+
node:
26+
# sets the kubernetes node role
27+
roles: [agent,foobar]
2828

29-
# dynamic kubelet configuration
30-
# see https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/
31-
#configSource:
32-
# configMap:
33-
# name: kubelet-config
34-
# namespace: kube-system
35-
# kubeletConfigKey: kubelet
29+
# dynamic kubelet configuration
30+
# see https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/
31+
#configSource:
32+
# configMap:
33+
# name: kubelet-config
34+
# namespace: kube-system
35+
# kubeletConfigKey: kubelet
3636

37-
# node labels
38-
labels:
39-
webdevops.io/testing: "true"
37+
# node labels
38+
labels:
39+
webdevops.io/testing: "true"
4040

41-
# node annotations
42-
annotations:
43-
webdevops.io/testing: 2
41+
# node annotations
42+
annotations:
43+
webdevops.io/testing: null
4444

45-
- pool: agents-regexp
46-
selector:
47-
- path: "{.spec.providerID}"
48-
# regexp match
49-
regexp: "^.+virtualMachineScaleSets\\/aks-agents-35471996-vmss\\/.+$"
50-
node:
51-
# sets the kubernetes node role
52-
roles: [agent,regexp]
45+
- pool: agents-regexp
46+
selector:
47+
- path: "{.spec.providerID}"
48+
# regexp match
49+
regexp: "^.+virtualMachineScaleSets\\/aks-agents-35471996-vmss\\/.+$"
50+
node:
51+
# sets the kubernetes node role
52+
roles:
53+
agent: ""
54+
regexp: ""
55+
linux: null # remove linux role
5356

54-
# dynamic kubelet configuration
55-
# see https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/
56-
#configSource:
57-
# configMap:
58-
# name: kubelet-config
59-
# namespace: kube-system
60-
# kubeletConfigKey: kubelet
57+
# dynamic kubelet configuration
58+
# see https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/
59+
#configSource:
60+
# configMap:
61+
# name: kubelet-config
62+
# namespace: kube-system
63+
# kubeletConfigKey: kubelet
6164

62-
# node labels
63-
labels:
64-
webdevops.io/testing: "regexp"
65+
# node labels
66+
labels:
67+
webdevops.io/testing: "regexp"
68+
webdevops.io/testing2: null # remove that annotation
6569

66-
# node annotations
67-
annotations:
68-
webdevops.io/testing: 3
70+
# node annotations
71+
annotations:
72+
webdevops.io/testing: "foobar"
73+
webdevops.io/testing2: null # remove that annotation

k8s/patch.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ type (
99
JsonPatch interface{}
1010

1111
JsonPatchString struct {
12-
JsonPatch
13-
Op string `json:"op"`
14-
Path string `json:"path"`
15-
Value string `json:"value"`
12+
JsonPatch `json:"-"`
13+
Op string `json:"op"`
14+
Path string `json:"path"`
15+
Value *string `json:"value,omitempty"`
1616
}
1717

1818
JsonPatchObject struct {

manager/manager.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func (m *KubePoolManager) applyNode(node *corev1.Node) {
161161
poolLogger.Infof("adding configuration from pool \"%s\" to node \"%s\"", poolConfig.Name, node.Name)
162162

163163
// create json patch
164-
patchSet := poolConfig.CreateJsonPatchSet()
164+
patchSet := poolConfig.CreateJsonPatchSet(node)
165165
nodePatchSets.AddSet(patchSet)
166166
poolNameList = append(poolNameList, poolConfig.Name)
167167
} else {
@@ -177,6 +177,7 @@ func (m *KubePoolManager) applyNode(node *corev1.Node) {
177177
contextLogger.Errorf("failed to create json patch: %v", patchErr)
178178
return
179179
}
180+
contextLogger.Debugf("apply patchset: %v", string(patchBytes))
180181

181182
if !m.Opts.DryRun {
182183
// patch node

0 commit comments

Comments
 (0)