@@ -17,11 +17,14 @@ limitations under the License.
17
17
package machine
18
18
19
19
import (
20
+ "fmt"
20
21
"testing"
22
+ "time"
21
23
22
24
. "github.com/onsi/gomega"
23
25
corev1 "k8s.io/api/core/v1"
24
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
+ "k8s.io/utils/pointer"
25
28
ctrl "sigs.k8s.io/controller-runtime"
26
29
"sigs.k8s.io/controller-runtime/pkg/client"
27
30
"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -31,6 +34,7 @@ import (
31
34
"sigs.k8s.io/cluster-api/controllers/noderefutil"
32
35
"sigs.k8s.io/cluster-api/controllers/remote"
33
36
"sigs.k8s.io/cluster-api/util"
37
+ "sigs.k8s.io/cluster-api/util/kubeconfig"
34
38
)
35
39
36
40
func TestGetNode (t * testing.T ) {
@@ -164,6 +168,200 @@ func TestGetNode(t *testing.T) {
164
168
}
165
169
}
166
170
171
+ func TestNodeLabelSync (t * testing.T ) {
172
+ defaultCluster := & clusterv1.Cluster {
173
+ ObjectMeta : metav1.ObjectMeta {
174
+ Name : "test-cluster" ,
175
+ Namespace : metav1 .NamespaceDefault ,
176
+ },
177
+ }
178
+
179
+ defaultMachine := clusterv1.Machine {
180
+ ObjectMeta : metav1.ObjectMeta {
181
+ Name : "machine-test" ,
182
+ Namespace : metav1 .NamespaceDefault ,
183
+ Labels : map [string ]string {
184
+ clusterv1 .MachineControlPlaneLabel : "" ,
185
+ },
186
+ },
187
+ Spec : clusterv1.MachineSpec {
188
+ ClusterName : defaultCluster .Name ,
189
+ Bootstrap : clusterv1.Bootstrap {
190
+ ConfigRef : & corev1.ObjectReference {
191
+ APIVersion : "bootstrap.cluster.x-k8s.io/v1beta1" ,
192
+ Kind : "GenericBootstrapConfig" ,
193
+ Name : "bootstrap-config1" ,
194
+ },
195
+ },
196
+ InfrastructureRef : corev1.ObjectReference {
197
+ APIVersion : "infrastructure.cluster.x-k8s.io/v1beta1" ,
198
+ Kind : "GenericInfrastructureMachine" ,
199
+ Name : "infra-config1" ,
200
+ },
201
+ },
202
+ }
203
+
204
+ t .Run ("Should sync node labels" , func (t * testing.T ) {
205
+ g := NewWithT (t )
206
+
207
+ ns , err := env .CreateNamespace (ctx , "test-node-label-sync" )
208
+ g .Expect (err ).ToNot (HaveOccurred ())
209
+ defer func () {
210
+ g .Expect (env .Cleanup (ctx , ns )).To (Succeed ())
211
+ }()
212
+
213
+ nodeProviderID := fmt .Sprintf ("test://%s" , util .RandomString (6 ))
214
+
215
+ cluster := defaultCluster .DeepCopy ()
216
+ cluster .Namespace = ns .Name
217
+
218
+ machine := defaultMachine .DeepCopy ()
219
+ machine .Namespace = ns .Name
220
+ machine .Spec .ProviderID = pointer .String (nodeProviderID )
221
+
222
+ // Set Machine labels.
223
+ machine .Labels = map [string ]string {}
224
+ // The expectation is that these labels will be synced to the Node.
225
+ managedMachineLabels := map [string ]string {
226
+ clusterv1 .NodeRoleLabelPrefix + "/anyRole" : "" ,
227
+
228
+ clusterv1 .ManagedNodeLabelDomain : "valueFromMachine" ,
229
+ "custom-prefix." + clusterv1 .ManagedNodeLabelDomain : "valueFromMachine" ,
230
+ clusterv1 .ManagedNodeLabelDomain + "/anything" : "valueFromMachine" ,
231
+ "custom-prefix." + clusterv1 .ManagedNodeLabelDomain + "/anything" : "valueFromMachine" ,
232
+
233
+ clusterv1 .NodeRestrictionLabelDomain : "valueFromMachine" ,
234
+ "custom-prefix." + clusterv1 .NodeRestrictionLabelDomain : "valueFromMachine" ,
235
+ clusterv1 .NodeRestrictionLabelDomain + "/anything" : "valueFromMachine" ,
236
+ "custom-prefix." + clusterv1 .NodeRestrictionLabelDomain + "/anything" : "valueFromMachine" ,
237
+ }
238
+ for k , v := range managedMachineLabels {
239
+ machine .Labels [k ] = v
240
+ }
241
+ // The expectation is that these labels will not be synced to the Node.
242
+ unmanagedMachineLabels := map [string ]string {
243
+ "foo" : "" ,
244
+ "bar" : "" ,
245
+ "company.xyz/node.cluster.x-k8s.io" : "not-managed" ,
246
+ "gpu-node.cluster.x-k8s.io" : "not-managed" ,
247
+ "company.xyz/node-restriction.kubernetes.io" : "not-managed" ,
248
+ "gpu-node-restriction.kubernetes.io" : "not-managed" ,
249
+ }
250
+ for k , v := range unmanagedMachineLabels {
251
+ machine .Labels [k ] = v
252
+ }
253
+
254
+ // Create Node.
255
+ node := & corev1.Node {
256
+ ObjectMeta : metav1.ObjectMeta {
257
+ GenerateName : "machine-test-node-" ,
258
+ },
259
+ Spec : corev1.NodeSpec {ProviderID : nodeProviderID },
260
+ }
261
+
262
+ // Set Node labels
263
+ // The expectation is that these labels will be overwritten by the labels
264
+ // from the Machine by the node label sync.
265
+ node .Labels = map [string ]string {}
266
+ managedNodeLabelsToBeOverWritten := map [string ]string {
267
+ clusterv1 .NodeRoleLabelPrefix + "/anyRole" : "valueFromNode" ,
268
+
269
+ clusterv1 .ManagedNodeLabelDomain : "valueFromNode" ,
270
+ "custom-prefix." + clusterv1 .ManagedNodeLabelDomain : "valueFromNode" ,
271
+ clusterv1 .ManagedNodeLabelDomain + "/anything" : "valueFromNode" ,
272
+ "custom-prefix." + clusterv1 .ManagedNodeLabelDomain + "/anything" : "valueFromNode" ,
273
+
274
+ clusterv1 .NodeRestrictionLabelDomain : "valueFromNode" ,
275
+ "custom-prefix." + clusterv1 .NodeRestrictionLabelDomain : "valueFromNode" ,
276
+ clusterv1 .NodeRestrictionLabelDomain + "/anything" : "valueFromNode" ,
277
+ "custom-prefix." + clusterv1 .NodeRestrictionLabelDomain + "/anything" : "valueFromNode" ,
278
+ }
279
+ for k , v := range managedNodeLabelsToBeOverWritten {
280
+ node .Labels [k ] = v
281
+ }
282
+ // The expectation is that these labels will be preserved by the node label sync.
283
+ unmanagedNodeLabelsToBePreserved := map [string ]string {
284
+ "node-role.kubernetes.io/control-plane" : "" ,
285
+ "label" : "valueFromNode" ,
286
+ }
287
+ for k , v := range unmanagedNodeLabelsToBePreserved {
288
+ node .Labels [k ] = v
289
+ }
290
+
291
+ g .Expect (env .Create (ctx , node )).To (Succeed ())
292
+ defer func () {
293
+ g .Expect (env .Cleanup (ctx , node )).To (Succeed ())
294
+ }()
295
+
296
+ g .Expect (env .Create (ctx , cluster )).To (Succeed ())
297
+ defaultKubeconfigSecret := kubeconfig .GenerateSecret (cluster , kubeconfig .FromEnvTestConfig (env .Config , cluster ))
298
+ g .Expect (env .Create (ctx , defaultKubeconfigSecret )).To (Succeed ())
299
+ g .Expect (env .Create (ctx , machine )).To (Succeed ())
300
+
301
+ // Validate that the right labels where synced to the Node.
302
+ g .Eventually (func (g Gomega ) bool {
303
+ if err := env .Get (ctx , client .ObjectKeyFromObject (node ), node ); err != nil {
304
+ return false
305
+ }
306
+
307
+ // Managed Machine Labels should have been synced to the Node.
308
+ for k , v := range managedMachineLabels {
309
+ g .Expect (node .Labels ).To (HaveKeyWithValue (k , v ))
310
+ }
311
+ // Unmanaged Machine labels should not have been synced to the Node.
312
+ for k , v := range unmanagedMachineLabels {
313
+ g .Expect (node .Labels ).ToNot (HaveKeyWithValue (k , v ))
314
+ }
315
+
316
+ // Pre-existing managed Node labels should have been overwritten on the Node.
317
+ for k , v := range managedNodeLabelsToBeOverWritten {
318
+ g .Expect (node .Labels ).ToNot (HaveKeyWithValue (k , v ))
319
+ }
320
+ // Pre-existing unmanaged Node labels should have been preserved on the Node.
321
+ for k , v := range unmanagedNodeLabelsToBePreserved {
322
+ g .Expect (node .Labels ).To (HaveKeyWithValue (k , v ))
323
+ }
324
+
325
+ return true
326
+ }, 10 * time .Second ).Should (BeTrue ())
327
+
328
+ // Remove managed labels from Machine.
329
+ modifiedMachine := machine .DeepCopy ()
330
+ for k := range managedMachineLabels {
331
+ delete (modifiedMachine .Labels , k )
332
+ }
333
+ g .Expect (env .Patch (ctx , modifiedMachine , client .MergeFrom (machine ))).To (Succeed ())
334
+
335
+ // Validate that managed Machine labels were removed from the Node and all others are not changed.
336
+ g .Eventually (func (g Gomega ) bool {
337
+ if err := env .Get (ctx , client .ObjectKeyFromObject (node ), node ); err != nil {
338
+ return false
339
+ }
340
+
341
+ // Managed Machine Labels should have been removed from the Node now.
342
+ for k , v := range managedMachineLabels {
343
+ g .Expect (node .Labels ).ToNot (HaveKeyWithValue (k , v ))
344
+ }
345
+ // Unmanaged Machine labels should not have been synced at all to the Node.
346
+ for k , v := range unmanagedMachineLabels {
347
+ g .Expect (node .Labels ).ToNot (HaveKeyWithValue (k , v ))
348
+ }
349
+
350
+ // Pre-existing managed Node labels have been overwritten earlier by the managed Machine labels.
351
+ // Now that the managed Machine labels have been removed, they should still not exist.
352
+ for k , v := range managedNodeLabelsToBeOverWritten {
353
+ g .Expect (node .Labels ).ToNot (HaveKeyWithValue (k , v ))
354
+ }
355
+ // Pre-existing unmanaged Node labels should have been preserved on the Node.
356
+ for k , v := range unmanagedNodeLabelsToBePreserved {
357
+ g .Expect (node .Labels ).To (HaveKeyWithValue (k , v ))
358
+ }
359
+
360
+ return true
361
+ }, 10 * time .Second ).Should (BeTrue ())
362
+ })
363
+ }
364
+
167
365
func TestSummarizeNodeConditions (t * testing.T ) {
168
366
testCases := []struct {
169
367
name string
@@ -230,11 +428,19 @@ func TestSummarizeNodeConditions(t *testing.T) {
230
428
231
429
func TestGetManagedLabels (t * testing.T ) {
232
430
// Create managedLabels map from known managed prefixes.
233
- managedLabels := map [string ]string {}
234
- managedLabels [clusterv1 .ManagedNodeLabelDomain ] = ""
235
- managedLabels ["custom-prefix." + clusterv1 .NodeRestrictionLabelDomain ] = ""
236
- managedLabels ["custom-prefix." + clusterv1 .NodeRestrictionLabelDomain + "/anything" ] = ""
237
- managedLabels [clusterv1 .NodeRoleLabelPrefix + "/anything" ] = ""
431
+ managedLabels := map [string ]string {
432
+ clusterv1 .NodeRoleLabelPrefix + "/anyRole" : "" ,
433
+
434
+ clusterv1 .ManagedNodeLabelDomain : "" ,
435
+ "custom-prefix." + clusterv1 .ManagedNodeLabelDomain : "" ,
436
+ clusterv1 .ManagedNodeLabelDomain + "/anything" : "" ,
437
+ "custom-prefix." + clusterv1 .ManagedNodeLabelDomain + "/anything" : "" ,
438
+
439
+ clusterv1 .NodeRestrictionLabelDomain : "" ,
440
+ "custom-prefix." + clusterv1 .NodeRestrictionLabelDomain : "" ,
441
+ clusterv1 .NodeRestrictionLabelDomain + "/anything" : "" ,
442
+ "custom-prefix." + clusterv1 .NodeRestrictionLabelDomain + "/anything" : "" ,
443
+ }
238
444
239
445
// Append arbitrary labels.
240
446
allLabels := map [string ]string {
0 commit comments