sigs.k8s.io/cluster-api@v1.7.1/internal/webhooks/clusterclass_test.go (about) 1 /* 2 Copyright 2021 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 webhooks 18 19 import ( 20 "strings" 21 "testing" 22 "time" 23 24 . "github.com/onsi/gomega" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 utilfeature "k8s.io/component-base/featuregate/testing" 29 "k8s.io/utils/ptr" 30 ctrl "sigs.k8s.io/controller-runtime" 31 "sigs.k8s.io/controller-runtime/pkg/client" 32 "sigs.k8s.io/controller-runtime/pkg/client/fake" 33 34 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 35 "sigs.k8s.io/cluster-api/api/v1beta1/index" 36 expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" 37 "sigs.k8s.io/cluster-api/feature" 38 "sigs.k8s.io/cluster-api/internal/test/builder" 39 "sigs.k8s.io/cluster-api/internal/webhooks/util" 40 ) 41 42 var ( 43 ctx = ctrl.SetupSignalHandler() 44 fakeScheme = runtime.NewScheme() 45 ) 46 47 func init() { 48 _ = clusterv1.AddToScheme(fakeScheme) 49 _ = expv1.AddToScheme(fakeScheme) 50 } 51 52 func TestClusterClassDefaultNamespaces(t *testing.T) { 53 // NOTE: ClusterTopology feature flag is disabled by default, thus preventing to create or update ClusterClasses. 54 // Enabling the feature flag temporarily for this test. 55 defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, feature.ClusterTopology, true)() 56 57 namespace := "default" 58 59 in := builder.ClusterClass(namespace, "class1"). 60 WithInfrastructureClusterTemplate( 61 builder.InfrastructureClusterTemplate("", "infra1").Build()). 62 WithControlPlaneTemplate( 63 builder.ControlPlaneTemplate("", "cp1"). 64 Build()). 65 WithControlPlaneInfrastructureMachineTemplate( 66 builder.InfrastructureMachineTemplate("", "cpInfra1"). 67 Build()). 68 WithWorkerMachineDeploymentClasses( 69 *builder.MachineDeploymentClass("aa"). 70 WithInfrastructureTemplate( 71 builder.InfrastructureMachineTemplate("", "infra1").Build()). 72 WithBootstrapTemplate( 73 builder.BootstrapTemplate("", "bootstrap1").Build()). 74 Build()). 75 WithWorkerMachinePoolClasses( 76 *builder.MachinePoolClass("aa"). 77 WithInfrastructureTemplate( 78 builder.InfrastructureMachinePoolTemplate("", "infra1").Build()). 79 WithBootstrapTemplate( 80 builder.BootstrapTemplate("", "bootstrap1").Build()). 81 Build()). 82 Build() 83 84 fakeClient := fake.NewClientBuilder(). 85 WithScheme(fakeScheme). 86 WithIndex(&clusterv1.Cluster{}, index.ClusterClassNameField, index.ClusterByClusterClassClassName). 87 Build() 88 89 // Create the webhook and add the fakeClient as its client. 90 webhook := &ClusterClass{Client: fakeClient} 91 t.Run("for ClusterClass", util.CustomDefaultValidateTest(ctx, in, webhook)) 92 93 g := NewWithT(t) 94 g.Expect(webhook.Default(ctx, in)).To(Succeed()) 95 96 // Namespace defaulted on references 97 g.Expect(in.Spec.Infrastructure.Ref.Namespace).To(Equal(namespace)) 98 g.Expect(in.Spec.ControlPlane.Ref.Namespace).To(Equal(namespace)) 99 g.Expect(in.Spec.ControlPlane.MachineInfrastructure.Ref.Namespace).To(Equal(namespace)) 100 for i := range in.Spec.Workers.MachineDeployments { 101 g.Expect(in.Spec.Workers.MachineDeployments[i].Template.Bootstrap.Ref.Namespace).To(Equal(namespace)) 102 g.Expect(in.Spec.Workers.MachineDeployments[i].Template.Infrastructure.Ref.Namespace).To(Equal(namespace)) 103 } 104 for i := range in.Spec.Workers.MachinePools { 105 g.Expect(in.Spec.Workers.MachinePools[i].Template.Bootstrap.Ref.Namespace).To(Equal(namespace)) 106 g.Expect(in.Spec.Workers.MachinePools[i].Template.Infrastructure.Ref.Namespace).To(Equal(namespace)) 107 } 108 } 109 110 func TestClusterClassValidationFeatureGated(t *testing.T) { 111 // NOTE: ClusterTopology feature flag is disabled by default, thus preventing to create or update ClusterClasses. 112 113 tests := []struct { 114 name string 115 in *clusterv1.ClusterClass 116 old *clusterv1.ClusterClass 117 expectErr bool 118 }{ 119 { 120 name: "creation should fail if feature flag is disabled, no matter the ClusterClass is valid(or not)", 121 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 122 WithInfrastructureClusterTemplate( 123 builder.InfrastructureClusterTemplate("", "infra1").Build()). 124 WithControlPlaneTemplate( 125 builder.ControlPlaneTemplate("", "cp1"). 126 Build()). 127 WithControlPlaneInfrastructureMachineTemplate( 128 builder.InfrastructureMachineTemplate("", "cpInfra1"). 129 Build()). 130 WithWorkerMachineDeploymentClasses( 131 *builder.MachineDeploymentClass("aa"). 132 WithInfrastructureTemplate( 133 builder.InfrastructureMachineTemplate("", "infra1").Build()). 134 WithBootstrapTemplate( 135 builder.BootstrapTemplate("", "bootstrap1").Build()). 136 Build()). 137 WithWorkerMachinePoolClasses( 138 *builder.MachinePoolClass("aa"). 139 WithInfrastructureTemplate( 140 builder.InfrastructureMachinePoolTemplate("", "infra1").Build()). 141 WithBootstrapTemplate( 142 builder.BootstrapTemplate("", "bootstrap1").Build()). 143 Build()). 144 Build(), 145 expectErr: true, 146 }, 147 { 148 name: "update should fail if feature flag is disabled, no matter the ClusterClass is valid(or not)", 149 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 150 WithInfrastructureClusterTemplate( 151 builder.InfrastructureClusterTemplate("", "infra1").Build()). 152 WithControlPlaneTemplate( 153 builder.ControlPlaneTemplate("", "cp1"). 154 Build()). 155 WithControlPlaneInfrastructureMachineTemplate( 156 builder.InfrastructureMachineTemplate("", "cpInfra1"). 157 Build()). 158 WithWorkerMachineDeploymentClasses( 159 *builder.MachineDeploymentClass("aa"). 160 WithInfrastructureTemplate( 161 builder.InfrastructureMachineTemplate("", "infra1").Build()). 162 WithBootstrapTemplate( 163 builder.BootstrapTemplate("", "bootstrap1").Build()). 164 Build()). 165 WithWorkerMachinePoolClasses( 166 *builder.MachinePoolClass("aa"). 167 WithInfrastructureTemplate( 168 builder.InfrastructureMachinePoolTemplate("", "infra1").Build()). 169 WithBootstrapTemplate( 170 builder.BootstrapTemplate("", "bootstrap1").Build()). 171 Build()). 172 Build(), 173 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 174 WithInfrastructureClusterTemplate( 175 builder.InfrastructureClusterTemplate("", "infra1").Build()). 176 WithControlPlaneTemplate( 177 builder.ControlPlaneTemplate("", "cp1"). 178 Build()). 179 WithControlPlaneInfrastructureMachineTemplate( 180 builder.InfrastructureMachineTemplate("", "cpInfra1"). 181 Build()). 182 WithWorkerMachineDeploymentClasses( 183 *builder.MachineDeploymentClass("aa"). 184 WithInfrastructureTemplate( 185 builder.InfrastructureMachineTemplate("", "infra1").Build()). 186 WithBootstrapTemplate( 187 builder.BootstrapTemplate("", "bootstrap1").Build()). 188 Build()). 189 WithWorkerMachinePoolClasses( 190 *builder.MachinePoolClass("aa"). 191 WithInfrastructureTemplate( 192 builder.InfrastructureMachinePoolTemplate("", "infra1").Build()). 193 WithBootstrapTemplate( 194 builder.BootstrapTemplate("", "bootstrap1").Build()). 195 Build()). 196 Build(), 197 expectErr: true, 198 }, 199 } 200 201 for _, tt := range tests { 202 t.Run(tt.name, func(t *testing.T) { 203 g := NewWithT(t) 204 webhook := &ClusterClass{} 205 err := webhook.validate(ctx, tt.old, tt.in) 206 if tt.expectErr { 207 g.Expect(err).To(HaveOccurred()) 208 return 209 } 210 g.Expect(err).ToNot(HaveOccurred()) 211 }) 212 } 213 } 214 215 func TestClusterClassValidation(t *testing.T) { 216 // NOTE: ClusterTopology feature flag is disabled by default, thus preventing to create or update ClusterClasses. 217 // Enabling the feature flag temporarily for this test. 218 defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, feature.ClusterTopology, true)() 219 220 ref := &corev1.ObjectReference{ 221 APIVersion: "group.test.io/foo", 222 Kind: "barTemplate", 223 Name: "baz", 224 Namespace: "default", 225 } 226 refBadTemplate := &corev1.ObjectReference{ 227 APIVersion: "group.test.io/foo", 228 Kind: "bar", 229 Name: "baz", 230 Namespace: "default", 231 } 232 refBadAPIVersion := &corev1.ObjectReference{ 233 APIVersion: "group/test.io/v1/foo", 234 Kind: "barTemplate", 235 Name: "baz", 236 Namespace: "default", 237 } 238 incompatibleRef := &corev1.ObjectReference{ 239 APIVersion: "group.test.io/foo", 240 Kind: "another-barTemplate", 241 Name: "baz", 242 Namespace: "default", 243 } 244 compatibleRef := &corev1.ObjectReference{ 245 APIVersion: "group.test.io/another-foo", 246 Kind: "barTemplate", 247 Name: "another-baz", 248 Namespace: "default", 249 } 250 251 tests := []struct { 252 name string 253 in *clusterv1.ClusterClass 254 old *clusterv1.ClusterClass 255 expectErr bool 256 }{ 257 258 /* 259 CREATE Tests 260 */ 261 262 { 263 name: "create pass", 264 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 265 WithInfrastructureClusterTemplate( 266 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 267 WithControlPlaneTemplate( 268 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 269 Build()). 270 WithControlPlaneInfrastructureMachineTemplate( 271 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 272 Build()). 273 WithWorkerMachineDeploymentClasses( 274 *builder.MachineDeploymentClass("aa"). 275 WithInfrastructureTemplate( 276 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 277 WithBootstrapTemplate( 278 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 279 Build(), 280 *builder.MachineDeploymentClass("bb"). 281 WithInfrastructureTemplate( 282 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 283 WithBootstrapTemplate( 284 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 285 Build()). 286 WithWorkerMachinePoolClasses( 287 *builder.MachinePoolClass("aa"). 288 WithInfrastructureTemplate( 289 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 290 WithBootstrapTemplate( 291 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 292 Build(), 293 *builder.MachinePoolClass("bb"). 294 WithInfrastructureTemplate( 295 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 296 WithBootstrapTemplate( 297 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 298 Build()). 299 Build(), 300 expectErr: false, 301 }, 302 303 // empty name in ref tests 304 { 305 name: "create fail infrastructureCluster has empty name", 306 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 307 WithInfrastructureClusterTemplate( 308 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "").Build()). 309 WithControlPlaneTemplate( 310 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 311 Build()). 312 Build(), 313 expectErr: true, 314 }, 315 { 316 name: "create fail controlPlane class has empty name", 317 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 318 WithInfrastructureClusterTemplate( 319 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 320 WithControlPlaneTemplate( 321 builder.ControlPlaneTemplate(metav1.NamespaceDefault, ""). 322 Build()). 323 Build(), 324 expectErr: true, 325 }, 326 { 327 name: "create fail control plane class machineInfrastructure has empty name", 328 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 329 WithInfrastructureClusterTemplate( 330 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 331 WithControlPlaneTemplate( 332 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 333 Build()). 334 WithControlPlaneInfrastructureMachineTemplate( 335 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, ""). 336 Build()). 337 Build(), 338 expectErr: true, 339 }, 340 { 341 name: "create fail machineDeployment Bootstrap has empty name", 342 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 343 WithInfrastructureClusterTemplate( 344 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 345 WithControlPlaneTemplate( 346 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 347 Build()). 348 WithControlPlaneInfrastructureMachineTemplate( 349 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 350 Build()). 351 WithWorkerMachineDeploymentClasses( 352 *builder.MachineDeploymentClass("aa"). 353 WithInfrastructureTemplate( 354 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 355 WithBootstrapTemplate( 356 builder.BootstrapTemplate(metav1.NamespaceDefault, "").Build()). 357 Build()). 358 Build(), 359 expectErr: true, 360 }, 361 { 362 name: "create fail machineDeployment Infrastructure has empty name", 363 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 364 WithInfrastructureClusterTemplate( 365 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 366 WithControlPlaneTemplate( 367 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 368 Build()). 369 WithControlPlaneInfrastructureMachineTemplate( 370 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 371 Build()). 372 WithWorkerMachineDeploymentClasses( 373 *builder.MachineDeploymentClass("aa"). 374 WithInfrastructureTemplate( 375 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "").Build()). 376 WithBootstrapTemplate( 377 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap").Build()). 378 Build()). 379 Build(), 380 expectErr: true, 381 }, 382 { 383 name: "create fail machinePool Bootstrap has empty name", 384 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 385 WithInfrastructureClusterTemplate( 386 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 387 WithControlPlaneTemplate( 388 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 389 Build()). 390 WithControlPlaneInfrastructureMachineTemplate( 391 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 392 Build()). 393 WithWorkerMachinePoolClasses( 394 *builder.MachinePoolClass("aa"). 395 WithInfrastructureTemplate( 396 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 397 WithBootstrapTemplate( 398 builder.BootstrapTemplate(metav1.NamespaceDefault, "").Build()). 399 Build()). 400 Build(), 401 expectErr: true, 402 }, 403 { 404 name: "create fail machinePool Infrastructure has empty name", 405 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 406 WithInfrastructureClusterTemplate( 407 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 408 WithControlPlaneTemplate( 409 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 410 Build()). 411 WithControlPlaneInfrastructureMachineTemplate( 412 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 413 Build()). 414 WithWorkerMachinePoolClasses( 415 *builder.MachinePoolClass("aa"). 416 WithInfrastructureTemplate( 417 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "").Build()). 418 WithBootstrapTemplate( 419 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap").Build()). 420 Build()). 421 Build(), 422 expectErr: true, 423 }, 424 425 // inconsistent namespace in ref tests 426 { 427 name: "create fail if InfrastructureCluster has inconsistent namespace", 428 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 429 WithInfrastructureClusterTemplate( 430 builder.InfrastructureClusterTemplate("WrongNamespace", "infra1").Build()). 431 WithControlPlaneTemplate( 432 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 433 Build()). 434 WithControlPlaneInfrastructureMachineTemplate( 435 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 436 Build()). 437 Build(), 438 expectErr: true, 439 }, 440 { 441 name: "create fail if controlPlane has inconsistent namespace", 442 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 443 WithInfrastructureClusterTemplate( 444 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 445 WithControlPlaneTemplate( 446 builder.ControlPlaneTemplate("WrongNamespace", "cp1"). 447 Build()). 448 WithControlPlaneInfrastructureMachineTemplate( 449 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 450 Build()). 451 Build(), 452 expectErr: true, 453 }, 454 { 455 name: "create fail if controlPlane machineInfrastructure has inconsistent namespace", 456 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 457 WithInfrastructureClusterTemplate( 458 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 459 WithControlPlaneTemplate( 460 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 461 Build()). 462 WithControlPlaneInfrastructureMachineTemplate( 463 builder.InfrastructureMachineTemplate("WrongNamespace", "cpInfra1"). 464 Build()). 465 Build(), 466 expectErr: true, 467 }, 468 { 469 name: "create fail if machineDeployment / bootstrap has inconsistent namespace", 470 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 471 WithInfrastructureClusterTemplate( 472 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 473 WithControlPlaneTemplate( 474 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 475 Build()). 476 WithControlPlaneInfrastructureMachineTemplate( 477 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 478 Build()). 479 WithWorkerMachineDeploymentClasses( 480 *builder.MachineDeploymentClass("aa"). 481 WithInfrastructureTemplate( 482 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 483 WithBootstrapTemplate( 484 builder.BootstrapTemplate("WrongNamespace", "bootstrap1").Build()). 485 Build()). 486 Build(), 487 expectErr: true, 488 }, 489 { 490 name: "create fail if machineDeployment / infrastructure has inconsistent namespace", 491 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 492 WithInfrastructureClusterTemplate( 493 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 494 WithControlPlaneTemplate( 495 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 496 Build()). 497 WithControlPlaneInfrastructureMachineTemplate( 498 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 499 Build()). 500 WithWorkerMachineDeploymentClasses( 501 *builder.MachineDeploymentClass("aa"). 502 WithInfrastructureTemplate( 503 builder.InfrastructureMachineTemplate("WrongNamespace", "infra1").Build()). 504 WithBootstrapTemplate( 505 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 506 Build()). 507 Build(), 508 expectErr: true, 509 }, 510 { 511 name: "create fail if machinePool / bootstrap has inconsistent namespace", 512 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 513 WithInfrastructureClusterTemplate( 514 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 515 WithControlPlaneTemplate( 516 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 517 Build()). 518 WithControlPlaneInfrastructureMachineTemplate( 519 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 520 Build()). 521 WithWorkerMachinePoolClasses( 522 *builder.MachinePoolClass("aa"). 523 WithInfrastructureTemplate( 524 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 525 WithBootstrapTemplate( 526 builder.BootstrapTemplate("WrongNamespace", "bootstrap1").Build()). 527 Build()). 528 Build(), 529 expectErr: true, 530 }, 531 { 532 name: "create fail if machinePool / infrastructure has inconsistent namespace", 533 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 534 WithInfrastructureClusterTemplate( 535 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 536 WithControlPlaneTemplate( 537 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 538 Build()). 539 WithControlPlaneInfrastructureMachineTemplate( 540 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 541 Build()). 542 WithWorkerMachinePoolClasses( 543 *builder.MachinePoolClass("aa"). 544 WithInfrastructureTemplate( 545 builder.InfrastructureMachinePoolTemplate("WrongNamespace", "infra1").Build()). 546 WithBootstrapTemplate( 547 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 548 Build()). 549 Build(), 550 expectErr: true, 551 }, 552 553 // bad template in ref tests 554 { 555 name: "create fail if bad template in InfrastructureCluster", 556 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 557 WithInfrastructureClusterTemplate( 558 refToUnstructured(refBadTemplate)). 559 WithControlPlaneTemplate( 560 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 561 Build()). 562 WithControlPlaneInfrastructureMachineTemplate( 563 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 564 Build()). 565 Build(), 566 old: nil, 567 expectErr: true, 568 }, 569 { 570 name: "create fail if bad template in controlPlane machineInfrastructure", 571 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 572 WithInfrastructureClusterTemplate( 573 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 574 WithControlPlaneTemplate( 575 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 576 Build()). 577 WithControlPlaneInfrastructureMachineTemplate( 578 refToUnstructured(refBadTemplate)). 579 Build(), 580 old: nil, 581 expectErr: true, 582 }, 583 { 584 name: "create fail if bad template in ControlPlane", 585 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 586 WithInfrastructureClusterTemplate( 587 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 588 WithControlPlaneTemplate( 589 refToUnstructured(refBadTemplate)). 590 WithControlPlaneInfrastructureMachineTemplate( 591 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 592 Build()). 593 Build(), 594 old: nil, 595 expectErr: true, 596 }, 597 { 598 name: "create fail if bad template in machineDeployment Bootstrap", 599 600 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 601 WithInfrastructureClusterTemplate( 602 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 603 WithControlPlaneTemplate( 604 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 605 Build()). 606 WithControlPlaneInfrastructureMachineTemplate( 607 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 608 Build()). 609 WithWorkerMachineDeploymentClasses( 610 *builder.MachineDeploymentClass("aa"). 611 WithInfrastructureTemplate( 612 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 613 WithBootstrapTemplate( 614 refToUnstructured(refBadTemplate)). 615 Build()). 616 Build(), 617 old: nil, 618 expectErr: true, 619 }, 620 { 621 name: "create fail if bad template in machineDeployment Infrastructure", 622 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 623 WithInfrastructureClusterTemplate( 624 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 625 WithControlPlaneTemplate( 626 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 627 Build()). 628 WithControlPlaneInfrastructureMachineTemplate( 629 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 630 Build()). 631 WithWorkerMachineDeploymentClasses( 632 *builder.MachineDeploymentClass("aa"). 633 WithInfrastructureTemplate( 634 refToUnstructured(refBadTemplate)). 635 WithBootstrapTemplate( 636 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 637 Build()). 638 Build(), 639 old: nil, 640 expectErr: true, 641 }, 642 { 643 name: "create fail if bad template in machinePool Bootstrap", 644 645 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 646 WithInfrastructureClusterTemplate( 647 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 648 WithControlPlaneTemplate( 649 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 650 Build()). 651 WithControlPlaneInfrastructureMachineTemplate( 652 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 653 Build()). 654 WithWorkerMachinePoolClasses( 655 *builder.MachinePoolClass("aa"). 656 WithInfrastructureTemplate( 657 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 658 WithBootstrapTemplate( 659 refToUnstructured(refBadTemplate)). 660 Build()). 661 Build(), 662 old: nil, 663 expectErr: true, 664 }, 665 { 666 name: "create fail if bad template in machinePool Infrastructure", 667 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 668 WithInfrastructureClusterTemplate( 669 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 670 WithControlPlaneTemplate( 671 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 672 Build()). 673 WithControlPlaneInfrastructureMachineTemplate( 674 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 675 Build()). 676 WithWorkerMachinePoolClasses( 677 *builder.MachinePoolClass("aa"). 678 WithInfrastructureTemplate( 679 refToUnstructured(refBadTemplate)). 680 WithBootstrapTemplate( 681 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 682 Build()). 683 Build(), 684 old: nil, 685 expectErr: true, 686 }, 687 688 // bad apiVersion in ref tests 689 { 690 name: "create fail with a bad APIVersion for template in InfrastructureCluster", 691 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 692 WithInfrastructureClusterTemplate( 693 refToUnstructured(refBadAPIVersion)). 694 WithControlPlaneTemplate( 695 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 696 Build()). 697 WithControlPlaneInfrastructureMachineTemplate( 698 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 699 Build()). 700 Build(), 701 old: nil, 702 expectErr: true, 703 }, 704 { 705 name: "create fail with a bad APIVersion for template in controlPlane machineInfrastructure", 706 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 707 WithInfrastructureClusterTemplate( 708 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 709 WithControlPlaneTemplate( 710 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 711 Build()). 712 WithControlPlaneInfrastructureMachineTemplate( 713 refToUnstructured(refBadAPIVersion)). 714 Build(), 715 old: nil, 716 expectErr: true, 717 }, 718 { 719 name: "create fail with a bad APIVersion for template in ControlPlane", 720 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 721 WithInfrastructureClusterTemplate( 722 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 723 WithControlPlaneTemplate( 724 refToUnstructured(refBadAPIVersion)). 725 WithControlPlaneInfrastructureMachineTemplate( 726 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 727 Build()). 728 Build(), 729 old: nil, 730 expectErr: true, 731 }, 732 { 733 name: "create fail with a bad APIVersion for template in machineDeployment Bootstrap", 734 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 735 WithInfrastructureClusterTemplate( 736 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 737 WithControlPlaneTemplate( 738 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 739 Build()). 740 WithControlPlaneInfrastructureMachineTemplate( 741 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 742 Build()). 743 WithWorkerMachineDeploymentClasses( 744 *builder.MachineDeploymentClass("aa"). 745 WithInfrastructureTemplate( 746 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 747 WithBootstrapTemplate( 748 refToUnstructured(refBadAPIVersion)). 749 Build()). 750 Build(), 751 old: nil, 752 expectErr: true, 753 }, 754 { 755 name: "create fail with a bad APIVersion for template in machineDeployment Infrastructure", 756 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 757 WithInfrastructureClusterTemplate( 758 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 759 WithControlPlaneTemplate( 760 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 761 Build()). 762 WithControlPlaneInfrastructureMachineTemplate( 763 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 764 Build()). 765 WithWorkerMachineDeploymentClasses( 766 *builder.MachineDeploymentClass("aa"). 767 WithInfrastructureTemplate( 768 refToUnstructured(refBadAPIVersion)). 769 WithBootstrapTemplate( 770 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 771 Build()). 772 Build(), 773 old: nil, 774 expectErr: true, 775 }, 776 { 777 name: "create fail with a bad APIVersion for template in machinePool Bootstrap", 778 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 779 WithInfrastructureClusterTemplate( 780 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 781 WithControlPlaneTemplate( 782 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 783 Build()). 784 WithControlPlaneInfrastructureMachineTemplate( 785 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 786 Build()). 787 WithWorkerMachinePoolClasses( 788 *builder.MachinePoolClass("aa"). 789 WithInfrastructureTemplate( 790 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 791 WithBootstrapTemplate( 792 refToUnstructured(refBadAPIVersion)). 793 Build()). 794 Build(), 795 old: nil, 796 expectErr: true, 797 }, 798 { 799 name: "create fail with a bad APIVersion for template in machinePool Infrastructure", 800 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 801 WithInfrastructureClusterTemplate( 802 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 803 WithControlPlaneTemplate( 804 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 805 Build()). 806 WithControlPlaneInfrastructureMachineTemplate( 807 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 808 Build()). 809 WithWorkerMachinePoolClasses( 810 *builder.MachinePoolClass("aa"). 811 WithInfrastructureTemplate( 812 refToUnstructured(refBadAPIVersion)). 813 WithBootstrapTemplate( 814 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 815 Build()). 816 Build(), 817 old: nil, 818 expectErr: true, 819 }, 820 821 // create test 822 { 823 name: "create fail if duplicated machineDeploymentClasses", 824 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 825 WithInfrastructureClusterTemplate( 826 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 827 WithControlPlaneTemplate( 828 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 829 Build()). 830 WithControlPlaneInfrastructureMachineTemplate( 831 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 832 Build()). 833 WithWorkerMachineDeploymentClasses( 834 *builder.MachineDeploymentClass("aa"). 835 WithInfrastructureTemplate( 836 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 837 WithBootstrapTemplate( 838 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()).Build(), 839 *builder.MachineDeploymentClass("aa"). 840 WithInfrastructureTemplate( 841 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 842 WithBootstrapTemplate( 843 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 844 Build()). 845 Build(), 846 expectErr: true, 847 }, 848 { 849 name: "create fail if duplicated machinePoolClasses", 850 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 851 WithInfrastructureClusterTemplate( 852 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 853 WithControlPlaneTemplate( 854 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 855 Build()). 856 WithControlPlaneInfrastructureMachineTemplate( 857 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 858 Build()). 859 WithWorkerMachinePoolClasses( 860 *builder.MachinePoolClass("aa"). 861 WithInfrastructureTemplate( 862 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 863 WithBootstrapTemplate( 864 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()).Build(), 865 *builder.MachinePoolClass("aa"). 866 WithInfrastructureTemplate( 867 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 868 WithBootstrapTemplate( 869 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 870 Build()). 871 Build(), 872 expectErr: true, 873 }, 874 { 875 name: "create pass if valid machineHealthCheck defined for ControlPlane with MachineInfrastructure set", 876 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 877 WithInfrastructureClusterTemplate( 878 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 879 WithControlPlaneTemplate( 880 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 881 Build()). 882 WithControlPlaneInfrastructureMachineTemplate( 883 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 884 Build()). 885 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckClass{ 886 UnhealthyConditions: []clusterv1.UnhealthyCondition{ 887 { 888 Type: corev1.NodeReady, 889 Status: corev1.ConditionUnknown, 890 Timeout: metav1.Duration{Duration: 5 * time.Minute}, 891 }, 892 }, 893 NodeStartupTimeout: &metav1.Duration{ 894 Duration: time.Duration(6000000000000)}}). 895 Build(), 896 }, 897 { 898 name: "create fail if MachineHealthCheck defined for ControlPlane with MachineInfrastructure unset", 899 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 900 WithInfrastructureClusterTemplate( 901 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 902 WithControlPlaneTemplate( 903 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 904 Build()). 905 // No ControlPlaneMachineInfrastructure makes this an invalid creation request. 906 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckClass{ 907 NodeStartupTimeout: &metav1.Duration{ 908 Duration: time.Duration(6000000000000)}}). 909 Build(), 910 expectErr: true, 911 }, 912 { 913 name: "create fail if ControlPlane MachineHealthCheck does not define UnhealthyConditions", 914 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 915 WithInfrastructureClusterTemplate( 916 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 917 WithControlPlaneTemplate( 918 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 919 Build()). 920 WithControlPlaneInfrastructureMachineTemplate( 921 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 922 Build()). 923 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckClass{ 924 NodeStartupTimeout: &metav1.Duration{ 925 Duration: time.Duration(6000000000000)}}). 926 Build(), 927 expectErr: true, 928 }, 929 { 930 name: "create pass if MachineDeployment MachineHealthCheck is valid", 931 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 932 WithInfrastructureClusterTemplate( 933 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 934 WithControlPlaneTemplate( 935 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 936 Build()). 937 WithWorkerMachineDeploymentClasses( 938 *builder.MachineDeploymentClass("aa"). 939 WithInfrastructureTemplate( 940 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 941 WithBootstrapTemplate( 942 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 943 WithMachineHealthCheckClass(&clusterv1.MachineHealthCheckClass{ 944 UnhealthyConditions: []clusterv1.UnhealthyCondition{ 945 { 946 Type: corev1.NodeReady, 947 Status: corev1.ConditionUnknown, 948 Timeout: metav1.Duration{Duration: 5 * time.Minute}, 949 }, 950 }, 951 NodeStartupTimeout: &metav1.Duration{ 952 Duration: time.Duration(6000000000000)}}). 953 Build()). 954 Build(), 955 }, 956 { 957 name: "create fail if MachineDeployment MachineHealthCheck NodeStartUpTimeout is too short", 958 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 959 WithInfrastructureClusterTemplate( 960 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 961 WithControlPlaneTemplate( 962 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 963 Build()). 964 WithWorkerMachineDeploymentClasses( 965 *builder.MachineDeploymentClass("aa"). 966 WithInfrastructureTemplate( 967 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 968 WithBootstrapTemplate( 969 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 970 WithMachineHealthCheckClass(&clusterv1.MachineHealthCheckClass{ 971 UnhealthyConditions: []clusterv1.UnhealthyCondition{ 972 { 973 Type: corev1.NodeReady, 974 Status: corev1.ConditionUnknown, 975 Timeout: metav1.Duration{Duration: 5 * time.Minute}, 976 }, 977 }, 978 NodeStartupTimeout: &metav1.Duration{ 979 // nodeStartupTimeout is too short here - 600ns. 980 Duration: time.Duration(600)}}). 981 Build()). 982 Build(), 983 expectErr: true, 984 }, 985 { 986 name: "create fail if MachineDeployment MachineHealthCheck does not define UnhealthyConditions", 987 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 988 WithInfrastructureClusterTemplate( 989 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 990 WithControlPlaneTemplate( 991 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 992 Build()). 993 WithWorkerMachineDeploymentClasses( 994 *builder.MachineDeploymentClass("aa"). 995 WithInfrastructureTemplate( 996 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 997 WithBootstrapTemplate( 998 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 999 WithMachineHealthCheckClass(&clusterv1.MachineHealthCheckClass{ 1000 NodeStartupTimeout: &metav1.Duration{ 1001 Duration: time.Duration(6000000000000)}}). 1002 Build()). 1003 Build(), 1004 expectErr: true, 1005 }, 1006 1007 /* 1008 UPDATE Tests 1009 */ 1010 1011 { 1012 name: "update pass in case of no changes", 1013 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1014 WithInfrastructureClusterTemplate( 1015 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1016 WithControlPlaneTemplate( 1017 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1018 Build()). 1019 WithControlPlaneInfrastructureMachineTemplate( 1020 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1021 Build()). 1022 WithWorkerMachineDeploymentClasses( 1023 *builder.MachineDeploymentClass("aa"). 1024 WithInfrastructureTemplate( 1025 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1026 WithBootstrapTemplate( 1027 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1028 Build()). 1029 WithWorkerMachinePoolClasses( 1030 *builder.MachinePoolClass("aa"). 1031 WithInfrastructureTemplate( 1032 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1033 WithBootstrapTemplate( 1034 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1035 Build()). 1036 Build(), 1037 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1038 WithInfrastructureClusterTemplate( 1039 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1040 WithControlPlaneTemplate( 1041 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1042 Build()). 1043 WithControlPlaneInfrastructureMachineTemplate( 1044 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1045 Build()). 1046 WithWorkerMachineDeploymentClasses( 1047 *builder.MachineDeploymentClass("aa"). 1048 WithInfrastructureTemplate( 1049 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1050 WithBootstrapTemplate( 1051 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1052 Build()). 1053 WithWorkerMachinePoolClasses( 1054 *builder.MachinePoolClass("aa"). 1055 WithInfrastructureTemplate( 1056 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1057 WithBootstrapTemplate( 1058 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1059 Build()). 1060 Build(), 1061 expectErr: false, 1062 }, 1063 { 1064 name: "update pass if infrastructureCluster changes in a compatible way", 1065 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1066 WithInfrastructureClusterTemplate( 1067 refToUnstructured(ref)). 1068 WithControlPlaneTemplate( 1069 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1070 Build()). 1071 WithControlPlaneInfrastructureMachineTemplate( 1072 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1073 Build()). 1074 WithWorkerMachineDeploymentClasses( 1075 *builder.MachineDeploymentClass("aa"). 1076 WithInfrastructureTemplate( 1077 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1078 WithBootstrapTemplate( 1079 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1080 Build()). 1081 WithWorkerMachinePoolClasses( 1082 *builder.MachinePoolClass("aa"). 1083 WithInfrastructureTemplate( 1084 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1085 WithBootstrapTemplate( 1086 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1087 Build()). 1088 Build(), 1089 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1090 WithInfrastructureClusterTemplate( 1091 refToUnstructured(compatibleRef)). 1092 WithControlPlaneTemplate( 1093 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1094 Build()). 1095 WithControlPlaneInfrastructureMachineTemplate( 1096 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1097 Build()). 1098 WithWorkerMachineDeploymentClasses( 1099 *builder.MachineDeploymentClass("aa"). 1100 WithInfrastructureTemplate( 1101 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1102 WithBootstrapTemplate( 1103 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1104 Build()). 1105 WithWorkerMachinePoolClasses( 1106 *builder.MachinePoolClass("aa"). 1107 WithInfrastructureTemplate( 1108 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1109 WithBootstrapTemplate( 1110 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1111 Build()). 1112 Build(), 1113 expectErr: false, 1114 }, 1115 { 1116 name: "update fails if infrastructureCluster changes in an incompatible way", 1117 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1118 WithInfrastructureClusterTemplate( 1119 refToUnstructured(ref)). 1120 WithControlPlaneTemplate( 1121 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1122 Build()). 1123 WithControlPlaneInfrastructureMachineTemplate( 1124 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1125 Build()). 1126 WithWorkerMachineDeploymentClasses( 1127 *builder.MachineDeploymentClass("aa"). 1128 WithInfrastructureTemplate( 1129 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1130 WithBootstrapTemplate( 1131 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1132 Build()). 1133 Build(), 1134 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1135 WithInfrastructureClusterTemplate( 1136 refToUnstructured(incompatibleRef)). 1137 WithControlPlaneTemplate( 1138 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1139 Build()). 1140 WithControlPlaneInfrastructureMachineTemplate( 1141 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1142 Build()). 1143 WithWorkerMachineDeploymentClasses( 1144 *builder.MachineDeploymentClass("aa"). 1145 WithInfrastructureTemplate( 1146 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1147 WithBootstrapTemplate( 1148 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1149 Build()). 1150 Build(), 1151 expectErr: true, 1152 }, 1153 { 1154 name: "update pass if controlPlane changes in a compatible way", 1155 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1156 WithInfrastructureClusterTemplate( 1157 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1158 WithControlPlaneTemplate( 1159 refToUnstructured(ref)). 1160 WithControlPlaneInfrastructureMachineTemplate( 1161 refToUnstructured(ref)). 1162 WithWorkerMachineDeploymentClasses( 1163 *builder.MachineDeploymentClass("aa"). 1164 WithInfrastructureTemplate( 1165 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1166 WithBootstrapTemplate( 1167 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1168 Build()). 1169 WithWorkerMachinePoolClasses( 1170 *builder.MachinePoolClass("aa"). 1171 WithInfrastructureTemplate( 1172 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1173 WithBootstrapTemplate( 1174 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1175 Build()). 1176 Build(), 1177 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1178 WithInfrastructureClusterTemplate( 1179 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1180 WithControlPlaneTemplate( 1181 refToUnstructured(compatibleRef)). 1182 WithControlPlaneInfrastructureMachineTemplate( 1183 refToUnstructured(compatibleRef)). 1184 WithWorkerMachineDeploymentClasses( 1185 *builder.MachineDeploymentClass("aa"). 1186 WithInfrastructureTemplate( 1187 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1188 WithBootstrapTemplate( 1189 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1190 Build()). 1191 WithWorkerMachinePoolClasses( 1192 *builder.MachinePoolClass("aa"). 1193 WithInfrastructureTemplate( 1194 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1195 WithBootstrapTemplate( 1196 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1197 Build()). 1198 Build(), 1199 expectErr: false, 1200 }, 1201 { 1202 name: "update fails if controlPlane changes in an incompatible way (controlPlane template)", 1203 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1204 WithInfrastructureClusterTemplate( 1205 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1206 WithControlPlaneTemplate( 1207 refToUnstructured(ref)). 1208 WithControlPlaneInfrastructureMachineTemplate( 1209 refToUnstructured(ref)). 1210 WithWorkerMachineDeploymentClasses( 1211 *builder.MachineDeploymentClass("aa"). 1212 WithInfrastructureTemplate( 1213 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1214 WithBootstrapTemplate( 1215 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1216 Build()). 1217 WithWorkerMachinePoolClasses( 1218 *builder.MachinePoolClass("aa"). 1219 WithInfrastructureTemplate( 1220 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1221 WithBootstrapTemplate( 1222 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1223 Build()). 1224 Build(), 1225 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1226 WithInfrastructureClusterTemplate( 1227 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1228 WithControlPlaneTemplate( 1229 refToUnstructured(incompatibleRef)). 1230 WithControlPlaneInfrastructureMachineTemplate( 1231 refToUnstructured(compatibleRef)). 1232 WithWorkerMachineDeploymentClasses( 1233 *builder.MachineDeploymentClass("aa"). 1234 WithInfrastructureTemplate( 1235 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1236 WithBootstrapTemplate( 1237 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1238 Build()). 1239 WithWorkerMachinePoolClasses( 1240 *builder.MachinePoolClass("aa"). 1241 WithInfrastructureTemplate( 1242 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1243 WithBootstrapTemplate( 1244 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1245 Build()). 1246 Build(), 1247 expectErr: true, 1248 }, 1249 { 1250 name: "update fails if controlPlane changes in an incompatible way (controlPlane infrastructureMachineTemplate)", 1251 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1252 WithInfrastructureClusterTemplate( 1253 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1254 WithControlPlaneTemplate( 1255 refToUnstructured(ref)). 1256 WithControlPlaneInfrastructureMachineTemplate( 1257 refToUnstructured(ref)). 1258 WithWorkerMachineDeploymentClasses( 1259 *builder.MachineDeploymentClass("aa"). 1260 WithInfrastructureTemplate( 1261 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1262 WithBootstrapTemplate( 1263 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1264 Build()). 1265 WithWorkerMachinePoolClasses( 1266 *builder.MachinePoolClass("aa"). 1267 WithInfrastructureTemplate( 1268 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1269 WithBootstrapTemplate( 1270 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1271 Build()). 1272 Build(), 1273 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1274 WithInfrastructureClusterTemplate( 1275 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1276 WithControlPlaneTemplate( 1277 refToUnstructured(compatibleRef)). 1278 WithControlPlaneInfrastructureMachineTemplate( 1279 refToUnstructured(incompatibleRef)). 1280 WithWorkerMachineDeploymentClasses( 1281 *builder.MachineDeploymentClass("aa"). 1282 WithInfrastructureTemplate( 1283 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1284 WithBootstrapTemplate( 1285 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1286 Build()). 1287 WithWorkerMachinePoolClasses( 1288 *builder.MachinePoolClass("aa"). 1289 WithInfrastructureTemplate( 1290 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1291 WithBootstrapTemplate( 1292 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1293 Build()). 1294 Build(), 1295 expectErr: true, 1296 }, 1297 { 1298 name: "update pass if a machine deployment and machine pool changes in a compatible way", 1299 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1300 WithInfrastructureClusterTemplate( 1301 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1302 WithControlPlaneTemplate( 1303 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1304 Build()). 1305 WithControlPlaneInfrastructureMachineTemplate( 1306 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1307 Build()). 1308 WithWorkerMachineDeploymentClasses( 1309 *builder.MachineDeploymentClass("aa"). 1310 WithInfrastructureTemplate( 1311 refToUnstructured(ref)). 1312 WithBootstrapTemplate( 1313 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1314 Build()). 1315 WithWorkerMachinePoolClasses( 1316 *builder.MachinePoolClass("aa"). 1317 WithInfrastructureTemplate( 1318 refToUnstructured(ref)). 1319 WithBootstrapTemplate( 1320 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1321 Build()). 1322 Build(), 1323 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1324 WithInfrastructureClusterTemplate( 1325 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1326 WithControlPlaneTemplate( 1327 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1328 Build()). 1329 WithControlPlaneInfrastructureMachineTemplate( 1330 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1331 Build()). 1332 WithWorkerMachineDeploymentClasses( 1333 *builder.MachineDeploymentClass("aa"). 1334 WithInfrastructureTemplate( 1335 refToUnstructured(compatibleRef)). 1336 WithBootstrapTemplate( 1337 refToUnstructured(incompatibleRef)). 1338 Build()). 1339 WithWorkerMachinePoolClasses( 1340 *builder.MachinePoolClass("aa"). 1341 WithInfrastructureTemplate( 1342 refToUnstructured(compatibleRef)). 1343 WithBootstrapTemplate( 1344 refToUnstructured(incompatibleRef)). 1345 Build()). 1346 Build(), 1347 expectErr: false, 1348 }, 1349 { 1350 name: "update fails a machine deployment changes in an incompatible way", 1351 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1352 WithInfrastructureClusterTemplate( 1353 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1354 WithControlPlaneTemplate( 1355 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1356 Build()). 1357 WithControlPlaneInfrastructureMachineTemplate( 1358 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1359 Build()). 1360 WithWorkerMachineDeploymentClasses( 1361 *builder.MachineDeploymentClass("aa"). 1362 WithInfrastructureTemplate( 1363 refToUnstructured(ref)). 1364 WithBootstrapTemplate( 1365 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1366 Build()). 1367 Build(), 1368 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1369 WithInfrastructureClusterTemplate( 1370 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1371 WithControlPlaneTemplate( 1372 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1373 Build()). 1374 WithControlPlaneInfrastructureMachineTemplate( 1375 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1376 Build()). 1377 WithWorkerMachineDeploymentClasses( 1378 *builder.MachineDeploymentClass("aa"). 1379 WithInfrastructureTemplate( 1380 refToUnstructured(incompatibleRef)). 1381 WithBootstrapTemplate( 1382 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1383 Build()). 1384 Build(), 1385 expectErr: true, 1386 }, 1387 { 1388 name: "update fails a machine pool changes in an incompatible way", 1389 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1390 WithInfrastructureClusterTemplate( 1391 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1392 WithControlPlaneTemplate( 1393 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1394 Build()). 1395 WithControlPlaneInfrastructureMachineTemplate( 1396 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1397 Build()). 1398 WithWorkerMachinePoolClasses( 1399 *builder.MachinePoolClass("aa"). 1400 WithInfrastructureTemplate( 1401 refToUnstructured(ref)). 1402 WithBootstrapTemplate( 1403 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1404 Build()). 1405 Build(), 1406 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1407 WithInfrastructureClusterTemplate( 1408 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1409 WithControlPlaneTemplate( 1410 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1411 Build()). 1412 WithControlPlaneInfrastructureMachineTemplate( 1413 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1414 Build()). 1415 WithWorkerMachinePoolClasses( 1416 *builder.MachinePoolClass("aa"). 1417 WithInfrastructureTemplate( 1418 refToUnstructured(incompatibleRef)). 1419 WithBootstrapTemplate( 1420 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1421 Build()). 1422 Build(), 1423 expectErr: true, 1424 }, 1425 { 1426 name: "update pass if a machine deployment or machine pool class gets added", 1427 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1428 WithInfrastructureClusterTemplate( 1429 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1430 WithControlPlaneTemplate( 1431 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1432 Build()). 1433 WithControlPlaneInfrastructureMachineTemplate( 1434 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1435 Build()). 1436 WithWorkerMachineDeploymentClasses( 1437 *builder.MachineDeploymentClass("aa"). 1438 WithInfrastructureTemplate( 1439 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1440 WithBootstrapTemplate( 1441 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1442 Build()). 1443 WithWorkerMachinePoolClasses( 1444 *builder.MachinePoolClass("aa"). 1445 WithInfrastructureTemplate( 1446 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1447 WithBootstrapTemplate( 1448 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1449 Build()). 1450 Build(), 1451 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1452 WithInfrastructureClusterTemplate( 1453 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1454 WithControlPlaneTemplate( 1455 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1456 Build()). 1457 WithControlPlaneInfrastructureMachineTemplate( 1458 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1459 Build()). 1460 WithWorkerMachineDeploymentClasses( 1461 *builder.MachineDeploymentClass("aa"). 1462 WithInfrastructureTemplate( 1463 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1464 WithBootstrapTemplate( 1465 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1466 Build(), 1467 *builder.MachineDeploymentClass("BB"). 1468 WithInfrastructureTemplate( 1469 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1470 WithBootstrapTemplate( 1471 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1472 Build()). 1473 WithWorkerMachinePoolClasses( 1474 *builder.MachinePoolClass("aa"). 1475 WithInfrastructureTemplate( 1476 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1477 WithBootstrapTemplate( 1478 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1479 Build(), 1480 *builder.MachinePoolClass("BB"). 1481 WithInfrastructureTemplate( 1482 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1483 WithBootstrapTemplate( 1484 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1485 Build()). 1486 Build(), 1487 expectErr: false, 1488 }, 1489 { 1490 name: "update fails if a duplicated machine deployment class gets added", 1491 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1492 WithInfrastructureClusterTemplate( 1493 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1494 WithControlPlaneTemplate( 1495 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1496 Build()). 1497 WithControlPlaneInfrastructureMachineTemplate( 1498 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1499 Build()). 1500 WithWorkerMachineDeploymentClasses( 1501 *builder.MachineDeploymentClass("aa"). 1502 WithInfrastructureTemplate( 1503 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1504 WithBootstrapTemplate( 1505 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1506 Build()). 1507 Build(), 1508 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1509 WithInfrastructureClusterTemplate( 1510 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1511 WithControlPlaneTemplate( 1512 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1513 Build()). 1514 WithControlPlaneInfrastructureMachineTemplate( 1515 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1516 Build()). 1517 WithWorkerMachineDeploymentClasses( 1518 *builder.MachineDeploymentClass("aa"). 1519 WithInfrastructureTemplate( 1520 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1521 WithBootstrapTemplate( 1522 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()).Build(), 1523 *builder.MachineDeploymentClass("aa"). 1524 WithInfrastructureTemplate( 1525 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1526 WithBootstrapTemplate( 1527 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1528 Build()). 1529 Build(), 1530 expectErr: true, 1531 }, 1532 { 1533 name: "update fails if a duplicated machine pool class gets added", 1534 old: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1535 WithInfrastructureClusterTemplate( 1536 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1537 WithControlPlaneTemplate( 1538 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1539 Build()). 1540 WithControlPlaneInfrastructureMachineTemplate( 1541 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1542 Build()). 1543 WithWorkerMachinePoolClasses( 1544 *builder.MachinePoolClass("aa"). 1545 WithInfrastructureTemplate( 1546 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1547 WithBootstrapTemplate( 1548 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1549 Build()). 1550 Build(), 1551 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1552 WithInfrastructureClusterTemplate( 1553 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1554 WithControlPlaneTemplate( 1555 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1556 Build()). 1557 WithControlPlaneInfrastructureMachineTemplate( 1558 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1559 Build()). 1560 WithWorkerMachinePoolClasses( 1561 *builder.MachinePoolClass("aa"). 1562 WithInfrastructureTemplate( 1563 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1564 WithBootstrapTemplate( 1565 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()).Build(), 1566 *builder.MachinePoolClass("aa"). 1567 WithInfrastructureTemplate( 1568 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1569 WithBootstrapTemplate( 1570 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1571 Build()). 1572 Build(), 1573 expectErr: true, 1574 }, 1575 { 1576 name: "should return error for invalid machine deployment labels and annotations", 1577 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1578 WithInfrastructureClusterTemplate( 1579 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1580 WithControlPlaneTemplate( 1581 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1582 Build()). 1583 WithControlPlaneInfrastructureMachineTemplate( 1584 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1585 Build()). 1586 WithWorkerMachineDeploymentClasses( 1587 *builder.MachineDeploymentClass("aa"). 1588 WithInfrastructureTemplate( 1589 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1590 WithBootstrapTemplate( 1591 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1592 WithLabels(invalidLabels()). 1593 WithAnnotations(invalidAnnotations()). 1594 Build()). 1595 WithControlPlaneMetadata(invalidLabels(), invalidAnnotations()). 1596 Build(), 1597 expectErr: true, 1598 }, 1599 { 1600 name: "should return error for invalid machine pool labels and annotations", 1601 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1602 WithInfrastructureClusterTemplate( 1603 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1604 WithControlPlaneTemplate( 1605 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1606 Build()). 1607 WithControlPlaneInfrastructureMachineTemplate( 1608 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1609 Build()). 1610 WithWorkerMachinePoolClasses( 1611 *builder.MachinePoolClass("aa"). 1612 WithInfrastructureTemplate( 1613 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1614 WithBootstrapTemplate( 1615 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1616 WithLabels(invalidLabels()). 1617 WithAnnotations(invalidAnnotations()). 1618 Build()). 1619 WithControlPlaneMetadata(invalidLabels(), invalidAnnotations()). 1620 Build(), 1621 expectErr: true, 1622 }, 1623 { 1624 name: "should not return error for valid namingStrategy.template", 1625 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1626 WithInfrastructureClusterTemplate( 1627 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1628 WithControlPlaneTemplate( 1629 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1630 Build()). 1631 WithControlPlaneNamingStrategy(&clusterv1.ControlPlaneClassNamingStrategy{Template: ptr.To("{{ .cluster.name }}-cp-{{ .random }}")}). 1632 WithControlPlaneInfrastructureMachineTemplate( 1633 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1634 Build()). 1635 WithWorkerMachineDeploymentClasses( 1636 *builder.MachineDeploymentClass("aa"). 1637 WithInfrastructureTemplate( 1638 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1639 WithBootstrapTemplate( 1640 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1641 WithNamingStrategy(&clusterv1.MachineDeploymentClassNamingStrategy{Template: ptr.To("{{ .cluster.name }}-md-{{ .machineDeployment.topologyName }}-{{ .random }}")}). 1642 Build()). 1643 WithWorkerMachinePoolClasses( 1644 *builder.MachinePoolClass("bb"). 1645 WithInfrastructureTemplate( 1646 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra2").Build()). 1647 WithBootstrapTemplate( 1648 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap2").Build()). 1649 WithNamingStrategy(&clusterv1.MachinePoolClassNamingStrategy{Template: ptr.To("{{ .cluster.name }}-md-{{ .machinePool.topologyName }}-{{ .random }}")}). 1650 Build()). 1651 Build(), 1652 expectErr: false, 1653 }, 1654 { 1655 name: "should return error for invalid ControlPlane namingStrategy.template", 1656 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1657 WithInfrastructureClusterTemplate( 1658 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1659 WithControlPlaneTemplate( 1660 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1661 Build()). 1662 WithControlPlaneNamingStrategy(&clusterv1.ControlPlaneClassNamingStrategy{Template: ptr.To("template-cp-{{ .invalidkey }}")}). 1663 WithControlPlaneInfrastructureMachineTemplate( 1664 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1665 Build()). 1666 Build(), 1667 expectErr: true, 1668 }, 1669 { 1670 name: "should return error for ControlPlane namingStrategy.template when the generated name does not conform to RFC 1123", 1671 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1672 WithInfrastructureClusterTemplate( 1673 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1674 WithControlPlaneTemplate( 1675 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1676 Build()). 1677 WithControlPlaneNamingStrategy(&clusterv1.ControlPlaneClassNamingStrategy{Template: ptr.To("template-cp-{{ .cluster.name }}-")}). 1678 WithControlPlaneInfrastructureMachineTemplate( 1679 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1680 Build()). 1681 Build(), 1682 expectErr: true, 1683 }, 1684 { 1685 name: "should return error for invalid MachineDeployment namingStrategy.template", 1686 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1687 WithInfrastructureClusterTemplate( 1688 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1689 WithControlPlaneTemplate( 1690 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1691 Build()). 1692 WithControlPlaneInfrastructureMachineTemplate( 1693 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1694 Build()). 1695 WithWorkerMachineDeploymentClasses( 1696 *builder.MachineDeploymentClass("aa"). 1697 WithInfrastructureTemplate( 1698 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1699 WithBootstrapTemplate( 1700 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1701 WithNamingStrategy(&clusterv1.MachineDeploymentClassNamingStrategy{Template: ptr.To("template-md-{{ .cluster.name")}). 1702 Build()). 1703 Build(), 1704 expectErr: true, 1705 }, 1706 { 1707 name: "should return error for invalid MachineDeployment namingStrategy.template when the generated name does not conform to RFC 1123", 1708 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1709 WithInfrastructureClusterTemplate( 1710 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1711 WithControlPlaneTemplate( 1712 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1713 Build()). 1714 WithControlPlaneInfrastructureMachineTemplate( 1715 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1716 Build()). 1717 WithWorkerMachineDeploymentClasses( 1718 *builder.MachineDeploymentClass("aa"). 1719 WithInfrastructureTemplate( 1720 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1721 WithBootstrapTemplate( 1722 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1723 WithNamingStrategy(&clusterv1.MachineDeploymentClassNamingStrategy{Template: ptr.To("template-md-{{ .cluster.name }}-")}). 1724 Build()). 1725 Build(), 1726 expectErr: true, 1727 }, 1728 { 1729 name: "should return error for invalid MachinePool namingStrategy.template", 1730 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1731 WithInfrastructureClusterTemplate( 1732 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1733 WithControlPlaneTemplate( 1734 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1735 Build()). 1736 WithControlPlaneInfrastructureMachineTemplate( 1737 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1738 Build()). 1739 WithWorkerMachinePoolClasses( 1740 *builder.MachinePoolClass("bb"). 1741 WithInfrastructureTemplate( 1742 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra2").Build()). 1743 WithBootstrapTemplate( 1744 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap2").Build()). 1745 WithNamingStrategy(&clusterv1.MachinePoolClassNamingStrategy{Template: ptr.To("template-mp-{{ .cluster.name")}). 1746 Build()). 1747 Build(), 1748 expectErr: true, 1749 }, 1750 { 1751 name: "should return error for invalid MachinePool namingStrategy.template when the generated name does not conform to RFC 1123", 1752 in: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1753 WithInfrastructureClusterTemplate( 1754 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "infra1").Build()). 1755 WithControlPlaneTemplate( 1756 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1757 Build()). 1758 WithControlPlaneInfrastructureMachineTemplate( 1759 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "cpInfra1"). 1760 Build()). 1761 WithWorkerMachinePoolClasses( 1762 *builder.MachinePoolClass("bb"). 1763 WithInfrastructureTemplate( 1764 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra2").Build()). 1765 WithBootstrapTemplate( 1766 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap2").Build()). 1767 WithNamingStrategy(&clusterv1.MachinePoolClassNamingStrategy{Template: ptr.To("template-mp-{{ .cluster.name }}-")}). 1768 Build()). 1769 Build(), 1770 expectErr: true, 1771 }, 1772 } 1773 1774 for _, tt := range tests { 1775 t.Run(tt.name, func(t *testing.T) { 1776 g := NewWithT(t) 1777 1778 // Sets up the fakeClient for the test case. 1779 fakeClient := fake.NewClientBuilder(). 1780 WithScheme(fakeScheme). 1781 WithIndex(&clusterv1.Cluster{}, index.ClusterClassNameField, index.ClusterByClusterClassClassName). 1782 Build() 1783 1784 // Create the webhook and add the fakeClient as its client. 1785 webhook := &ClusterClass{Client: fakeClient} 1786 err := webhook.validate(ctx, tt.old, tt.in) 1787 if tt.expectErr { 1788 g.Expect(err).To(HaveOccurred()) 1789 return 1790 } 1791 g.Expect(err).ToNot(HaveOccurred()) 1792 }) 1793 } 1794 } 1795 1796 func TestClusterClassValidationWithClusterAwareChecks(t *testing.T) { 1797 // NOTE: ClusterTopology feature flag is disabled by default, thus preventing to create or update ClusterClasses. 1798 // Enabling the feature flag temporarily for this test. 1799 defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, feature.ClusterTopology, true)() 1800 1801 tests := []struct { 1802 name string 1803 oldClusterClass *clusterv1.ClusterClass 1804 newClusterClass *clusterv1.ClusterClass 1805 clusters []client.Object 1806 expectErr bool 1807 }{ 1808 { 1809 name: "pass if a MachineDeploymentClass or MachinePoolClass not in use gets removed", 1810 clusters: []client.Object{ 1811 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 1812 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 1813 WithTopology( 1814 builder.ClusterTopology(). 1815 WithClass("class1"). 1816 WithMachineDeployment( 1817 builder.MachineDeploymentTopology("workers1"). 1818 WithClass("bb"). 1819 Build(), 1820 ). 1821 Build()). 1822 Build(), 1823 }, 1824 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1825 WithInfrastructureClusterTemplate( 1826 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 1827 WithControlPlaneTemplate( 1828 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1829 Build()). 1830 WithWorkerMachineDeploymentClasses( 1831 *builder.MachineDeploymentClass("aa"). 1832 WithInfrastructureTemplate( 1833 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1834 WithBootstrapTemplate( 1835 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1836 Build(), 1837 *builder.MachineDeploymentClass("bb"). 1838 WithInfrastructureTemplate( 1839 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1840 WithBootstrapTemplate( 1841 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1842 Build()). 1843 WithWorkerMachinePoolClasses( 1844 *builder.MachinePoolClass("aa"). 1845 WithInfrastructureTemplate( 1846 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1847 WithBootstrapTemplate( 1848 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1849 Build(), 1850 *builder.MachinePoolClass("bb"). 1851 WithInfrastructureTemplate( 1852 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1853 WithBootstrapTemplate( 1854 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1855 Build()). 1856 Build(), 1857 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1858 WithInfrastructureClusterTemplate( 1859 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 1860 WithControlPlaneTemplate( 1861 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1862 Build()). 1863 WithWorkerMachineDeploymentClasses( 1864 *builder.MachineDeploymentClass("bb"). 1865 WithInfrastructureTemplate( 1866 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1867 WithBootstrapTemplate( 1868 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1869 Build()). 1870 WithWorkerMachinePoolClasses( 1871 *builder.MachinePoolClass("bb"). 1872 WithInfrastructureTemplate( 1873 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1874 WithBootstrapTemplate( 1875 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1876 Build()). 1877 Build(), 1878 expectErr: false, 1879 }, 1880 { 1881 name: "error if a MachineDeploymentClass in use gets removed", 1882 clusters: []client.Object{ 1883 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 1884 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 1885 WithTopology( 1886 builder.ClusterTopology(). 1887 WithClass("class1"). 1888 WithMachineDeployment( 1889 builder.MachineDeploymentTopology("workers1"). 1890 WithClass("bb"). 1891 Build(), 1892 ). 1893 Build()). 1894 Build(), 1895 }, 1896 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1897 WithInfrastructureClusterTemplate( 1898 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 1899 WithControlPlaneTemplate( 1900 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1901 Build()). 1902 WithWorkerMachineDeploymentClasses( 1903 *builder.MachineDeploymentClass("aa"). 1904 WithInfrastructureTemplate( 1905 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1906 WithBootstrapTemplate( 1907 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1908 Build(), 1909 *builder.MachineDeploymentClass("bb"). 1910 WithInfrastructureTemplate( 1911 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1912 WithBootstrapTemplate( 1913 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1914 Build()). 1915 Build(), 1916 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1917 WithInfrastructureClusterTemplate( 1918 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 1919 WithControlPlaneTemplate( 1920 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1921 Build()). 1922 WithWorkerMachineDeploymentClasses( 1923 *builder.MachineDeploymentClass("aa"). 1924 WithInfrastructureTemplate( 1925 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 1926 WithBootstrapTemplate( 1927 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1928 Build()). 1929 Build(), 1930 expectErr: true, 1931 }, 1932 { 1933 name: "error if a MachinePoolClass in use gets removed", 1934 clusters: []client.Object{ 1935 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 1936 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 1937 WithTopology( 1938 builder.ClusterTopology(). 1939 WithClass("class1"). 1940 WithMachinePool( 1941 builder.MachinePoolTopology("workers1"). 1942 WithClass("bb"). 1943 Build(), 1944 ). 1945 Build()). 1946 Build(), 1947 }, 1948 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1949 WithInfrastructureClusterTemplate( 1950 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 1951 WithControlPlaneTemplate( 1952 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1953 Build()). 1954 WithWorkerMachinePoolClasses( 1955 *builder.MachinePoolClass("aa"). 1956 WithInfrastructureTemplate( 1957 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1958 WithBootstrapTemplate( 1959 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1960 Build(), 1961 *builder.MachinePoolClass("bb"). 1962 WithInfrastructureTemplate( 1963 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1964 WithBootstrapTemplate( 1965 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1966 Build()). 1967 Build(), 1968 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 1969 WithInfrastructureClusterTemplate( 1970 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 1971 WithControlPlaneTemplate( 1972 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 1973 Build()). 1974 WithWorkerMachinePoolClasses( 1975 *builder.MachinePoolClass("aa"). 1976 WithInfrastructureTemplate( 1977 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 1978 WithBootstrapTemplate( 1979 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 1980 Build()). 1981 Build(), 1982 expectErr: true, 1983 }, 1984 { 1985 name: "error if many MachineDeploymentClasses, used in multiple Clusters using the modified ClusterClass, are removed", 1986 clusters: []client.Object{ 1987 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 1988 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 1989 WithTopology( 1990 builder.ClusterTopology(). 1991 WithClass("class1"). 1992 WithMachineDeployment( 1993 builder.MachineDeploymentTopology("workers1"). 1994 WithClass("bb"). 1995 Build(), 1996 ). 1997 WithMachineDeployment( 1998 builder.MachineDeploymentTopology("workers2"). 1999 WithClass("aa"). 2000 Build(), 2001 ). 2002 Build()). 2003 Build(), 2004 builder.Cluster(metav1.NamespaceDefault, "cluster2"). 2005 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 2006 WithTopology( 2007 builder.ClusterTopology(). 2008 WithClass("class1"). 2009 WithMachineDeployment( 2010 builder.MachineDeploymentTopology("workers1"). 2011 WithClass("aa"). 2012 Build(), 2013 ). 2014 WithMachineDeployment( 2015 builder.MachineDeploymentTopology("workers2"). 2016 WithClass("aa"). 2017 Build(), 2018 ). 2019 Build()). 2020 Build(), 2021 builder.Cluster(metav1.NamespaceDefault, "cluster3"). 2022 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 2023 WithTopology( 2024 builder.ClusterTopology(). 2025 WithClass("class1"). 2026 WithMachineDeployment( 2027 builder.MachineDeploymentTopology("workers1"). 2028 WithClass("bb"). 2029 Build(), 2030 ). 2031 Build()). 2032 Build(), 2033 }, 2034 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 2035 WithInfrastructureClusterTemplate( 2036 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2037 WithControlPlaneTemplate( 2038 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2039 Build()). 2040 WithWorkerMachineDeploymentClasses( 2041 *builder.MachineDeploymentClass("aa"). 2042 WithInfrastructureTemplate( 2043 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2044 WithBootstrapTemplate( 2045 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2046 Build(), 2047 *builder.MachineDeploymentClass("bb"). 2048 WithInfrastructureTemplate( 2049 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2050 WithBootstrapTemplate( 2051 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2052 Build()). 2053 Build(), 2054 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 2055 WithInfrastructureClusterTemplate( 2056 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2057 WithControlPlaneTemplate( 2058 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2059 Build()). 2060 WithWorkerMachineDeploymentClasses( 2061 *builder.MachineDeploymentClass("bb"). 2062 WithInfrastructureTemplate( 2063 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2064 WithBootstrapTemplate( 2065 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2066 Build()). 2067 Build(), 2068 expectErr: true, 2069 }, 2070 { 2071 name: "error if many MachinePoolClasses, used in multiple Clusters using the modified ClusterClass, are removed", 2072 clusters: []client.Object{ 2073 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2074 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 2075 WithTopology( 2076 builder.ClusterTopology(). 2077 WithClass("class1"). 2078 WithMachinePool( 2079 builder.MachinePoolTopology("workers1"). 2080 WithClass("bb"). 2081 Build(), 2082 ). 2083 WithMachinePool( 2084 builder.MachinePoolTopology("workers2"). 2085 WithClass("aa"). 2086 Build(), 2087 ). 2088 Build()). 2089 Build(), 2090 builder.Cluster(metav1.NamespaceDefault, "cluster2"). 2091 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 2092 WithTopology( 2093 builder.ClusterTopology(). 2094 WithClass("class1"). 2095 WithMachinePool( 2096 builder.MachinePoolTopology("workers1"). 2097 WithClass("aa"). 2098 Build(), 2099 ). 2100 WithMachinePool( 2101 builder.MachinePoolTopology("workers2"). 2102 WithClass("aa"). 2103 Build(), 2104 ). 2105 Build()). 2106 Build(), 2107 builder.Cluster(metav1.NamespaceDefault, "cluster3"). 2108 WithLabels(map[string]string{clusterv1.ClusterTopologyOwnedLabel: ""}). 2109 WithTopology( 2110 builder.ClusterTopology(). 2111 WithClass("class1"). 2112 WithMachinePool( 2113 builder.MachinePoolTopology("workers1"). 2114 WithClass("bb"). 2115 Build(), 2116 ). 2117 Build()). 2118 Build(), 2119 }, 2120 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 2121 WithInfrastructureClusterTemplate( 2122 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2123 WithControlPlaneTemplate( 2124 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2125 Build()). 2126 WithWorkerMachinePoolClasses( 2127 *builder.MachinePoolClass("aa"). 2128 WithInfrastructureTemplate( 2129 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 2130 WithBootstrapTemplate( 2131 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2132 Build(), 2133 *builder.MachinePoolClass("bb"). 2134 WithInfrastructureTemplate( 2135 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 2136 WithBootstrapTemplate( 2137 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2138 Build()). 2139 Build(), 2140 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1"). 2141 WithInfrastructureClusterTemplate( 2142 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2143 WithControlPlaneTemplate( 2144 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2145 Build()). 2146 WithWorkerMachinePoolClasses( 2147 *builder.MachinePoolClass("bb"). 2148 WithInfrastructureTemplate( 2149 builder.InfrastructureMachinePoolTemplate(metav1.NamespaceDefault, "infra1").Build()). 2150 WithBootstrapTemplate( 2151 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2152 Build()). 2153 Build(), 2154 expectErr: true, 2155 }, 2156 { 2157 name: "error if a control plane MachineHealthCheck that is in use by a cluster is removed", 2158 clusters: []client.Object{ 2159 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2160 WithTopology(builder.ClusterTopology(). 2161 WithClass("clusterclass1"). 2162 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckTopology{ 2163 Enable: ptr.To(true), 2164 }). 2165 Build()). 2166 Build(), 2167 }, 2168 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2169 WithInfrastructureClusterTemplate( 2170 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2171 WithControlPlaneTemplate( 2172 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2173 Build()). 2174 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckClass{ 2175 UnhealthyConditions: []clusterv1.UnhealthyCondition{ 2176 { 2177 Type: corev1.NodeReady, 2178 Status: corev1.ConditionUnknown, 2179 Timeout: metav1.Duration{Duration: 5 * time.Minute}, 2180 }, 2181 }, 2182 }). 2183 Build(), 2184 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2185 WithInfrastructureClusterTemplate( 2186 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2187 WithControlPlaneTemplate( 2188 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2189 Build()). 2190 Build(), 2191 expectErr: true, 2192 }, 2193 { 2194 name: "pass if a control plane MachineHealthCheck is removed but no cluster enforces it", 2195 clusters: []client.Object{ 2196 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2197 WithTopology(builder.ClusterTopology(). 2198 WithClass("clusterclass1"). 2199 Build()). 2200 Build(), 2201 }, 2202 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2203 WithInfrastructureClusterTemplate( 2204 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2205 WithControlPlaneTemplate( 2206 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2207 Build()). 2208 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckClass{}). 2209 Build(), 2210 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2211 WithInfrastructureClusterTemplate( 2212 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2213 WithControlPlaneTemplate( 2214 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2215 Build()). 2216 Build(), 2217 expectErr: false, 2218 }, 2219 { 2220 name: "pass if a control plane MachineHealthCheck is removed when clusters are not using it (clusters have overrides in topology)", 2221 clusters: []client.Object{ 2222 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2223 WithTopology(builder.ClusterTopology(). 2224 WithClass("clusterclass1"). 2225 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckTopology{ 2226 Enable: ptr.To(true), 2227 MachineHealthCheckClass: clusterv1.MachineHealthCheckClass{ 2228 UnhealthyConditions: []clusterv1.UnhealthyCondition{ 2229 { 2230 Type: corev1.NodeReady, 2231 Status: corev1.ConditionUnknown, 2232 Timeout: metav1.Duration{Duration: 5 * time.Minute}, 2233 }, 2234 }, 2235 }, 2236 }). 2237 Build()). 2238 Build(), 2239 }, 2240 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2241 WithInfrastructureClusterTemplate( 2242 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2243 WithControlPlaneTemplate( 2244 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2245 Build()). 2246 WithControlPlaneMachineHealthCheck(&clusterv1.MachineHealthCheckClass{}). 2247 Build(), 2248 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2249 WithInfrastructureClusterTemplate( 2250 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2251 WithControlPlaneTemplate( 2252 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2253 Build()). 2254 Build(), 2255 expectErr: false, 2256 }, 2257 { 2258 name: "error if a MachineDeployment MachineHealthCheck that is in use by a cluster is removed", 2259 clusters: []client.Object{ 2260 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2261 WithTopology(builder.ClusterTopology(). 2262 WithClass("clusterclass1"). 2263 WithMachineDeployment(builder.MachineDeploymentTopology("md1"). 2264 WithClass("mdclass1"). 2265 WithMachineHealthCheck(&clusterv1.MachineHealthCheckTopology{ 2266 Enable: ptr.To(true), 2267 }). 2268 Build()). 2269 Build()). 2270 Build(), 2271 }, 2272 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2273 WithInfrastructureClusterTemplate( 2274 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2275 WithControlPlaneTemplate( 2276 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2277 Build()). 2278 WithWorkerMachineDeploymentClasses( 2279 *builder.MachineDeploymentClass("mdclass1"). 2280 WithInfrastructureTemplate( 2281 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2282 WithBootstrapTemplate( 2283 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2284 WithMachineHealthCheckClass(&clusterv1.MachineHealthCheckClass{}). 2285 Build(), 2286 ). 2287 Build(), 2288 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2289 WithInfrastructureClusterTemplate( 2290 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2291 WithControlPlaneTemplate( 2292 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2293 Build()). 2294 WithWorkerMachineDeploymentClasses( 2295 *builder.MachineDeploymentClass("mdclass1"). 2296 WithInfrastructureTemplate( 2297 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2298 WithBootstrapTemplate( 2299 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2300 Build(), 2301 ). 2302 Build(), 2303 expectErr: true, 2304 }, 2305 { 2306 name: "pass if a MachineDeployment MachineHealthCheck is removed but no cluster enforces it", 2307 clusters: []client.Object{ 2308 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2309 WithTopology(builder.ClusterTopology(). 2310 WithClass("clusterclass1"). 2311 WithMachineDeployment(builder.MachineDeploymentTopology("md1"). 2312 WithClass("mdclass1"). 2313 Build()). 2314 Build()). 2315 Build(), 2316 }, 2317 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2318 WithInfrastructureClusterTemplate( 2319 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2320 WithControlPlaneTemplate( 2321 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2322 Build()). 2323 WithWorkerMachineDeploymentClasses( 2324 *builder.MachineDeploymentClass("mdclass1"). 2325 WithInfrastructureTemplate( 2326 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2327 WithBootstrapTemplate( 2328 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2329 WithMachineHealthCheckClass(&clusterv1.MachineHealthCheckClass{}). 2330 Build(), 2331 ). 2332 Build(), 2333 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2334 WithInfrastructureClusterTemplate( 2335 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2336 WithControlPlaneTemplate( 2337 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2338 Build()). 2339 WithWorkerMachineDeploymentClasses( 2340 *builder.MachineDeploymentClass("mdclass1"). 2341 WithInfrastructureTemplate( 2342 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2343 WithBootstrapTemplate( 2344 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2345 Build(), 2346 ). 2347 Build(), 2348 expectErr: false, 2349 }, 2350 { 2351 name: "pass if a MachineDeployment MachineHealthCheck is removed when clusters are not using it (clusters have overrides in topology)", 2352 clusters: []client.Object{ 2353 builder.Cluster(metav1.NamespaceDefault, "cluster1"). 2354 WithTopology(builder.ClusterTopology(). 2355 WithClass("clusterclass1"). 2356 WithMachineDeployment(builder.MachineDeploymentTopology("md1"). 2357 WithClass("mdclass1"). 2358 WithMachineHealthCheck(&clusterv1.MachineHealthCheckTopology{ 2359 Enable: ptr.To(true), 2360 MachineHealthCheckClass: clusterv1.MachineHealthCheckClass{ 2361 UnhealthyConditions: []clusterv1.UnhealthyCondition{ 2362 { 2363 Type: corev1.NodeReady, 2364 Status: corev1.ConditionUnknown, 2365 Timeout: metav1.Duration{Duration: 5 * time.Minute}, 2366 }, 2367 }, 2368 }, 2369 }). 2370 Build()). 2371 Build()). 2372 Build(), 2373 }, 2374 oldClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2375 WithInfrastructureClusterTemplate( 2376 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2377 WithControlPlaneTemplate( 2378 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2379 Build()). 2380 WithWorkerMachineDeploymentClasses( 2381 *builder.MachineDeploymentClass("mdclass1"). 2382 WithInfrastructureTemplate( 2383 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2384 WithBootstrapTemplate( 2385 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2386 WithMachineHealthCheckClass(&clusterv1.MachineHealthCheckClass{}). 2387 Build(), 2388 ). 2389 Build(), 2390 newClusterClass: builder.ClusterClass(metav1.NamespaceDefault, "clusterclass1"). 2391 WithInfrastructureClusterTemplate( 2392 builder.InfrastructureClusterTemplate(metav1.NamespaceDefault, "inf").Build()). 2393 WithControlPlaneTemplate( 2394 builder.ControlPlaneTemplate(metav1.NamespaceDefault, "cp1"). 2395 Build()). 2396 WithWorkerMachineDeploymentClasses( 2397 *builder.MachineDeploymentClass("mdclass1"). 2398 WithInfrastructureTemplate( 2399 builder.InfrastructureMachineTemplate(metav1.NamespaceDefault, "infra1").Build()). 2400 WithBootstrapTemplate( 2401 builder.BootstrapTemplate(metav1.NamespaceDefault, "bootstrap1").Build()). 2402 Build(), 2403 ). 2404 Build(), 2405 expectErr: false, 2406 }, 2407 } 2408 2409 for _, tt := range tests { 2410 t.Run(tt.name, func(t *testing.T) { 2411 g := NewWithT(t) 2412 2413 // Sets up the fakeClient for the test case. 2414 fakeClient := fake.NewClientBuilder(). 2415 WithScheme(fakeScheme). 2416 WithObjects(tt.clusters...). 2417 WithIndex(&clusterv1.Cluster{}, index.ClusterClassNameField, index.ClusterByClusterClassClassName). 2418 Build() 2419 2420 // Create the webhook and add the fakeClient as its client. 2421 webhook := &ClusterClass{Client: fakeClient} 2422 err := webhook.validate(ctx, tt.oldClusterClass, tt.newClusterClass) 2423 if tt.expectErr { 2424 g.Expect(err).To(HaveOccurred()) 2425 return 2426 } 2427 g.Expect(err).ToNot(HaveOccurred()) 2428 }) 2429 } 2430 } 2431 2432 func invalidLabels() map[string]string { 2433 return map[string]string{ 2434 "foo": "$invalid-key", 2435 "bar": strings.Repeat("a", 64) + "too-long-value", 2436 "/invalid-key": "foo", 2437 } 2438 } 2439 2440 func invalidAnnotations() map[string]string { 2441 return map[string]string{ 2442 "/invalid-key": "foo", 2443 } 2444 }