sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/scope/managedmachinepool_test.go (about) 1 /* 2 Copyright 2022 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 scope 18 19 import ( 20 "context" 21 "reflect" 22 "testing" 23 24 asocontainerservicev1 "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20231001" 25 "github.com/Azure/azure-service-operator/v2/pkg/genruntime" 26 "github.com/google/go-cmp/cmp" 27 . "github.com/onsi/gomega" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 "k8s.io/apimachinery/pkg/runtime" 30 "k8s.io/utils/ptr" 31 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 32 "sigs.k8s.io/cluster-api-provider-azure/azure" 33 "sigs.k8s.io/cluster-api-provider-azure/azure/services/agentpools" 34 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 35 expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" 36 "sigs.k8s.io/controller-runtime/pkg/client/fake" 37 ) 38 39 func TestManagedMachinePoolScope_Autoscaling(t *testing.T) { 40 scheme := runtime.NewScheme() 41 _ = expv1.AddToScheme(scheme) 42 _ = infrav1.AddToScheme(scheme) 43 44 cases := []struct { 45 Name string 46 Input ManagedMachinePoolScopeParams 47 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 48 }{ 49 { 50 Name: "Without Autoscaling", 51 Input: ManagedMachinePoolScopeParams{ 52 Cluster: &clusterv1.Cluster{ 53 ObjectMeta: metav1.ObjectMeta{ 54 Name: "cluster1", 55 Namespace: "default", 56 }, 57 }, 58 ControlPlane: &infrav1.AzureManagedControlPlane{ 59 ObjectMeta: metav1.ObjectMeta{ 60 Name: "cluster1", 61 Namespace: "default", 62 }, 63 Spec: infrav1.AzureManagedControlPlaneSpec{ 64 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 65 SubscriptionID: "00000000-0000-0000-0000-000000000000", 66 }, 67 }, 68 }, 69 ManagedMachinePool: ManagedMachinePool{ 70 MachinePool: getMachinePool("pool0"), 71 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 72 }, 73 }, 74 Expected: &agentpools.AgentPoolSpec{ 75 76 Name: "pool0", 77 AzureName: "pool0", 78 SKU: "Standard_D2s_v3", 79 Replicas: 1, 80 Mode: "System", 81 Cluster: "cluster1", 82 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 83 }, 84 }, 85 { 86 Name: "With Autoscaling", 87 Input: ManagedMachinePoolScopeParams{ 88 Cluster: &clusterv1.Cluster{ 89 ObjectMeta: metav1.ObjectMeta{ 90 Name: "cluster1", 91 Namespace: "default", 92 }, 93 }, 94 ControlPlane: &infrav1.AzureManagedControlPlane{ 95 ObjectMeta: metav1.ObjectMeta{ 96 Name: "cluster1", 97 Namespace: "default", 98 }, 99 Spec: infrav1.AzureManagedControlPlaneSpec{ 100 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 101 SubscriptionID: "00000000-0000-0000-0000-000000000000", 102 }, 103 }, 104 }, 105 ManagedMachinePool: ManagedMachinePool{ 106 MachinePool: getMachinePool("pool1"), 107 InfraMachinePool: getAzureMachinePoolWithScaling("pool1", 2, 10), 108 }, 109 }, 110 Expected: &agentpools.AgentPoolSpec{ 111 Name: "pool1", 112 AzureName: "pool1", 113 SKU: "Standard_D2s_v3", 114 Mode: "User", 115 Cluster: "cluster1", 116 Replicas: 1, 117 EnableAutoScaling: true, 118 MinCount: ptr.To(2), 119 MaxCount: ptr.To(10), 120 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 121 }, 122 }, 123 } 124 125 for _, c := range cases { 126 c := c 127 t.Run(c.Name, func(t *testing.T) { 128 g := NewWithT(t) 129 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 130 c.Input.Client = fakeClient 131 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 132 g.Expect(err).To(Succeed()) 133 agentPool := s.AgentPoolSpec() 134 if !reflect.DeepEqual(c.Expected, agentPool) { 135 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 136 } 137 }) 138 } 139 } 140 141 func TestManagedMachinePoolScope_NodeLabels(t *testing.T) { 142 scheme := runtime.NewScheme() 143 _ = expv1.AddToScheme(scheme) 144 _ = infrav1.AddToScheme(scheme) 145 146 cases := []struct { 147 Name string 148 Input ManagedMachinePoolScopeParams 149 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 150 }{ 151 { 152 Name: "Without node labels", 153 Input: ManagedMachinePoolScopeParams{ 154 Cluster: &clusterv1.Cluster{ 155 ObjectMeta: metav1.ObjectMeta{ 156 Name: "cluster1", 157 Namespace: "default", 158 }, 159 }, 160 ControlPlane: &infrav1.AzureManagedControlPlane{ 161 ObjectMeta: metav1.ObjectMeta{ 162 Name: "cluster1", 163 Namespace: "default", 164 }, 165 Spec: infrav1.AzureManagedControlPlaneSpec{ 166 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 167 SubscriptionID: "00000000-0000-0000-0000-000000000000", 168 }, 169 }, 170 }, 171 ManagedMachinePool: ManagedMachinePool{ 172 MachinePool: getMachinePool("pool0"), 173 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 174 }, 175 }, 176 Expected: &agentpools.AgentPoolSpec{ 177 Name: "pool0", 178 AzureName: "pool0", 179 SKU: "Standard_D2s_v3", 180 Replicas: 1, 181 Mode: "System", 182 Cluster: "cluster1", 183 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 184 }, 185 }, 186 { 187 Name: "With node labels", 188 Input: ManagedMachinePoolScopeParams{ 189 Cluster: &clusterv1.Cluster{ 190 ObjectMeta: metav1.ObjectMeta{ 191 Name: "cluster1", 192 Namespace: "default", 193 }, 194 }, 195 ControlPlane: &infrav1.AzureManagedControlPlane{ 196 ObjectMeta: metav1.ObjectMeta{ 197 Name: "cluster1", 198 Namespace: "default", 199 }, 200 Spec: infrav1.AzureManagedControlPlaneSpec{ 201 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 202 SubscriptionID: "00000000-0000-0000-0000-000000000000", 203 }, 204 }, 205 }, 206 ManagedMachinePool: ManagedMachinePool{ 207 MachinePool: getMachinePool("pool1"), 208 InfraMachinePool: getAzureMachinePoolWithLabels("pool1", map[string]string{ 209 "custom": "default", 210 }), 211 }, 212 }, 213 Expected: &agentpools.AgentPoolSpec{ 214 Name: "pool1", 215 AzureName: "pool1", 216 SKU: "Standard_D2s_v3", 217 Mode: "System", 218 Cluster: "cluster1", 219 Replicas: 1, 220 NodeLabels: map[string]string{ 221 "custom": "default", 222 }, 223 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 224 }, 225 }, 226 } 227 228 for _, c := range cases { 229 c := c 230 t.Run(c.Name, func(t *testing.T) { 231 g := NewWithT(t) 232 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 233 c.Input.Client = fakeClient 234 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 235 g.Expect(err).To(Succeed()) 236 agentPool := s.AgentPoolSpec() 237 if !reflect.DeepEqual(c.Expected, agentPool) { 238 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 239 } 240 }) 241 } 242 } 243 244 func TestManagedMachinePoolScope_AdditionalTags(t *testing.T) { 245 scheme := runtime.NewScheme() 246 _ = expv1.AddToScheme(scheme) 247 _ = infrav1.AddToScheme(scheme) 248 249 cases := []struct { 250 Name string 251 Input ManagedMachinePoolScopeParams 252 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 253 }{ 254 { 255 Name: "Without additional tags", 256 Input: ManagedMachinePoolScopeParams{ 257 Cluster: &clusterv1.Cluster{ 258 ObjectMeta: metav1.ObjectMeta{ 259 Name: "cluster1", 260 Namespace: "default", 261 }, 262 }, 263 ControlPlane: &infrav1.AzureManagedControlPlane{ 264 ObjectMeta: metav1.ObjectMeta{ 265 Name: "cluster1", 266 Namespace: "default", 267 }, 268 Spec: infrav1.AzureManagedControlPlaneSpec{ 269 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 270 SubscriptionID: "00000000-0000-0000-0000-000000000000", 271 }, 272 }, 273 }, 274 ManagedMachinePool: ManagedMachinePool{ 275 MachinePool: getMachinePool("pool0"), 276 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 277 }, 278 }, 279 Expected: &agentpools.AgentPoolSpec{ 280 Name: "pool0", 281 AzureName: "pool0", 282 SKU: "Standard_D2s_v3", 283 Replicas: 1, 284 Mode: "System", 285 Cluster: "cluster1", 286 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 287 }, 288 }, 289 { 290 Name: "With additional tags", 291 Input: ManagedMachinePoolScopeParams{ 292 Cluster: &clusterv1.Cluster{ 293 ObjectMeta: metav1.ObjectMeta{ 294 Name: "cluster1", 295 Namespace: "default", 296 }, 297 }, 298 ControlPlane: &infrav1.AzureManagedControlPlane{ 299 ObjectMeta: metav1.ObjectMeta{ 300 Name: "cluster1", 301 Namespace: "default", 302 }, 303 Spec: infrav1.AzureManagedControlPlaneSpec{ 304 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 305 SubscriptionID: "00000000-0000-0000-0000-000000000000", 306 }, 307 }, 308 }, 309 ManagedMachinePool: ManagedMachinePool{ 310 MachinePool: getMachinePool("pool1"), 311 InfraMachinePool: getAzureMachinePoolWithAdditionalTags("pool1", map[string]string{ 312 "environment": "production", 313 }), 314 }, 315 }, 316 Expected: &agentpools.AgentPoolSpec{ 317 Name: "pool1", 318 AzureName: "pool1", 319 SKU: "Standard_D2s_v3", 320 Mode: "System", 321 Cluster: "cluster1", 322 Replicas: 1, 323 AdditionalTags: map[string]string{ 324 "environment": "production", 325 }, 326 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 327 }, 328 }, 329 } 330 331 for _, c := range cases { 332 c := c 333 t.Run(c.Name, func(t *testing.T) { 334 g := NewWithT(t) 335 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 336 c.Input.Client = fakeClient 337 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 338 g.Expect(err).To(Succeed()) 339 agentPool := s.AgentPoolSpec() 340 if !reflect.DeepEqual(c.Expected, agentPool) { 341 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 342 } 343 }) 344 } 345 } 346 347 func TestManagedMachinePoolScope_MaxPods(t *testing.T) { 348 scheme := runtime.NewScheme() 349 _ = expv1.AddToScheme(scheme) 350 _ = infrav1.AddToScheme(scheme) 351 352 cases := []struct { 353 Name string 354 Input ManagedMachinePoolScopeParams 355 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 356 }{ 357 { 358 Name: "Without MaxPods", 359 Input: ManagedMachinePoolScopeParams{ 360 Cluster: &clusterv1.Cluster{ 361 ObjectMeta: metav1.ObjectMeta{ 362 Name: "cluster1", 363 Namespace: "default", 364 }, 365 }, 366 ControlPlane: &infrav1.AzureManagedControlPlane{ 367 ObjectMeta: metav1.ObjectMeta{ 368 Name: "cluster1", 369 Namespace: "default", 370 }, 371 Spec: infrav1.AzureManagedControlPlaneSpec{ 372 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 373 SubscriptionID: "00000000-0000-0000-0000-000000000000", 374 }, 375 }, 376 }, 377 ManagedMachinePool: ManagedMachinePool{ 378 MachinePool: getMachinePool("pool0"), 379 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 380 }, 381 }, 382 Expected: &agentpools.AgentPoolSpec{ 383 Name: "pool0", 384 AzureName: "pool0", 385 SKU: "Standard_D2s_v3", 386 Replicas: 1, 387 Mode: "System", 388 Cluster: "cluster1", 389 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 390 }, 391 }, 392 { 393 Name: "With MaxPods", 394 Input: ManagedMachinePoolScopeParams{ 395 Cluster: &clusterv1.Cluster{ 396 ObjectMeta: metav1.ObjectMeta{ 397 Name: "cluster1", 398 Namespace: "default", 399 }, 400 }, 401 ControlPlane: &infrav1.AzureManagedControlPlane{ 402 ObjectMeta: metav1.ObjectMeta{ 403 Name: "cluster1", 404 Namespace: "default", 405 }, 406 Spec: infrav1.AzureManagedControlPlaneSpec{ 407 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 408 SubscriptionID: "00000000-0000-0000-0000-000000000000", 409 }, 410 }, 411 }, 412 ManagedMachinePool: ManagedMachinePool{ 413 MachinePool: getMachinePool("pool1"), 414 InfraMachinePool: getAzureMachinePoolWithMaxPods("pool1", 12), 415 }, 416 }, 417 Expected: &agentpools.AgentPoolSpec{ 418 Name: "pool1", 419 AzureName: "pool1", 420 SKU: "Standard_D2s_v3", 421 Mode: "System", 422 Cluster: "cluster1", 423 Replicas: 1, 424 MaxPods: ptr.To(12), 425 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 426 }, 427 }, 428 } 429 430 for _, c := range cases { 431 c := c 432 t.Run(c.Name, func(t *testing.T) { 433 g := NewWithT(t) 434 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 435 c.Input.Client = fakeClient 436 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 437 g.Expect(err).To(Succeed()) 438 agentPool := s.AgentPoolSpec() 439 if !reflect.DeepEqual(c.Expected, agentPool) { 440 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 441 } 442 }) 443 } 444 } 445 446 func TestManagedMachinePoolScope_Taints(t *testing.T) { 447 scheme := runtime.NewScheme() 448 _ = expv1.AddToScheme(scheme) 449 _ = infrav1.AddToScheme(scheme) 450 451 cases := []struct { 452 Name string 453 Input ManagedMachinePoolScopeParams 454 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 455 }{ 456 { 457 Name: "Without taints", 458 Input: ManagedMachinePoolScopeParams{ 459 Cluster: &clusterv1.Cluster{ 460 ObjectMeta: metav1.ObjectMeta{ 461 Name: "cluster1", 462 Namespace: "default", 463 }, 464 }, 465 ControlPlane: &infrav1.AzureManagedControlPlane{ 466 ObjectMeta: metav1.ObjectMeta{ 467 Name: "cluster1", 468 Namespace: "default", 469 }, 470 Spec: infrav1.AzureManagedControlPlaneSpec{ 471 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 472 SubscriptionID: "00000000-0000-0000-0000-000000000000", 473 }, 474 }, 475 }, 476 ManagedMachinePool: ManagedMachinePool{ 477 MachinePool: getMachinePool("pool0"), 478 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 479 }, 480 }, 481 Expected: &agentpools.AgentPoolSpec{ 482 483 Name: "pool0", 484 AzureName: "pool0", 485 SKU: "Standard_D2s_v3", 486 Replicas: 1, 487 Mode: "System", 488 Cluster: "cluster1", 489 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 490 }, 491 }, 492 { 493 Name: "With taints", 494 Input: ManagedMachinePoolScopeParams{ 495 Cluster: &clusterv1.Cluster{ 496 ObjectMeta: metav1.ObjectMeta{ 497 Name: "cluster1", 498 Namespace: "default", 499 }, 500 }, 501 ControlPlane: &infrav1.AzureManagedControlPlane{ 502 ObjectMeta: metav1.ObjectMeta{ 503 Name: "cluster1", 504 Namespace: "default", 505 }, 506 Spec: infrav1.AzureManagedControlPlaneSpec{ 507 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 508 SubscriptionID: "00000000-0000-0000-0000-000000000000", 509 }, 510 }, 511 }, 512 ManagedMachinePool: ManagedMachinePool{ 513 MachinePool: getMachinePool("pool1"), 514 InfraMachinePool: getAzureMachinePoolWithTaints("pool1", infrav1.Taints{ 515 infrav1.Taint{ 516 Key: "key1", 517 Value: "value1", 518 Effect: "NoSchedule", 519 }, 520 }), 521 }, 522 }, 523 Expected: &agentpools.AgentPoolSpec{ 524 Name: "pool1", 525 AzureName: "pool1", 526 SKU: "Standard_D2s_v3", 527 Mode: "User", 528 Cluster: "cluster1", 529 Replicas: 1, 530 NodeTaints: []string{"key1=value1:NoSchedule"}, 531 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 532 }, 533 }, 534 } 535 536 for _, c := range cases { 537 c := c 538 t.Run(c.Name, func(t *testing.T) { 539 g := NewWithT(t) 540 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 541 c.Input.Client = fakeClient 542 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 543 g.Expect(err).To(Succeed()) 544 agentPool := s.AgentPoolSpec() 545 if !reflect.DeepEqual(c.Expected, agentPool) { 546 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 547 } 548 }) 549 } 550 } 551 552 func TestManagedMachinePoolScope_OSDiskType(t *testing.T) { 553 scheme := runtime.NewScheme() 554 _ = expv1.AddToScheme(scheme) 555 _ = infrav1.AddToScheme(scheme) 556 557 cases := []struct { 558 Name string 559 Input ManagedMachinePoolScopeParams 560 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 561 }{ 562 { 563 Name: "Without OsDiskType", 564 Input: ManagedMachinePoolScopeParams{ 565 Cluster: &clusterv1.Cluster{ 566 ObjectMeta: metav1.ObjectMeta{ 567 Name: "cluster1", 568 Namespace: "default", 569 }, 570 }, 571 ControlPlane: &infrav1.AzureManagedControlPlane{ 572 ObjectMeta: metav1.ObjectMeta{ 573 Name: "cluster1", 574 Namespace: "default", 575 }, 576 Spec: infrav1.AzureManagedControlPlaneSpec{ 577 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 578 SubscriptionID: "00000000-0000-0000-0000-000000000000", 579 }, 580 }, 581 }, 582 ManagedMachinePool: ManagedMachinePool{ 583 MachinePool: getMachinePool("pool0"), 584 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 585 }, 586 }, 587 Expected: &agentpools.AgentPoolSpec{ 588 Name: "pool0", 589 AzureName: "pool0", 590 SKU: "Standard_D2s_v3", 591 Replicas: 1, 592 Mode: "System", 593 Cluster: "cluster1", 594 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 595 }, 596 }, 597 { 598 Name: "With OsDiskType", 599 Input: ManagedMachinePoolScopeParams{ 600 Cluster: &clusterv1.Cluster{ 601 ObjectMeta: metav1.ObjectMeta{ 602 Name: "cluster1", 603 Namespace: "default", 604 }, 605 }, 606 ControlPlane: &infrav1.AzureManagedControlPlane{ 607 ObjectMeta: metav1.ObjectMeta{ 608 Name: "cluster1", 609 Namespace: "default", 610 }, 611 Spec: infrav1.AzureManagedControlPlaneSpec{ 612 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 613 SubscriptionID: "00000000-0000-0000-0000-000000000000", 614 }, 615 }, 616 }, 617 ManagedMachinePool: ManagedMachinePool{ 618 MachinePool: getMachinePool("pool1"), 619 InfraMachinePool: getAzureMachinePoolWithOsDiskType("pool1", string(asocontainerservicev1.OSDiskType_Ephemeral)), 620 }, 621 }, 622 Expected: &agentpools.AgentPoolSpec{ 623 Name: "pool1", 624 AzureName: "pool1", 625 SKU: "Standard_D2s_v3", 626 Mode: "User", 627 Cluster: "cluster1", 628 Replicas: 1, 629 OsDiskType: ptr.To(string(asocontainerservicev1.OSDiskType_Ephemeral)), 630 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 631 }, 632 }, 633 } 634 635 for _, c := range cases { 636 c := c 637 t.Run(c.Name, func(t *testing.T) { 638 g := NewWithT(t) 639 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 640 c.Input.Client = fakeClient 641 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 642 g.Expect(err).To(Succeed()) 643 agentPool := s.AgentPoolSpec() 644 if !reflect.DeepEqual(c.Expected, agentPool) { 645 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 646 } 647 }) 648 } 649 } 650 651 func TestManagedMachinePoolScope_SubnetName(t *testing.T) { 652 scheme := runtime.NewScheme() 653 _ = expv1.AddToScheme(scheme) 654 _ = infrav1.AddToScheme(scheme) 655 656 cases := []struct { 657 Name string 658 Input ManagedMachinePoolScopeParams 659 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 660 }{ 661 { 662 Name: "Without Vnet and SubnetName", 663 Input: ManagedMachinePoolScopeParams{ 664 Cluster: &clusterv1.Cluster{ 665 ObjectMeta: metav1.ObjectMeta{ 666 Name: "cluster1", 667 Namespace: "default", 668 }, 669 }, 670 ControlPlane: &infrav1.AzureManagedControlPlane{ 671 ObjectMeta: metav1.ObjectMeta{ 672 Name: "cluster1", 673 Namespace: "default", 674 }, 675 Spec: infrav1.AzureManagedControlPlaneSpec{ 676 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 677 SubscriptionID: "00000000-0000-0000-0000-000000000000", 678 }, 679 }, 680 }, 681 ManagedMachinePool: ManagedMachinePool{ 682 MachinePool: getMachinePool("pool0"), 683 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 684 }, 685 }, 686 Expected: &agentpools.AgentPoolSpec{ 687 Name: "pool0", 688 AzureName: "pool0", 689 SKU: "Standard_D2s_v3", 690 Replicas: 1, 691 Mode: "System", 692 Cluster: "cluster1", 693 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 694 }, 695 }, 696 { 697 Name: "With Vnet and Without SubnetName", 698 Input: ManagedMachinePoolScopeParams{ 699 Cluster: &clusterv1.Cluster{ 700 ObjectMeta: metav1.ObjectMeta{ 701 Name: "cluster1", 702 Namespace: "default", 703 }, 704 }, 705 ControlPlane: &infrav1.AzureManagedControlPlane{ 706 ObjectMeta: metav1.ObjectMeta{ 707 Name: "cluster1", 708 Namespace: "default", 709 }, 710 Spec: infrav1.AzureManagedControlPlaneSpec{ 711 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 712 SubscriptionID: "00000000-0000-0000-0000-000000000000", 713 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 714 ManagedControlPlaneVirtualNetworkClassSpec: infrav1.ManagedControlPlaneVirtualNetworkClassSpec{ 715 Name: "my-vnet", 716 Subnet: infrav1.ManagedControlPlaneSubnet{ 717 Name: "my-vnet-subnet", 718 }, 719 }, 720 ResourceGroup: "my-resource-group", 721 }, 722 }, 723 }, 724 }, 725 ManagedMachinePool: ManagedMachinePool{ 726 MachinePool: getMachinePool("pool1"), 727 InfraMachinePool: getAzureMachinePool("pool1", infrav1.NodePoolModeUser), 728 }, 729 }, 730 Expected: &agentpools.AgentPoolSpec{ 731 Name: "pool1", 732 AzureName: "pool1", 733 SKU: "Standard_D2s_v3", 734 Mode: "User", 735 Cluster: "cluster1", 736 Replicas: 1, 737 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-resource-group/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/my-vnet-subnet", 738 }, 739 }, 740 { 741 Name: "With Vnet and With SubnetName", 742 Input: ManagedMachinePoolScopeParams{ 743 Cluster: &clusterv1.Cluster{ 744 ObjectMeta: metav1.ObjectMeta{ 745 Name: "cluster1", 746 Namespace: "default", 747 }, 748 }, 749 ControlPlane: &infrav1.AzureManagedControlPlane{ 750 ObjectMeta: metav1.ObjectMeta{ 751 Name: "cluster1", 752 Namespace: "default", 753 }, 754 Spec: infrav1.AzureManagedControlPlaneSpec{ 755 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 756 SubscriptionID: "00000000-0000-0000-0000-000000000000", 757 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 758 ManagedControlPlaneVirtualNetworkClassSpec: infrav1.ManagedControlPlaneVirtualNetworkClassSpec{ 759 Name: "my-vnet", 760 Subnet: infrav1.ManagedControlPlaneSubnet{ 761 Name: "my-vnet-subnet", 762 }, 763 }, 764 ResourceGroup: "my-resource-group", 765 }, 766 }, 767 }, 768 }, 769 ManagedMachinePool: ManagedMachinePool{ 770 MachinePool: getMachinePool("pool1"), 771 InfraMachinePool: getAzureMachinePoolWithSubnetName("pool1", ptr.To("my-subnet")), 772 }, 773 }, 774 Expected: &agentpools.AgentPoolSpec{ 775 Name: "pool1", 776 AzureName: "pool1", 777 SKU: "Standard_D2s_v3", 778 Mode: "User", 779 Cluster: "cluster1", 780 Replicas: 1, 781 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-resource-group/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/my-subnet", 782 }, 783 }, 784 } 785 786 for _, c := range cases { 787 c := c 788 t.Run(c.Name, func(t *testing.T) { 789 g := NewWithT(t) 790 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 791 c.Input.Client = fakeClient 792 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 793 g.Expect(err).To(Succeed()) 794 s.SetSubnetName() 795 agentPool := s.AgentPoolSpec() 796 if !reflect.DeepEqual(c.Expected, agentPool) { 797 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 798 } 799 }) 800 } 801 } 802 803 func TestManagedMachinePoolScope_KubeletDiskType(t *testing.T) { 804 scheme := runtime.NewScheme() 805 _ = expv1.AddToScheme(scheme) 806 _ = infrav1.AddToScheme(scheme) 807 808 cases := []struct { 809 Name string 810 Input ManagedMachinePoolScopeParams 811 Expected azure.ASOResourceSpecGetter[genruntime.MetaObject] 812 }{ 813 { 814 Name: "Without KubeletDiskType", 815 Input: ManagedMachinePoolScopeParams{ 816 Cluster: &clusterv1.Cluster{ 817 ObjectMeta: metav1.ObjectMeta{ 818 Name: "cluster1", 819 Namespace: "default", 820 }, 821 }, 822 ControlPlane: &infrav1.AzureManagedControlPlane{ 823 ObjectMeta: metav1.ObjectMeta{ 824 Name: "cluster1", 825 Namespace: "default", 826 }, 827 Spec: infrav1.AzureManagedControlPlaneSpec{ 828 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 829 SubscriptionID: "00000000-0000-0000-0000-000000000000", 830 }, 831 }, 832 }, 833 ManagedMachinePool: ManagedMachinePool{ 834 MachinePool: getMachinePool("pool0"), 835 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 836 }, 837 }, 838 Expected: &agentpools.AgentPoolSpec{ 839 Name: "pool0", 840 AzureName: "pool0", 841 SKU: "Standard_D2s_v3", 842 Replicas: 1, 843 Mode: "System", 844 Cluster: "cluster1", 845 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 846 }, 847 }, 848 { 849 Name: "With KubeletDiskType", 850 Input: ManagedMachinePoolScopeParams{ 851 Cluster: &clusterv1.Cluster{ 852 ObjectMeta: metav1.ObjectMeta{ 853 Name: "cluster1", 854 Namespace: "default", 855 }, 856 }, 857 ControlPlane: &infrav1.AzureManagedControlPlane{ 858 ObjectMeta: metav1.ObjectMeta{ 859 Name: "cluster1", 860 Namespace: "default", 861 }, 862 Spec: infrav1.AzureManagedControlPlaneSpec{ 863 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 864 SubscriptionID: "00000000-0000-0000-0000-000000000000", 865 }, 866 }, 867 }, 868 ManagedMachinePool: ManagedMachinePool{ 869 MachinePool: getMachinePool("pool1"), 870 InfraMachinePool: getAzureMachinePoolWithKubeletDiskType("pool1", (*infrav1.KubeletDiskType)(ptr.To("Temporary"))), 871 }, 872 }, 873 Expected: &agentpools.AgentPoolSpec{ 874 Name: "pool1", 875 AzureName: "pool1", 876 SKU: "Standard_D2s_v3", 877 Mode: "User", 878 Cluster: "cluster1", 879 Replicas: 1, 880 KubeletDiskType: (*infrav1.KubeletDiskType)(ptr.To("Temporary")), 881 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 882 }, 883 }, 884 } 885 886 for _, c := range cases { 887 c := c 888 t.Run(c.Name, func(t *testing.T) { 889 g := NewWithT(t) 890 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build() 891 c.Input.Client = fakeClient 892 s, err := NewManagedMachinePoolScope(context.TODO(), c.Input) 893 g.Expect(err).To(Succeed()) 894 agentPool := s.AgentPoolSpec() 895 if !reflect.DeepEqual(c.Expected, agentPool) { 896 t.Errorf("Got difference between expected result and result:\n%s", cmp.Diff(c.Expected, agentPool)) 897 } 898 }) 899 } 900 } 901 902 func TestManagedMachinePoolScope_EnablePreviewFeatures(t *testing.T) { 903 cases := []struct { 904 Name string 905 previewEnabled *bool 906 Expected bool 907 }{ 908 { 909 Name: "Without EnablePreviewFeatures", 910 previewEnabled: nil, 911 Expected: false, 912 }, 913 { 914 Name: "With EnablePreviewFeatures false", 915 previewEnabled: ptr.To(false), 916 Expected: false, 917 }, 918 { 919 Name: "With EnablePreviewFeatures true", 920 previewEnabled: ptr.To(true), 921 Expected: true, 922 }, 923 } 924 for _, c := range cases { 925 c := c 926 t.Run(c.Name, func(t *testing.T) { 927 g := NewWithT(t) 928 s := &ManagedMachinePoolScope{ 929 ControlPlane: &infrav1.AzureManagedControlPlane{ 930 Spec: infrav1.AzureManagedControlPlaneSpec{ 931 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 932 EnablePreviewFeatures: c.previewEnabled, 933 }, 934 }, 935 }, 936 MachinePool: &expv1.MachinePool{}, 937 InfraMachinePool: &infrav1.AzureManagedMachinePool{}, 938 } 939 agentPoolGetter := s.AgentPoolSpec() 940 agentPool, ok := agentPoolGetter.(*agentpools.AgentPoolSpec) 941 g.Expect(ok).To(BeTrue()) 942 g.Expect(agentPool.Preview).To(Equal(c.Expected)) 943 g.Expect(s.IsPreviewEnabled()).To(Equal(c.Expected)) 944 }) 945 } 946 } 947 948 func Test_getManagedMachinePoolVersion(t *testing.T) { 949 cases := []struct { 950 name string 951 managedControlPlane *infrav1.AzureManagedControlPlane 952 machinePool *expv1.MachinePool 953 expected *string 954 }{ 955 { 956 name: "Empty configs", 957 managedControlPlane: nil, 958 machinePool: nil, 959 expected: nil, 960 }, 961 { 962 name: "Empty mp", 963 managedControlPlane: &infrav1.AzureManagedControlPlane{}, 964 machinePool: nil, 965 expected: nil, 966 }, 967 { 968 name: "Only machine pool is available", 969 managedControlPlane: nil, 970 machinePool: &expv1.MachinePool{ 971 Spec: expv1.MachinePoolSpec{ 972 Template: clusterv1.MachineTemplateSpec{ 973 Spec: clusterv1.MachineSpec{ 974 Version: ptr.To("v1.15.0"), 975 }, 976 }, 977 }, 978 }, 979 expected: ptr.To("1.15.0"), 980 }, 981 { 982 name: "Only machine pool is available and cp is nil", 983 managedControlPlane: nil, 984 machinePool: &expv1.MachinePool{ 985 Spec: expv1.MachinePoolSpec{ 986 Template: clusterv1.MachineTemplateSpec{ 987 Spec: clusterv1.MachineSpec{ 988 Version: ptr.To("v1.15.0"), 989 }, 990 }, 991 }, 992 }, 993 expected: ptr.To("1.15.0"), 994 }, 995 { 996 name: "mcp.status.autoUpgradeVersion > mp.spec.template.spec.version", 997 managedControlPlane: &infrav1.AzureManagedControlPlane{ 998 Status: infrav1.AzureManagedControlPlaneStatus{ 999 AutoUpgradeVersion: "1.20.3", 1000 }, 1001 }, 1002 machinePool: &expv1.MachinePool{ 1003 Spec: expv1.MachinePoolSpec{ 1004 Template: clusterv1.MachineTemplateSpec{ 1005 Spec: clusterv1.MachineSpec{ 1006 Version: ptr.To("v1.15.0"), 1007 }, 1008 }, 1009 }, 1010 }, 1011 expected: ptr.To("1.20.3"), 1012 }, 1013 { 1014 name: "suffix + mcp.status.autoUpgradeVersion > mp.spec.template.spec.version", 1015 managedControlPlane: &infrav1.AzureManagedControlPlane{ 1016 Status: infrav1.AzureManagedControlPlaneStatus{ 1017 AutoUpgradeVersion: "v1.20.3", 1018 }, 1019 }, 1020 machinePool: &expv1.MachinePool{ 1021 Spec: expv1.MachinePoolSpec{ 1022 Template: clusterv1.MachineTemplateSpec{ 1023 Spec: clusterv1.MachineSpec{ 1024 Version: ptr.To("v1.15.0"), 1025 }, 1026 }, 1027 }, 1028 }, 1029 expected: ptr.To("1.20.3"), 1030 }, 1031 { 1032 name: "mcp.status.autoUpgradeVersion < mp.spec.template.spec.version", 1033 managedControlPlane: &infrav1.AzureManagedControlPlane{ 1034 Status: infrav1.AzureManagedControlPlaneStatus{ 1035 AutoUpgradeVersion: "v1.20.3", 1036 }, 1037 }, 1038 machinePool: &expv1.MachinePool{ 1039 Spec: expv1.MachinePoolSpec{ 1040 Template: clusterv1.MachineTemplateSpec{ 1041 Spec: clusterv1.MachineSpec{ 1042 Version: ptr.To("v1.21.0"), 1043 }, 1044 }, 1045 }, 1046 }, 1047 expected: ptr.To("1.21.0"), 1048 }, 1049 } 1050 1051 for _, c := range cases { 1052 t.Run(c.name, func(t *testing.T) { 1053 g := NewWithT(t) 1054 v := getManagedMachinePoolVersion(c.managedControlPlane, c.machinePool) 1055 if c.expected != nil { 1056 g.Expect(*v).To(Equal(*c.expected)) 1057 } else { 1058 g.Expect(v).To(BeNil()) 1059 } 1060 }) 1061 } 1062 } 1063 1064 func getAzureMachinePool(name string, mode infrav1.NodePoolMode) *infrav1.AzureManagedMachinePool { 1065 return &infrav1.AzureManagedMachinePool{ 1066 ObjectMeta: metav1.ObjectMeta{ 1067 Name: name, 1068 Namespace: "default", 1069 Labels: map[string]string{ 1070 clusterv1.ClusterNameLabel: "cluster1", 1071 }, 1072 OwnerReferences: []metav1.OwnerReference{ 1073 { 1074 APIVersion: "cluster.x-k8s.io/v1beta1", 1075 Kind: "MachinePool", 1076 Name: name, 1077 }, 1078 }, 1079 }, 1080 Spec: infrav1.AzureManagedMachinePoolSpec{ 1081 AzureManagedMachinePoolClassSpec: infrav1.AzureManagedMachinePoolClassSpec{ 1082 Mode: string(mode), 1083 SKU: "Standard_D2s_v3", 1084 Name: ptr.To(name), 1085 }, 1086 }, 1087 } 1088 } 1089 1090 func getAzureMachinePoolWithScaling(name string, min, max int) *infrav1.AzureManagedMachinePool { 1091 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1092 managedPool.Spec.Scaling = &infrav1.ManagedMachinePoolScaling{ 1093 MinSize: ptr.To(min), 1094 MaxSize: ptr.To(max), 1095 } 1096 return managedPool 1097 } 1098 1099 func getAzureMachinePoolWithMaxPods(name string, maxPods int) *infrav1.AzureManagedMachinePool { 1100 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeSystem) 1101 managedPool.Spec.MaxPods = ptr.To(maxPods) 1102 return managedPool 1103 } 1104 1105 func getAzureMachinePoolWithTaints(name string, taints infrav1.Taints) *infrav1.AzureManagedMachinePool { 1106 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1107 managedPool.Spec.Taints = taints 1108 return managedPool 1109 } 1110 1111 func getAzureMachinePoolWithSubnetName(name string, subnetName *string) *infrav1.AzureManagedMachinePool { 1112 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1113 managedPool.Spec.SubnetName = subnetName 1114 return managedPool 1115 } 1116 1117 func getAzureMachinePoolWithOsDiskType(name string, osDiskType string) *infrav1.AzureManagedMachinePool { 1118 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1119 managedPool.Spec.OsDiskType = ptr.To(osDiskType) 1120 return managedPool 1121 } 1122 1123 func getAzureMachinePoolWithKubeletDiskType(name string, kubeletDiskType *infrav1.KubeletDiskType) *infrav1.AzureManagedMachinePool { 1124 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1125 managedPool.Spec.KubeletDiskType = kubeletDiskType 1126 return managedPool 1127 } 1128 1129 func getAzureMachinePoolWithLabels(name string, nodeLabels map[string]string) *infrav1.AzureManagedMachinePool { 1130 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeSystem) 1131 managedPool.Spec.NodeLabels = nodeLabels 1132 return managedPool 1133 } 1134 1135 func getAzureMachinePoolWithAdditionalTags(name string, additionalTags infrav1.Tags) *infrav1.AzureManagedMachinePool { 1136 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeSystem) 1137 managedPool.Spec.AdditionalTags = additionalTags 1138 return managedPool 1139 } 1140 1141 func getMachinePool(name string) *expv1.MachinePool { 1142 return &expv1.MachinePool{ 1143 ObjectMeta: metav1.ObjectMeta{ 1144 Name: name, 1145 Namespace: "default", 1146 Labels: map[string]string{ 1147 clusterv1.ClusterNameLabel: "cluster1", 1148 }, 1149 }, 1150 Spec: expv1.MachinePoolSpec{ 1151 ClusterName: "cluster1", 1152 }, 1153 } 1154 } 1155 1156 func getLinuxAzureMachinePool(name string) *infrav1.AzureManagedMachinePool { 1157 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1158 managedPool.Spec.OSType = ptr.To(azure.LinuxOS) 1159 return managedPool 1160 } 1161 1162 func getWindowsAzureMachinePool(name string) *infrav1.AzureManagedMachinePool { 1163 managedPool := getAzureMachinePool(name, infrav1.NodePoolModeUser) 1164 managedPool.Spec.OSType = ptr.To(azure.WindowsOS) 1165 return managedPool 1166 } 1167 1168 func getMachinePoolWithVersion(name, version string) *expv1.MachinePool { 1169 machine := getMachinePool(name) 1170 machine.Spec.Template.Spec.Version = ptr.To(version) 1171 return machine 1172 }