sigs.k8s.io/cluster-api@v1.6.3/controlplane/kubeadm/internal/filters_test.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package internal 18 19 import ( 20 "testing" 21 22 . "github.com/onsi/gomega" 23 corev1 "k8s.io/api/core/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 26 27 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 28 bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" 29 controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" 30 ) 31 32 func TestMatchClusterConfiguration(t *testing.T) { 33 t.Run("machine without the ClusterConfiguration annotation should match (not enough information to make a decision)", func(t *testing.T) { 34 g := NewWithT(t) 35 kcp := &controlplanev1.KubeadmControlPlane{} 36 m := &clusterv1.Machine{} 37 g.Expect(matchClusterConfiguration(kcp, m)).To(BeTrue()) 38 }) 39 t.Run("machine without an invalid ClusterConfiguration annotation should not match (only solution is to rollout)", func(t *testing.T) { 40 g := NewWithT(t) 41 kcp := &controlplanev1.KubeadmControlPlane{} 42 m := &clusterv1.Machine{ 43 ObjectMeta: metav1.ObjectMeta{ 44 Annotations: map[string]string{ 45 controlplanev1.KubeadmClusterConfigurationAnnotation: "$|^^_", 46 }, 47 }, 48 } 49 g.Expect(matchClusterConfiguration(kcp, m)).To(BeFalse()) 50 }) 51 t.Run("Return true if cluster configuration matches", func(t *testing.T) { 52 g := NewWithT(t) 53 kcp := &controlplanev1.KubeadmControlPlane{ 54 Spec: controlplanev1.KubeadmControlPlaneSpec{ 55 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 56 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{ 57 ClusterName: "foo", 58 }, 59 }, 60 }, 61 } 62 m := &clusterv1.Machine{ 63 ObjectMeta: metav1.ObjectMeta{ 64 Annotations: map[string]string{ 65 controlplanev1.KubeadmClusterConfigurationAnnotation: "{\n \"clusterName\": \"foo\"\n}", 66 }, 67 }, 68 } 69 g.Expect(matchClusterConfiguration(kcp, m)).To(BeTrue()) 70 }) 71 t.Run("Return false if cluster configuration does not match", func(t *testing.T) { 72 g := NewWithT(t) 73 kcp := &controlplanev1.KubeadmControlPlane{ 74 Spec: controlplanev1.KubeadmControlPlaneSpec{ 75 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 76 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{ 77 ClusterName: "foo", 78 }, 79 }, 80 }, 81 } 82 m := &clusterv1.Machine{ 83 ObjectMeta: metav1.ObjectMeta{ 84 Annotations: map[string]string{ 85 controlplanev1.KubeadmClusterConfigurationAnnotation: "{\n \"clusterName\": \"bar\"\n}", 86 }, 87 }, 88 } 89 g.Expect(matchClusterConfiguration(kcp, m)).To(BeFalse()) 90 }) 91 t.Run("Return true if cluster configuration is nil (special case)", func(t *testing.T) { 92 g := NewWithT(t) 93 kcp := &controlplanev1.KubeadmControlPlane{ 94 Spec: controlplanev1.KubeadmControlPlaneSpec{ 95 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{}, 96 }, 97 } 98 m := &clusterv1.Machine{ 99 ObjectMeta: metav1.ObjectMeta{ 100 Annotations: map[string]string{ 101 controlplanev1.KubeadmClusterConfigurationAnnotation: "null", 102 }, 103 }, 104 } 105 g.Expect(matchClusterConfiguration(kcp, m)).To(BeTrue()) 106 }) 107 } 108 109 func TestGetAdjustedKcpConfig(t *testing.T) { 110 t.Run("if the machine is the first control plane, kcp config should get InitConfiguration", func(t *testing.T) { 111 g := NewWithT(t) 112 kcp := &controlplanev1.KubeadmControlPlane{ 113 Spec: controlplanev1.KubeadmControlPlaneSpec{ 114 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 115 InitConfiguration: &bootstrapv1.InitConfiguration{}, 116 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 117 }, 118 }, 119 } 120 machineConfig := &bootstrapv1.KubeadmConfig{ 121 Spec: bootstrapv1.KubeadmConfigSpec{ 122 InitConfiguration: &bootstrapv1.InitConfiguration{}, // first control-plane 123 }, 124 } 125 kcpConfig := getAdjustedKcpConfig(kcp, machineConfig) 126 g.Expect(kcpConfig.InitConfiguration).ToNot(BeNil()) 127 g.Expect(kcpConfig.JoinConfiguration).To(BeNil()) 128 }) 129 t.Run("if the machine is a joining control plane, kcp config should get JoinConfiguration", func(t *testing.T) { 130 g := NewWithT(t) 131 kcp := &controlplanev1.KubeadmControlPlane{ 132 Spec: controlplanev1.KubeadmControlPlaneSpec{ 133 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 134 InitConfiguration: &bootstrapv1.InitConfiguration{}, 135 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 136 }, 137 }, 138 } 139 machineConfig := &bootstrapv1.KubeadmConfig{ 140 Spec: bootstrapv1.KubeadmConfigSpec{ 141 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, // joining control-plane 142 }, 143 } 144 kcpConfig := getAdjustedKcpConfig(kcp, machineConfig) 145 g.Expect(kcpConfig.InitConfiguration).To(BeNil()) 146 g.Expect(kcpConfig.JoinConfiguration).ToNot(BeNil()) 147 }) 148 } 149 150 func TestCleanupConfigFields(t *testing.T) { 151 t.Run("ClusterConfiguration gets removed from KcpConfig and MachineConfig", func(t *testing.T) { 152 g := NewWithT(t) 153 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 154 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 155 } 156 machineConfig := &bootstrapv1.KubeadmConfig{ 157 Spec: bootstrapv1.KubeadmConfigSpec{ 158 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 159 }, 160 } 161 cleanupConfigFields(kcpConfig, machineConfig) 162 g.Expect(kcpConfig.ClusterConfiguration).To(BeNil()) 163 g.Expect(machineConfig.Spec.ClusterConfiguration).To(BeNil()) 164 }) 165 t.Run("JoinConfiguration gets removed from MachineConfig if it was not derived by KCPConfig", func(t *testing.T) { 166 g := NewWithT(t) 167 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 168 JoinConfiguration: nil, // KCP not providing a JoinConfiguration 169 } 170 machineConfig := &bootstrapv1.KubeadmConfig{ 171 Spec: bootstrapv1.KubeadmConfigSpec{ 172 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, // Machine gets a default JoinConfiguration from CABPK 173 }, 174 } 175 cleanupConfigFields(kcpConfig, machineConfig) 176 g.Expect(kcpConfig.JoinConfiguration).To(BeNil()) 177 g.Expect(machineConfig.Spec.JoinConfiguration).To(BeNil()) 178 }) 179 t.Run("JoinConfiguration.Discovery gets removed because it is not relevant for compare", func(t *testing.T) { 180 g := NewWithT(t) 181 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 182 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 183 Discovery: bootstrapv1.Discovery{TLSBootstrapToken: "aaa"}, 184 }, 185 } 186 machineConfig := &bootstrapv1.KubeadmConfig{ 187 Spec: bootstrapv1.KubeadmConfigSpec{ 188 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 189 Discovery: bootstrapv1.Discovery{TLSBootstrapToken: "aaa"}, 190 }, 191 }, 192 } 193 cleanupConfigFields(kcpConfig, machineConfig) 194 g.Expect(kcpConfig.JoinConfiguration.Discovery).To(BeComparableTo(bootstrapv1.Discovery{})) 195 g.Expect(machineConfig.Spec.JoinConfiguration.Discovery).To(BeComparableTo(bootstrapv1.Discovery{})) 196 }) 197 t.Run("JoinConfiguration.ControlPlane gets removed from MachineConfig if it was not derived by KCPConfig", func(t *testing.T) { 198 g := NewWithT(t) 199 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 200 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 201 ControlPlane: nil, // Control plane configuration missing in KCP 202 }, 203 } 204 machineConfig := &bootstrapv1.KubeadmConfig{ 205 Spec: bootstrapv1.KubeadmConfigSpec{ 206 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 207 ControlPlane: &bootstrapv1.JoinControlPlane{}, // Machine gets a default JoinConfiguration.ControlPlane from CABPK 208 }, 209 }, 210 } 211 cleanupConfigFields(kcpConfig, machineConfig) 212 g.Expect(kcpConfig.JoinConfiguration).ToNot(BeNil()) 213 g.Expect(machineConfig.Spec.JoinConfiguration.ControlPlane).To(BeNil()) 214 }) 215 t.Run("JoinConfiguration.NodeRegistrationOptions gets removed from MachineConfig if it was not derived by KCPConfig", func(t *testing.T) { 216 g := NewWithT(t) 217 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 218 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 219 NodeRegistration: bootstrapv1.NodeRegistrationOptions{}, // NodeRegistrationOptions configuration missing in KCP 220 }, 221 } 222 machineConfig := &bootstrapv1.KubeadmConfig{ 223 Spec: bootstrapv1.KubeadmConfigSpec{ 224 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 225 NodeRegistration: bootstrapv1.NodeRegistrationOptions{Name: "test"}, // Machine gets a some JoinConfiguration.NodeRegistrationOptions 226 }, 227 }, 228 } 229 cleanupConfigFields(kcpConfig, machineConfig) 230 g.Expect(kcpConfig.JoinConfiguration).ToNot(BeNil()) 231 g.Expect(machineConfig.Spec.JoinConfiguration.NodeRegistration).To(BeComparableTo(bootstrapv1.NodeRegistrationOptions{})) 232 }) 233 t.Run("InitConfiguration.TypeMeta gets removed from MachineConfig", func(t *testing.T) { 234 g := NewWithT(t) 235 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 236 InitConfiguration: &bootstrapv1.InitConfiguration{}, 237 } 238 machineConfig := &bootstrapv1.KubeadmConfig{ 239 Spec: bootstrapv1.KubeadmConfigSpec{ 240 InitConfiguration: &bootstrapv1.InitConfiguration{ 241 TypeMeta: metav1.TypeMeta{ 242 Kind: "JoinConfiguration", 243 APIVersion: bootstrapv1.GroupVersion.String(), 244 }, 245 }, 246 }, 247 } 248 cleanupConfigFields(kcpConfig, machineConfig) 249 g.Expect(kcpConfig.InitConfiguration).ToNot(BeNil()) 250 g.Expect(machineConfig.Spec.InitConfiguration.TypeMeta).To(BeComparableTo(metav1.TypeMeta{})) 251 }) 252 t.Run("JoinConfiguration.TypeMeta gets removed from MachineConfig", func(t *testing.T) { 253 g := NewWithT(t) 254 kcpConfig := &bootstrapv1.KubeadmConfigSpec{ 255 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 256 } 257 machineConfig := &bootstrapv1.KubeadmConfig{ 258 Spec: bootstrapv1.KubeadmConfigSpec{ 259 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 260 TypeMeta: metav1.TypeMeta{ 261 Kind: "JoinConfiguration", 262 APIVersion: bootstrapv1.GroupVersion.String(), 263 }, 264 }, 265 }, 266 } 267 cleanupConfigFields(kcpConfig, machineConfig) 268 g.Expect(kcpConfig.JoinConfiguration).ToNot(BeNil()) 269 g.Expect(machineConfig.Spec.JoinConfiguration.TypeMeta).To(BeComparableTo(metav1.TypeMeta{})) 270 }) 271 } 272 273 func TestMatchInitOrJoinConfiguration(t *testing.T) { 274 t.Run("returns true if the machine does not have a bootstrap config", func(t *testing.T) { 275 g := NewWithT(t) 276 kcp := &controlplanev1.KubeadmControlPlane{} 277 g.Expect(matchInitOrJoinConfiguration(nil, kcp)).To(BeTrue()) 278 }) 279 t.Run("returns true if the there are problems reading the bootstrap config", func(t *testing.T) { 280 g := NewWithT(t) 281 kcp := &controlplanev1.KubeadmControlPlane{} 282 g.Expect(matchInitOrJoinConfiguration(nil, kcp)).To(BeTrue()) 283 }) 284 t.Run("returns true if one format is empty and the other one cloud-config", func(t *testing.T) { 285 g := NewWithT(t) 286 kcp := &controlplanev1.KubeadmControlPlane{ 287 Spec: controlplanev1.KubeadmControlPlaneSpec{ 288 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 289 Format: bootstrapv1.CloudConfig, 290 }, 291 }, 292 } 293 m := &clusterv1.Machine{ 294 TypeMeta: metav1.TypeMeta{ 295 Kind: "KubeadmConfig", 296 APIVersion: clusterv1.GroupVersion.String(), 297 }, 298 ObjectMeta: metav1.ObjectMeta{ 299 Namespace: "default", 300 Name: "test", 301 }, 302 Spec: clusterv1.MachineSpec{ 303 Bootstrap: clusterv1.Bootstrap{ 304 ConfigRef: &corev1.ObjectReference{ 305 Kind: "KubeadmConfig", 306 Namespace: "default", 307 Name: "test", 308 APIVersion: bootstrapv1.GroupVersion.String(), 309 }, 310 }, 311 }, 312 } 313 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 314 m.Name: { 315 TypeMeta: metav1.TypeMeta{ 316 Kind: "KubeadmConfig", 317 APIVersion: bootstrapv1.GroupVersion.String(), 318 }, 319 ObjectMeta: metav1.ObjectMeta{ 320 Namespace: "default", 321 Name: "test", 322 }, 323 Spec: bootstrapv1.KubeadmConfigSpec{ 324 Format: "", 325 }, 326 }, 327 } 328 g.Expect(matchInitOrJoinConfiguration(machineConfigs[m.Name], kcp)).To(BeTrue()) 329 }) 330 t.Run("returns true if InitConfiguration is equal", func(t *testing.T) { 331 g := NewWithT(t) 332 kcp := &controlplanev1.KubeadmControlPlane{ 333 Spec: controlplanev1.KubeadmControlPlaneSpec{ 334 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 335 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 336 InitConfiguration: &bootstrapv1.InitConfiguration{}, 337 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 338 }, 339 }, 340 } 341 m := &clusterv1.Machine{ 342 TypeMeta: metav1.TypeMeta{ 343 Kind: "KubeadmConfig", 344 APIVersion: clusterv1.GroupVersion.String(), 345 }, 346 ObjectMeta: metav1.ObjectMeta{ 347 Namespace: "default", 348 Name: "test", 349 }, 350 Spec: clusterv1.MachineSpec{ 351 Bootstrap: clusterv1.Bootstrap{ 352 ConfigRef: &corev1.ObjectReference{ 353 Kind: "KubeadmConfig", 354 Namespace: "default", 355 Name: "test", 356 APIVersion: bootstrapv1.GroupVersion.String(), 357 }, 358 }, 359 }, 360 } 361 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 362 m.Name: { 363 TypeMeta: metav1.TypeMeta{ 364 Kind: "KubeadmConfig", 365 APIVersion: bootstrapv1.GroupVersion.String(), 366 }, 367 ObjectMeta: metav1.ObjectMeta{ 368 Namespace: "default", 369 Name: "test", 370 }, 371 Spec: bootstrapv1.KubeadmConfigSpec{ 372 InitConfiguration: &bootstrapv1.InitConfiguration{}, 373 }, 374 }, 375 } 376 g.Expect(matchInitOrJoinConfiguration(machineConfigs[m.Name], kcp)).To(BeTrue()) 377 }) 378 t.Run("returns false if InitConfiguration is NOT equal", func(t *testing.T) { 379 g := NewWithT(t) 380 kcp := &controlplanev1.KubeadmControlPlane{ 381 Spec: controlplanev1.KubeadmControlPlaneSpec{ 382 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 383 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 384 InitConfiguration: &bootstrapv1.InitConfiguration{ 385 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 386 Name: "A new name", // This is a change 387 }, 388 }, 389 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 390 }, 391 }, 392 } 393 m := &clusterv1.Machine{ 394 TypeMeta: metav1.TypeMeta{ 395 Kind: "KubeadmConfig", 396 APIVersion: clusterv1.GroupVersion.String(), 397 }, 398 ObjectMeta: metav1.ObjectMeta{ 399 Namespace: "default", 400 Name: "test", 401 }, 402 Spec: clusterv1.MachineSpec{ 403 Bootstrap: clusterv1.Bootstrap{ 404 ConfigRef: &corev1.ObjectReference{ 405 Kind: "KubeadmConfig", 406 Namespace: "default", 407 Name: "test", 408 APIVersion: bootstrapv1.GroupVersion.String(), 409 }, 410 }, 411 }, 412 } 413 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 414 m.Name: { 415 TypeMeta: metav1.TypeMeta{ 416 Kind: "KubeadmConfig", 417 APIVersion: bootstrapv1.GroupVersion.String(), 418 }, 419 ObjectMeta: metav1.ObjectMeta{ 420 Namespace: "default", 421 Name: "test", 422 }, 423 Spec: bootstrapv1.KubeadmConfigSpec{ 424 InitConfiguration: &bootstrapv1.InitConfiguration{}, 425 }, 426 }, 427 } 428 g.Expect(matchInitOrJoinConfiguration(machineConfigs[m.Name], kcp)).To(BeFalse()) 429 }) 430 t.Run("returns true if JoinConfiguration is equal", func(t *testing.T) { 431 g := NewWithT(t) 432 kcp := &controlplanev1.KubeadmControlPlane{ 433 Spec: controlplanev1.KubeadmControlPlaneSpec{ 434 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 435 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 436 InitConfiguration: &bootstrapv1.InitConfiguration{}, 437 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 438 }, 439 }, 440 } 441 m := &clusterv1.Machine{ 442 TypeMeta: metav1.TypeMeta{ 443 Kind: "KubeadmConfig", 444 APIVersion: clusterv1.GroupVersion.String(), 445 }, 446 ObjectMeta: metav1.ObjectMeta{ 447 Namespace: "default", 448 Name: "test", 449 }, 450 Spec: clusterv1.MachineSpec{ 451 Bootstrap: clusterv1.Bootstrap{ 452 ConfigRef: &corev1.ObjectReference{ 453 Kind: "KubeadmConfig", 454 Namespace: "default", 455 Name: "test", 456 APIVersion: bootstrapv1.GroupVersion.String(), 457 }, 458 }, 459 }, 460 } 461 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 462 m.Name: { 463 TypeMeta: metav1.TypeMeta{ 464 Kind: "KubeadmConfig", 465 APIVersion: bootstrapv1.GroupVersion.String(), 466 }, 467 ObjectMeta: metav1.ObjectMeta{ 468 Namespace: "default", 469 Name: "test", 470 }, 471 Spec: bootstrapv1.KubeadmConfigSpec{ 472 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 473 }, 474 }, 475 } 476 g.Expect(matchInitOrJoinConfiguration(machineConfigs[m.Name], kcp)).To(BeTrue()) 477 }) 478 t.Run("returns false if JoinConfiguration is NOT equal", func(t *testing.T) { 479 g := NewWithT(t) 480 kcp := &controlplanev1.KubeadmControlPlane{ 481 Spec: controlplanev1.KubeadmControlPlaneSpec{ 482 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 483 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 484 InitConfiguration: &bootstrapv1.InitConfiguration{}, 485 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 486 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 487 Name: "A new name", // This is a change 488 }, 489 }, 490 }, 491 }, 492 } 493 m := &clusterv1.Machine{ 494 TypeMeta: metav1.TypeMeta{ 495 Kind: "KubeadmConfig", 496 APIVersion: clusterv1.GroupVersion.String(), 497 }, 498 ObjectMeta: metav1.ObjectMeta{ 499 Namespace: "default", 500 Name: "test", 501 }, 502 Spec: clusterv1.MachineSpec{ 503 Bootstrap: clusterv1.Bootstrap{ 504 ConfigRef: &corev1.ObjectReference{ 505 Kind: "KubeadmConfig", 506 Namespace: "default", 507 Name: "test", 508 APIVersion: bootstrapv1.GroupVersion.String(), 509 }, 510 }, 511 }, 512 } 513 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 514 m.Name: { 515 TypeMeta: metav1.TypeMeta{ 516 Kind: "KubeadmConfig", 517 APIVersion: bootstrapv1.GroupVersion.String(), 518 }, 519 ObjectMeta: metav1.ObjectMeta{ 520 Namespace: "default", 521 Name: "test", 522 }, 523 Spec: bootstrapv1.KubeadmConfigSpec{ 524 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 525 }, 526 }, 527 } 528 g.Expect(matchInitOrJoinConfiguration(machineConfigs[m.Name], kcp)).To(BeFalse()) 529 }) 530 t.Run("returns false if some other configurations are not equal", func(t *testing.T) { 531 g := NewWithT(t) 532 kcp := &controlplanev1.KubeadmControlPlane{ 533 Spec: controlplanev1.KubeadmControlPlaneSpec{ 534 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 535 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 536 InitConfiguration: &bootstrapv1.InitConfiguration{}, 537 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 538 Files: []bootstrapv1.File{}, // This is a change 539 }, 540 }, 541 } 542 m := &clusterv1.Machine{ 543 TypeMeta: metav1.TypeMeta{ 544 Kind: "KubeadmConfig", 545 APIVersion: clusterv1.GroupVersion.String(), 546 }, 547 ObjectMeta: metav1.ObjectMeta{ 548 Namespace: "default", 549 Name: "test", 550 }, 551 Spec: clusterv1.MachineSpec{ 552 Bootstrap: clusterv1.Bootstrap{ 553 ConfigRef: &corev1.ObjectReference{ 554 Kind: "KubeadmConfig", 555 Namespace: "default", 556 Name: "test", 557 APIVersion: bootstrapv1.GroupVersion.String(), 558 }, 559 }, 560 }, 561 } 562 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 563 m.Name: { 564 TypeMeta: metav1.TypeMeta{ 565 Kind: "KubeadmConfig", 566 APIVersion: bootstrapv1.GroupVersion.String(), 567 }, 568 ObjectMeta: metav1.ObjectMeta{ 569 Namespace: "default", 570 Name: "test", 571 }, 572 Spec: bootstrapv1.KubeadmConfigSpec{ 573 InitConfiguration: &bootstrapv1.InitConfiguration{}, 574 }, 575 }, 576 } 577 g.Expect(matchInitOrJoinConfiguration(machineConfigs[m.Name], kcp)).To(BeFalse()) 578 }) 579 } 580 581 func TestMatchesKubeadmBootstrapConfig(t *testing.T) { 582 t.Run("returns true if ClusterConfiguration is equal", func(t *testing.T) { 583 g := NewWithT(t) 584 kcp := &controlplanev1.KubeadmControlPlane{ 585 Spec: controlplanev1.KubeadmControlPlaneSpec{ 586 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 587 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{ 588 ClusterName: "foo", 589 }, 590 }, 591 }, 592 } 593 m := &clusterv1.Machine{ 594 ObjectMeta: metav1.ObjectMeta{ 595 Annotations: map[string]string{ 596 controlplanev1.KubeadmClusterConfigurationAnnotation: "{\n \"clusterName\": \"foo\"\n}", 597 }, 598 }, 599 } 600 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 601 m.Name: {}, 602 } 603 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 604 g.Expect(match).To(BeTrue()) 605 g.Expect(reason).To(BeEmpty()) 606 }) 607 t.Run("returns false if ClusterConfiguration is NOT equal", func(t *testing.T) { 608 g := NewWithT(t) 609 kcp := &controlplanev1.KubeadmControlPlane{ 610 Spec: controlplanev1.KubeadmControlPlaneSpec{ 611 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 612 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{ 613 ClusterName: "foo", 614 }, 615 }, 616 }, 617 } 618 m := &clusterv1.Machine{ 619 ObjectMeta: metav1.ObjectMeta{ 620 Annotations: map[string]string{ 621 controlplanev1.KubeadmClusterConfigurationAnnotation: "{\n \"clusterName\": \"bar\"\n}", 622 }, 623 }, 624 } 625 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 626 m.Name: {}, 627 } 628 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 629 g.Expect(match).To(BeFalse()) 630 g.Expect(reason).To(Equal("Machine ClusterConfiguration is outdated")) 631 }) 632 t.Run("returns true if InitConfiguration is equal", func(t *testing.T) { 633 g := NewWithT(t) 634 kcp := &controlplanev1.KubeadmControlPlane{ 635 Spec: controlplanev1.KubeadmControlPlaneSpec{ 636 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 637 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 638 InitConfiguration: &bootstrapv1.InitConfiguration{}, 639 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 640 }, 641 }, 642 } 643 m := &clusterv1.Machine{ 644 TypeMeta: metav1.TypeMeta{ 645 Kind: "KubeadmConfig", 646 APIVersion: clusterv1.GroupVersion.String(), 647 }, 648 ObjectMeta: metav1.ObjectMeta{ 649 Namespace: "default", 650 Name: "test", 651 }, 652 Spec: clusterv1.MachineSpec{ 653 Bootstrap: clusterv1.Bootstrap{ 654 ConfigRef: &corev1.ObjectReference{ 655 Kind: "KubeadmConfig", 656 Namespace: "default", 657 Name: "test", 658 APIVersion: bootstrapv1.GroupVersion.String(), 659 }, 660 }, 661 }, 662 } 663 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 664 m.Name: { 665 TypeMeta: metav1.TypeMeta{ 666 Kind: "KubeadmConfig", 667 APIVersion: bootstrapv1.GroupVersion.String(), 668 }, 669 ObjectMeta: metav1.ObjectMeta{ 670 Namespace: "default", 671 Name: "test", 672 }, 673 Spec: bootstrapv1.KubeadmConfigSpec{ 674 InitConfiguration: &bootstrapv1.InitConfiguration{}, 675 }, 676 }, 677 } 678 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 679 g.Expect(match).To(BeTrue()) 680 g.Expect(reason).To(BeEmpty()) 681 }) 682 t.Run("returns false if InitConfiguration is NOT equal", func(t *testing.T) { 683 g := NewWithT(t) 684 kcp := &controlplanev1.KubeadmControlPlane{ 685 Spec: controlplanev1.KubeadmControlPlaneSpec{ 686 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 687 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 688 InitConfiguration: &bootstrapv1.InitConfiguration{ 689 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 690 Name: "foo", // This is a change 691 }, 692 }, 693 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 694 }, 695 }, 696 } 697 m := &clusterv1.Machine{ 698 TypeMeta: metav1.TypeMeta{ 699 Kind: "KubeadmConfig", 700 APIVersion: clusterv1.GroupVersion.String(), 701 }, 702 ObjectMeta: metav1.ObjectMeta{ 703 Namespace: "default", 704 Name: "test", 705 }, 706 Spec: clusterv1.MachineSpec{ 707 Bootstrap: clusterv1.Bootstrap{ 708 ConfigRef: &corev1.ObjectReference{ 709 Kind: "KubeadmConfig", 710 Namespace: "default", 711 Name: "test", 712 APIVersion: bootstrapv1.GroupVersion.String(), 713 }, 714 }, 715 }, 716 } 717 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 718 m.Name: { 719 TypeMeta: metav1.TypeMeta{ 720 Kind: "KubeadmConfig", 721 APIVersion: bootstrapv1.GroupVersion.String(), 722 }, 723 ObjectMeta: metav1.ObjectMeta{ 724 Namespace: "default", 725 Name: "test", 726 }, 727 Spec: bootstrapv1.KubeadmConfigSpec{ 728 InitConfiguration: &bootstrapv1.InitConfiguration{}, 729 }, 730 }, 731 } 732 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 733 g.Expect(match).To(BeFalse()) 734 g.Expect(reason).To(Equal("Machine InitConfiguration or JoinConfiguration are outdated")) 735 }) 736 t.Run("returns true if JoinConfiguration is equal", func(t *testing.T) { 737 g := NewWithT(t) 738 kcp := &controlplanev1.KubeadmControlPlane{ 739 Spec: controlplanev1.KubeadmControlPlaneSpec{ 740 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 741 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 742 InitConfiguration: &bootstrapv1.InitConfiguration{}, 743 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 744 }, 745 }, 746 } 747 m := &clusterv1.Machine{ 748 TypeMeta: metav1.TypeMeta{ 749 Kind: "KubeadmConfig", 750 APIVersion: clusterv1.GroupVersion.String(), 751 }, 752 ObjectMeta: metav1.ObjectMeta{ 753 Namespace: "default", 754 Name: "test", 755 }, 756 Spec: clusterv1.MachineSpec{ 757 Bootstrap: clusterv1.Bootstrap{ 758 ConfigRef: &corev1.ObjectReference{ 759 Kind: "KubeadmConfig", 760 Namespace: "default", 761 Name: "test", 762 APIVersion: bootstrapv1.GroupVersion.String(), 763 }, 764 }, 765 }, 766 } 767 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 768 m.Name: { 769 TypeMeta: metav1.TypeMeta{ 770 Kind: "KubeadmConfig", 771 APIVersion: bootstrapv1.GroupVersion.String(), 772 }, 773 ObjectMeta: metav1.ObjectMeta{ 774 Namespace: "default", 775 Name: "test", 776 }, 777 Spec: bootstrapv1.KubeadmConfigSpec{ 778 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 779 }, 780 }, 781 } 782 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 783 g.Expect(match).To(BeTrue()) 784 g.Expect(reason).To(BeEmpty()) 785 }) 786 t.Run("returns false if JoinConfiguration is NOT equal", func(t *testing.T) { 787 g := NewWithT(t) 788 kcp := &controlplanev1.KubeadmControlPlane{ 789 Spec: controlplanev1.KubeadmControlPlaneSpec{ 790 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 791 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 792 InitConfiguration: &bootstrapv1.InitConfiguration{}, 793 JoinConfiguration: &bootstrapv1.JoinConfiguration{ 794 NodeRegistration: bootstrapv1.NodeRegistrationOptions{ 795 Name: "foo", // This is a change 796 }, 797 }, 798 }, 799 }, 800 } 801 m := &clusterv1.Machine{ 802 TypeMeta: metav1.TypeMeta{ 803 Kind: "KubeadmConfig", 804 APIVersion: clusterv1.GroupVersion.String(), 805 }, 806 ObjectMeta: metav1.ObjectMeta{ 807 Namespace: "default", 808 Name: "test", 809 }, 810 Spec: clusterv1.MachineSpec{ 811 Bootstrap: clusterv1.Bootstrap{ 812 ConfigRef: &corev1.ObjectReference{ 813 Kind: "KubeadmConfig", 814 Namespace: "default", 815 Name: "test", 816 APIVersion: bootstrapv1.GroupVersion.String(), 817 }, 818 }, 819 }, 820 } 821 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 822 m.Name: { 823 TypeMeta: metav1.TypeMeta{ 824 Kind: "KubeadmConfig", 825 APIVersion: bootstrapv1.GroupVersion.String(), 826 }, 827 ObjectMeta: metav1.ObjectMeta{ 828 Namespace: "default", 829 Name: "test", 830 }, 831 Spec: bootstrapv1.KubeadmConfigSpec{ 832 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 833 }, 834 }, 835 } 836 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 837 g.Expect(match).To(BeFalse()) 838 g.Expect(reason).To(Equal("Machine InitConfiguration or JoinConfiguration are outdated")) 839 }) 840 t.Run("returns false if some other configurations are not equal", func(t *testing.T) { 841 g := NewWithT(t) 842 kcp := &controlplanev1.KubeadmControlPlane{ 843 Spec: controlplanev1.KubeadmControlPlaneSpec{ 844 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 845 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 846 InitConfiguration: &bootstrapv1.InitConfiguration{}, 847 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 848 Files: []bootstrapv1.File{}, // This is a change 849 }, 850 }, 851 } 852 m := &clusterv1.Machine{ 853 TypeMeta: metav1.TypeMeta{ 854 Kind: "KubeadmConfig", 855 APIVersion: clusterv1.GroupVersion.String(), 856 }, 857 ObjectMeta: metav1.ObjectMeta{ 858 Namespace: "default", 859 Name: "test", 860 }, 861 Spec: clusterv1.MachineSpec{ 862 Bootstrap: clusterv1.Bootstrap{ 863 ConfigRef: &corev1.ObjectReference{ 864 Kind: "KubeadmConfig", 865 Namespace: "default", 866 Name: "test", 867 APIVersion: bootstrapv1.GroupVersion.String(), 868 }, 869 }, 870 }, 871 } 872 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 873 m.Name: { 874 TypeMeta: metav1.TypeMeta{ 875 Kind: "KubeadmConfig", 876 APIVersion: bootstrapv1.GroupVersion.String(), 877 }, 878 ObjectMeta: metav1.ObjectMeta{ 879 Namespace: "default", 880 Name: "test", 881 }, 882 Spec: bootstrapv1.KubeadmConfigSpec{ 883 InitConfiguration: &bootstrapv1.InitConfiguration{}, 884 }, 885 }, 886 } 887 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 888 g.Expect(match).To(BeFalse()) 889 g.Expect(reason).To(Equal("Machine InitConfiguration or JoinConfiguration are outdated")) 890 }) 891 t.Run("should match on labels and annotations", func(t *testing.T) { 892 kcp := &controlplanev1.KubeadmControlPlane{ 893 Spec: controlplanev1.KubeadmControlPlaneSpec{ 894 MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ 895 ObjectMeta: clusterv1.ObjectMeta{ 896 Annotations: map[string]string{ 897 "test": "annotation", 898 }, 899 Labels: map[string]string{ 900 "test": "labels", 901 }, 902 }, 903 }, 904 KubeadmConfigSpec: bootstrapv1.KubeadmConfigSpec{ 905 ClusterConfiguration: &bootstrapv1.ClusterConfiguration{}, 906 InitConfiguration: &bootstrapv1.InitConfiguration{}, 907 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 908 }, 909 }, 910 } 911 m := &clusterv1.Machine{ 912 TypeMeta: metav1.TypeMeta{ 913 Kind: "KubeadmConfig", 914 APIVersion: clusterv1.GroupVersion.String(), 915 }, 916 ObjectMeta: metav1.ObjectMeta{ 917 Namespace: "default", 918 Name: "test", 919 }, 920 Spec: clusterv1.MachineSpec{ 921 Bootstrap: clusterv1.Bootstrap{ 922 ConfigRef: &corev1.ObjectReference{ 923 Kind: "KubeadmConfig", 924 Namespace: "default", 925 Name: "test", 926 APIVersion: bootstrapv1.GroupVersion.String(), 927 }, 928 }, 929 }, 930 } 931 machineConfigs := map[string]*bootstrapv1.KubeadmConfig{ 932 m.Name: { 933 TypeMeta: metav1.TypeMeta{ 934 Kind: "KubeadmConfig", 935 APIVersion: bootstrapv1.GroupVersion.String(), 936 }, 937 ObjectMeta: metav1.ObjectMeta{ 938 Namespace: "default", 939 Name: "test", 940 }, 941 Spec: bootstrapv1.KubeadmConfigSpec{ 942 JoinConfiguration: &bootstrapv1.JoinConfiguration{}, 943 }, 944 }, 945 } 946 947 t.Run("by returning true if neither labels or annotations match", func(t *testing.T) { 948 g := NewWithT(t) 949 machineConfigs[m.Name].Annotations = nil 950 machineConfigs[m.Name].Labels = nil 951 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 952 g.Expect(match).To(BeTrue()) 953 g.Expect(reason).To(BeEmpty()) 954 }) 955 956 t.Run("by returning true if only labels don't match", func(t *testing.T) { 957 g := NewWithT(t) 958 machineConfigs[m.Name].Annotations = kcp.Spec.MachineTemplate.ObjectMeta.Annotations 959 machineConfigs[m.Name].Labels = nil 960 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 961 g.Expect(match).To(BeTrue()) 962 g.Expect(reason).To(BeEmpty()) 963 }) 964 965 t.Run("by returning true if only annotations don't match", func(t *testing.T) { 966 g := NewWithT(t) 967 machineConfigs[m.Name].Annotations = nil 968 machineConfigs[m.Name].Labels = kcp.Spec.MachineTemplate.ObjectMeta.Labels 969 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 970 g.Expect(match).To(BeTrue()) 971 g.Expect(reason).To(BeEmpty()) 972 }) 973 974 t.Run("by returning true if both labels and annotations match", func(t *testing.T) { 975 g := NewWithT(t) 976 machineConfigs[m.Name].Labels = kcp.Spec.MachineTemplate.ObjectMeta.Labels 977 machineConfigs[m.Name].Annotations = kcp.Spec.MachineTemplate.ObjectMeta.Annotations 978 reason, match := matchesKubeadmBootstrapConfig(machineConfigs, kcp, m) 979 g.Expect(match).To(BeTrue()) 980 g.Expect(reason).To(BeEmpty()) 981 }) 982 }) 983 } 984 985 func TestMatchesTemplateClonedFrom(t *testing.T) { 986 t.Run("nil machine returns false", func(t *testing.T) { 987 g := NewWithT(t) 988 reason, match := matchesTemplateClonedFrom(nil, nil, nil) 989 g.Expect(match).To(BeFalse()) 990 g.Expect(reason).To(Equal("Machine cannot be compared with KCP.spec.machineTemplate.infrastructureRef: Machine is nil")) 991 }) 992 993 t.Run("returns true if machine not found", func(t *testing.T) { 994 g := NewWithT(t) 995 kcp := &controlplanev1.KubeadmControlPlane{} 996 machine := &clusterv1.Machine{ 997 Spec: clusterv1.MachineSpec{ 998 InfrastructureRef: corev1.ObjectReference{ 999 Kind: "KubeadmConfig", 1000 Namespace: "default", 1001 Name: "test", 1002 APIVersion: bootstrapv1.GroupVersion.String(), 1003 }, 1004 }, 1005 } 1006 reason, match := matchesTemplateClonedFrom(map[string]*unstructured.Unstructured{}, kcp, machine) 1007 g.Expect(match).To(BeTrue()) 1008 g.Expect(reason).To(BeEmpty()) 1009 }) 1010 1011 t.Run("matches labels or annotations", func(t *testing.T) { 1012 kcp := &controlplanev1.KubeadmControlPlane{ 1013 ObjectMeta: metav1.ObjectMeta{ 1014 Namespace: "default", 1015 }, 1016 Spec: controlplanev1.KubeadmControlPlaneSpec{ 1017 MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ 1018 ObjectMeta: clusterv1.ObjectMeta{ 1019 Annotations: map[string]string{ 1020 "test": "annotation", 1021 }, 1022 Labels: map[string]string{ 1023 "test": "labels", 1024 }, 1025 }, 1026 InfrastructureRef: corev1.ObjectReference{ 1027 Kind: "GenericMachineTemplate", 1028 Namespace: "default", 1029 Name: "infra-foo", 1030 APIVersion: "generic.io/v1", 1031 }, 1032 }, 1033 }, 1034 } 1035 m := &clusterv1.Machine{ 1036 Spec: clusterv1.MachineSpec{ 1037 InfrastructureRef: corev1.ObjectReference{ 1038 Kind: "GenericMachine", 1039 Namespace: "default", 1040 Name: "infra-foo", 1041 APIVersion: "generic.io/v1", 1042 }, 1043 }, 1044 } 1045 1046 infraConfigs := map[string]*unstructured.Unstructured{ 1047 m.Name: { 1048 Object: map[string]interface{}{ 1049 "kind": "InfrastructureMachine", 1050 "apiVersion": "infrastructure.cluster.x-k8s.io/v1beta1", 1051 "metadata": map[string]interface{}{ 1052 "name": "infra-config1", 1053 "namespace": "default", 1054 }, 1055 }, 1056 }, 1057 } 1058 1059 t.Run("by returning true if neither labels or annotations match", func(t *testing.T) { 1060 g := NewWithT(t) 1061 infraConfigs[m.Name].SetAnnotations(map[string]string{ 1062 clusterv1.TemplateClonedFromNameAnnotation: "infra-foo", 1063 clusterv1.TemplateClonedFromGroupKindAnnotation: "GenericMachineTemplate.generic.io", 1064 }) 1065 infraConfigs[m.Name].SetLabels(nil) 1066 reason, match := matchesTemplateClonedFrom(infraConfigs, kcp, m) 1067 g.Expect(match).To(BeTrue()) 1068 g.Expect(reason).To(BeEmpty()) 1069 }) 1070 1071 t.Run("by returning true if only labels don't match", func(t *testing.T) { 1072 g := NewWithT(t) 1073 infraConfigs[m.Name].SetAnnotations(map[string]string{ 1074 clusterv1.TemplateClonedFromNameAnnotation: "infra-foo", 1075 clusterv1.TemplateClonedFromGroupKindAnnotation: "GenericMachineTemplate.generic.io", 1076 "test": "annotation", 1077 }) 1078 infraConfigs[m.Name].SetLabels(nil) 1079 reason, match := matchesTemplateClonedFrom(infraConfigs, kcp, m) 1080 g.Expect(match).To(BeTrue()) 1081 g.Expect(reason).To(BeEmpty()) 1082 }) 1083 1084 t.Run("by returning true if only annotations don't match", func(t *testing.T) { 1085 g := NewWithT(t) 1086 infraConfigs[m.Name].SetAnnotations(map[string]string{ 1087 clusterv1.TemplateClonedFromNameAnnotation: "infra-foo", 1088 clusterv1.TemplateClonedFromGroupKindAnnotation: "GenericMachineTemplate.generic.io", 1089 }) 1090 infraConfigs[m.Name].SetLabels(kcp.Spec.MachineTemplate.ObjectMeta.Labels) 1091 reason, match := matchesTemplateClonedFrom(infraConfigs, kcp, m) 1092 g.Expect(match).To(BeTrue()) 1093 g.Expect(reason).To(BeEmpty()) 1094 }) 1095 1096 t.Run("by returning true if both labels and annotations match", func(t *testing.T) { 1097 g := NewWithT(t) 1098 infraConfigs[m.Name].SetAnnotations(map[string]string{ 1099 clusterv1.TemplateClonedFromNameAnnotation: "infra-foo", 1100 clusterv1.TemplateClonedFromGroupKindAnnotation: "GenericMachineTemplate.generic.io", 1101 "test": "annotation", 1102 }) 1103 infraConfigs[m.Name].SetLabels(kcp.Spec.MachineTemplate.ObjectMeta.Labels) 1104 reason, match := matchesTemplateClonedFrom(infraConfigs, kcp, m) 1105 g.Expect(match).To(BeTrue()) 1106 g.Expect(reason).To(BeEmpty()) 1107 }) 1108 }) 1109 } 1110 1111 func TestMatchesTemplateClonedFrom_WithClonedFromAnnotations(t *testing.T) { 1112 kcp := &controlplanev1.KubeadmControlPlane{ 1113 ObjectMeta: metav1.ObjectMeta{ 1114 Namespace: "default", 1115 }, 1116 Spec: controlplanev1.KubeadmControlPlaneSpec{ 1117 MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ 1118 InfrastructureRef: corev1.ObjectReference{ 1119 Kind: "GenericMachineTemplate", 1120 Namespace: "default", 1121 Name: "infra-foo", 1122 APIVersion: "generic.io/v1", 1123 }, 1124 }, 1125 }, 1126 } 1127 machine := &clusterv1.Machine{ 1128 Spec: clusterv1.MachineSpec{ 1129 InfrastructureRef: corev1.ObjectReference{ 1130 APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", 1131 Kind: "InfrastructureMachine", 1132 Name: "infra-config1", 1133 Namespace: "default", 1134 }, 1135 }, 1136 } 1137 tests := []struct { 1138 name string 1139 annotations map[string]interface{} 1140 expectMatch bool 1141 expectReason string 1142 }{ 1143 { 1144 name: "returns true if annotations don't exist", 1145 annotations: map[string]interface{}{}, 1146 expectMatch: true, 1147 }, 1148 { 1149 name: "returns false if annotations don't match anything", 1150 annotations: map[string]interface{}{ 1151 clusterv1.TemplateClonedFromNameAnnotation: "barfoo1", 1152 clusterv1.TemplateClonedFromGroupKindAnnotation: "barfoo2", 1153 }, 1154 expectMatch: false, 1155 expectReason: "Infrastructure template on KCP rotated from barfoo2 barfoo1 to GenericMachineTemplate.generic.io infra-foo", 1156 }, 1157 { 1158 name: "returns false if TemplateClonedFromNameAnnotation matches but TemplateClonedFromGroupKindAnnotation doesn't", 1159 annotations: map[string]interface{}{ 1160 clusterv1.TemplateClonedFromNameAnnotation: "infra-foo", 1161 clusterv1.TemplateClonedFromGroupKindAnnotation: "barfoo2", 1162 }, 1163 expectMatch: false, 1164 expectReason: "Infrastructure template on KCP rotated from barfoo2 infra-foo to GenericMachineTemplate.generic.io infra-foo", 1165 }, 1166 { 1167 name: "returns true if both annotations match", 1168 annotations: map[string]interface{}{ 1169 clusterv1.TemplateClonedFromNameAnnotation: "infra-foo", 1170 clusterv1.TemplateClonedFromGroupKindAnnotation: "GenericMachineTemplate.generic.io", 1171 }, 1172 expectMatch: true, 1173 }, 1174 } 1175 1176 for _, tt := range tests { 1177 t.Run(tt.name, func(t *testing.T) { 1178 g := NewWithT(t) 1179 infraConfigs := map[string]*unstructured.Unstructured{ 1180 machine.Name: { 1181 Object: map[string]interface{}{ 1182 "kind": "InfrastructureMachine", 1183 "apiVersion": "infrastructure.cluster.x-k8s.io/v1beta1", 1184 "metadata": map[string]interface{}{ 1185 "name": "infra-config1", 1186 "namespace": "default", 1187 "annotations": tt.annotations, 1188 }, 1189 }, 1190 }, 1191 } 1192 reason, match := matchesTemplateClonedFrom(infraConfigs, kcp, machine) 1193 g.Expect(match).To(Equal(tt.expectMatch)) 1194 g.Expect(reason).To(Equal(tt.expectReason)) 1195 }) 1196 } 1197 }