sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/scope/managedcontrolplane_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 scope 18 19 import ( 20 "context" 21 "reflect" 22 "testing" 23 24 asokubernetesconfigurationv1 "github.com/Azure/azure-service-operator/v2/api/kubernetesconfiguration/v1api20230501" 25 asonetworkv1 "github.com/Azure/azure-service-operator/v2/api/network/v1api20220701" 26 asoresourcesv1 "github.com/Azure/azure-service-operator/v2/api/resources/v1api20200601" 27 "github.com/Azure/azure-service-operator/v2/pkg/genruntime" 28 . "github.com/onsi/gomega" 29 corev1 "k8s.io/api/core/v1" 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 "k8s.io/apimachinery/pkg/runtime" 32 "k8s.io/utils/ptr" 33 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 34 "sigs.k8s.io/cluster-api-provider-azure/azure" 35 "sigs.k8s.io/cluster-api-provider-azure/azure/services/agentpools" 36 "sigs.k8s.io/cluster-api-provider-azure/azure/services/aksextensions" 37 "sigs.k8s.io/cluster-api-provider-azure/azure/services/groups" 38 "sigs.k8s.io/cluster-api-provider-azure/azure/services/managedclusters" 39 "sigs.k8s.io/cluster-api-provider-azure/azure/services/privateendpoints" 40 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 41 expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" 42 "sigs.k8s.io/controller-runtime/pkg/client/fake" 43 ) 44 45 func TestManagedControlPlaneScope_OutboundType(t *testing.T) { 46 scheme := runtime.NewScheme() 47 _ = expv1.AddToScheme(scheme) 48 _ = infrav1.AddToScheme(scheme) 49 _ = corev1.AddToScheme(scheme) 50 explicitOutboundType := infrav1.ManagedControlPlaneOutboundTypeUserDefinedRouting 51 cases := []struct { 52 Name string 53 Input ManagedControlPlaneScopeParams 54 Expected bool 55 }{ 56 { 57 Name: "With Explicit OutboundType defined", 58 Input: ManagedControlPlaneScopeParams{ 59 Cluster: &clusterv1.Cluster{ 60 ObjectMeta: metav1.ObjectMeta{ 61 Name: "cluster1", 62 Namespace: "default", 63 }, 64 }, 65 ControlPlane: &infrav1.AzureManagedControlPlane{ 66 Spec: infrav1.AzureManagedControlPlaneSpec{ 67 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 68 SubscriptionID: "00000000-0000-0000-0000-000000000000", 69 IdentityRef: &corev1.ObjectReference{ 70 Name: "fake-identity", 71 Namespace: "default", 72 Kind: "AzureClusterIdentity", 73 }, 74 OutboundType: &explicitOutboundType, 75 }, 76 }, 77 }, 78 }, 79 Expected: false, 80 }, 81 { 82 Name: "Without OutboundType defined", 83 Input: ManagedControlPlaneScopeParams{ 84 Cluster: &clusterv1.Cluster{ 85 ObjectMeta: metav1.ObjectMeta{ 86 Name: "cluster1", 87 Namespace: "default", 88 }, 89 }, 90 ControlPlane: &infrav1.AzureManagedControlPlane{ 91 Spec: infrav1.AzureManagedControlPlaneSpec{ 92 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 93 SubscriptionID: "00000000-0000-0000-0000-000000000000", 94 IdentityRef: &corev1.ObjectReference{ 95 Name: "fake-identity", 96 Namespace: "default", 97 Kind: "AzureClusterIdentity", 98 }, 99 }, 100 }, 101 }, 102 }, 103 Expected: true, 104 }, 105 } 106 for _, c := range cases { 107 c := c 108 t.Run(c.Name, func(t *testing.T) { 109 g := NewWithT(t) 110 fakeIdentity := &infrav1.AzureClusterIdentity{ 111 ObjectMeta: metav1.ObjectMeta{ 112 Name: "fake-identity", 113 Namespace: "default", 114 }, 115 Spec: infrav1.AzureClusterIdentitySpec{ 116 Type: infrav1.ServicePrincipal, 117 ClientID: fakeClientID, 118 TenantID: fakeTenantID, 119 }, 120 } 121 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 122 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 123 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 124 125 c.Input.Client = fakeClient 126 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 127 g.Expect(err).To(Succeed()) 128 managedCluster := s.ManagedClusterSpec() 129 result := managedCluster.(*managedclusters.ManagedClusterSpec).OutboundType == nil 130 g.Expect(result).To(Equal(c.Expected)) 131 }) 132 } 133 } 134 135 func TestManagedControlPlaneScope_PoolVersion(t *testing.T) { 136 scheme := runtime.NewScheme() 137 _ = expv1.AddToScheme(scheme) 138 _ = infrav1.AddToScheme(scheme) 139 _ = corev1.AddToScheme(scheme) 140 141 cases := []struct { 142 Name string 143 Input ManagedControlPlaneScopeParams 144 Expected []azure.ASOResourceSpecGetter[genruntime.MetaObject] 145 Err string 146 }{ 147 { 148 Name: "Without Version", 149 Input: ManagedControlPlaneScopeParams{ 150 Cluster: &clusterv1.Cluster{ 151 ObjectMeta: metav1.ObjectMeta{ 152 Name: "cluster1", 153 Namespace: "default", 154 }, 155 }, 156 ControlPlane: &infrav1.AzureManagedControlPlane{ 157 ObjectMeta: metav1.ObjectMeta{ 158 Name: "cluster1", 159 Namespace: "default", 160 }, 161 Spec: infrav1.AzureManagedControlPlaneSpec{ 162 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 163 SubscriptionID: "00000000-0000-0000-0000-000000000000", 164 IdentityRef: &corev1.ObjectReference{ 165 Name: "fake-identity", 166 Namespace: "default", 167 Kind: "AzureClusterIdentity", 168 }, 169 }, 170 }, 171 }, 172 ManagedMachinePools: []ManagedMachinePool{ 173 { 174 MachinePool: getMachinePool("pool0"), 175 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 176 }, 177 }, 178 }, 179 Expected: []azure.ASOResourceSpecGetter[genruntime.MetaObject]{ 180 &agentpools.AgentPoolSpec{ 181 Name: "pool0", 182 AzureName: "pool0", 183 SKU: "Standard_D2s_v3", 184 Replicas: 1, 185 Mode: "System", 186 Cluster: "cluster1", 187 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 188 }, 189 }, 190 }, 191 { 192 Name: "With Version", 193 Input: ManagedControlPlaneScopeParams{ 194 Cluster: &clusterv1.Cluster{ 195 ObjectMeta: metav1.ObjectMeta{ 196 Name: "cluster1", 197 Namespace: "default", 198 }, 199 }, 200 ControlPlane: &infrav1.AzureManagedControlPlane{ 201 ObjectMeta: metav1.ObjectMeta{ 202 Name: "cluster1", 203 Namespace: "default", 204 }, 205 Spec: infrav1.AzureManagedControlPlaneSpec{ 206 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 207 Version: "v1.22.0", 208 SubscriptionID: "00000000-0000-0000-0000-000000000000", 209 IdentityRef: &corev1.ObjectReference{ 210 Name: "fake-identity", 211 Namespace: "default", 212 Kind: "AzureClusterIdentity", 213 }, 214 }, 215 }, 216 }, 217 ManagedMachinePools: []ManagedMachinePool{ 218 { 219 MachinePool: getMachinePoolWithVersion("pool0", "v1.21.1"), 220 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 221 }, 222 }, 223 }, 224 Expected: []azure.ASOResourceSpecGetter[genruntime.MetaObject]{ 225 &agentpools.AgentPoolSpec{ 226 Name: "pool0", 227 AzureName: "pool0", 228 SKU: "Standard_D2s_v3", 229 Mode: "System", 230 Replicas: 1, 231 Version: ptr.To("1.21.1"), 232 Cluster: "cluster1", 233 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 234 }, 235 }, 236 }, 237 { 238 Name: "With bad version", 239 Input: ManagedControlPlaneScopeParams{ 240 Cluster: &clusterv1.Cluster{ 241 ObjectMeta: metav1.ObjectMeta{ 242 Name: "cluster1", 243 Namespace: "default", 244 }, 245 }, 246 ControlPlane: &infrav1.AzureManagedControlPlane{ 247 ObjectMeta: metav1.ObjectMeta{ 248 Name: "cluster1", 249 Namespace: "default", 250 }, 251 Spec: infrav1.AzureManagedControlPlaneSpec{ 252 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 253 Version: "v1.20.1", 254 SubscriptionID: "00000000-0000-0000-0000-000000000000", 255 IdentityRef: &corev1.ObjectReference{ 256 Name: "fake-identity", 257 Namespace: "default", 258 Kind: "AzureClusterIdentity", 259 }, 260 }, 261 }, 262 }, 263 ManagedMachinePools: []ManagedMachinePool{ 264 { 265 MachinePool: getMachinePoolWithVersion("pool0", "v1.21.1"), 266 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 267 }, 268 }, 269 }, 270 Err: "MachinePool version cannot be greater than the AzureManagedControlPlane version", 271 }, 272 } 273 274 for _, c := range cases { 275 c := c 276 t.Run(c.Name, func(t *testing.T) { 277 g := NewWithT(t) 278 fakeIdentity := &infrav1.AzureClusterIdentity{ 279 ObjectMeta: metav1.ObjectMeta{ 280 Name: "fake-identity", 281 Namespace: "default", 282 }, 283 Spec: infrav1.AzureClusterIdentitySpec{ 284 Type: infrav1.ServicePrincipal, 285 ClientID: fakeClientID, 286 TenantID: fakeTenantID, 287 }, 288 } 289 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 290 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 291 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 292 293 c.Input.Client = fakeClient 294 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 295 g.Expect(err).To(Succeed()) 296 agentPools, err := s.GetAllAgentPoolSpecs() 297 if err != nil { 298 g.Expect(err.Error()).To(Equal(c.Err)) 299 } else { 300 g.Expect(agentPools).To(Equal(c.Expected)) 301 } 302 }) 303 } 304 } 305 306 func TestManagedControlPlaneScope_AddonProfiles(t *testing.T) { 307 scheme := runtime.NewScheme() 308 _ = expv1.AddToScheme(scheme) 309 _ = infrav1.AddToScheme(scheme) 310 _ = corev1.AddToScheme(scheme) 311 312 cases := []struct { 313 Name string 314 Input ManagedControlPlaneScopeParams 315 Expected []managedclusters.AddonProfile 316 }{ 317 { 318 Name: "Without add-ons", 319 Input: ManagedControlPlaneScopeParams{ 320 Cluster: &clusterv1.Cluster{ 321 ObjectMeta: metav1.ObjectMeta{ 322 Name: "cluster1", 323 Namespace: "default", 324 }, 325 }, 326 ControlPlane: &infrav1.AzureManagedControlPlane{ 327 ObjectMeta: metav1.ObjectMeta{ 328 Name: "cluster1", 329 Namespace: "default", 330 }, 331 Spec: infrav1.AzureManagedControlPlaneSpec{ 332 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 333 SubscriptionID: "00000000-0000-0000-0000-000000000000", 334 IdentityRef: &corev1.ObjectReference{ 335 Name: "fake-identity", 336 Namespace: "default", 337 Kind: "AzureClusterIdentity", 338 }, 339 }, 340 }, 341 }, 342 ManagedMachinePools: []ManagedMachinePool{ 343 { 344 MachinePool: getMachinePool("pool0"), 345 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 346 }, 347 }, 348 }, 349 Expected: nil, 350 }, 351 { 352 Name: "With add-ons", 353 Input: ManagedControlPlaneScopeParams{ 354 Cluster: &clusterv1.Cluster{ 355 ObjectMeta: metav1.ObjectMeta{ 356 Name: "cluster1", 357 Namespace: "default", 358 }, 359 }, 360 ControlPlane: &infrav1.AzureManagedControlPlane{ 361 ObjectMeta: metav1.ObjectMeta{ 362 Name: "cluster1", 363 Namespace: "default", 364 }, 365 Spec: infrav1.AzureManagedControlPlaneSpec{ 366 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 367 SubscriptionID: "00000000-0000-0000-0000-000000000000", 368 IdentityRef: &corev1.ObjectReference{ 369 Name: "fake-identity", 370 Namespace: "default", 371 Kind: "AzureClusterIdentity", 372 }, 373 AddonProfiles: []infrav1.AddonProfile{ 374 {Name: "addon1", Config: nil, Enabled: false}, 375 {Name: "addon2", Config: map[string]string{"k1": "v1", "k2": "v2"}, Enabled: true}, 376 }, 377 }, 378 }, 379 }, 380 ManagedMachinePools: []ManagedMachinePool{ 381 { 382 MachinePool: getMachinePool("pool0"), 383 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 384 }, 385 }, 386 }, 387 Expected: []managedclusters.AddonProfile{ 388 {Name: "addon1", Config: nil, Enabled: false}, 389 {Name: "addon2", Config: map[string]string{"k1": "v1", "k2": "v2"}, Enabled: true}, 390 }, 391 }, 392 } 393 394 for _, c := range cases { 395 c := c 396 t.Run(c.Name, func(t *testing.T) { 397 g := NewWithT(t) 398 fakeIdentity := &infrav1.AzureClusterIdentity{ 399 ObjectMeta: metav1.ObjectMeta{ 400 Name: "fake-identity", 401 Namespace: "default", 402 }, 403 Spec: infrav1.AzureClusterIdentitySpec{ 404 Type: infrav1.ServicePrincipal, 405 ClientID: fakeClientID, 406 TenantID: fakeTenantID, 407 }, 408 } 409 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 410 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 411 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 412 413 c.Input.Client = fakeClient 414 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 415 g.Expect(err).To(Succeed()) 416 managedCluster := s.ManagedClusterSpec() 417 g.Expect(managedCluster.(*managedclusters.ManagedClusterSpec).AddonProfiles).To(Equal(c.Expected)) 418 }) 419 } 420 } 421 422 func TestManagedControlPlaneScope_OSType(t *testing.T) { 423 scheme := runtime.NewScheme() 424 _ = expv1.AddToScheme(scheme) 425 _ = infrav1.AddToScheme(scheme) 426 _ = corev1.AddToScheme(scheme) 427 428 cases := []struct { 429 Name string 430 Input ManagedControlPlaneScopeParams 431 Expected []azure.ASOResourceSpecGetter[genruntime.MetaObject] 432 Err string 433 }{ 434 { 435 Name: "with Linux and Windows pools", 436 Input: ManagedControlPlaneScopeParams{ 437 Cluster: &clusterv1.Cluster{ 438 ObjectMeta: metav1.ObjectMeta{ 439 Name: "cluster1", 440 Namespace: "default", 441 }, 442 }, 443 ControlPlane: &infrav1.AzureManagedControlPlane{ 444 ObjectMeta: metav1.ObjectMeta{ 445 Name: "cluster1", 446 Namespace: "default", 447 }, 448 Spec: infrav1.AzureManagedControlPlaneSpec{ 449 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 450 Version: "v1.20.1", 451 SubscriptionID: "00000000-0000-0000-0000-000000000000", 452 IdentityRef: &corev1.ObjectReference{ 453 Name: "fake-identity", 454 Namespace: "default", 455 Kind: "AzureClusterIdentity", 456 }, 457 }, 458 }, 459 }, 460 ManagedMachinePools: []ManagedMachinePool{ 461 { 462 MachinePool: getMachinePool("pool0"), 463 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 464 }, 465 { 466 MachinePool: getMachinePool("pool1"), 467 InfraMachinePool: getLinuxAzureMachinePool("pool1"), 468 }, 469 { 470 MachinePool: getMachinePool("pool2"), 471 InfraMachinePool: getWindowsAzureMachinePool("pool2"), 472 }, 473 }, 474 }, 475 Expected: []azure.ASOResourceSpecGetter[genruntime.MetaObject]{ 476 &agentpools.AgentPoolSpec{ 477 Name: "pool0", 478 AzureName: "pool0", 479 SKU: "Standard_D2s_v3", 480 Mode: "System", 481 Replicas: 1, 482 Cluster: "cluster1", 483 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 484 }, 485 &agentpools.AgentPoolSpec{ 486 Name: "pool1", 487 AzureName: "pool1", 488 SKU: "Standard_D2s_v3", 489 Mode: "User", 490 Replicas: 1, 491 Cluster: "cluster1", 492 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 493 OSType: ptr.To(azure.LinuxOS), 494 }, 495 &agentpools.AgentPoolSpec{ 496 Name: "pool2", 497 AzureName: "pool2", 498 SKU: "Standard_D2s_v3", 499 Mode: "User", 500 Replicas: 1, 501 Cluster: "cluster1", 502 VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", 503 OSType: ptr.To(azure.WindowsOS), 504 }, 505 }, 506 }, 507 { 508 Name: "system pool required", 509 Input: ManagedControlPlaneScopeParams{ 510 Cluster: &clusterv1.Cluster{ 511 ObjectMeta: metav1.ObjectMeta{ 512 Name: "cluster1", 513 Namespace: "default", 514 }, 515 }, 516 ControlPlane: &infrav1.AzureManagedControlPlane{ 517 ObjectMeta: metav1.ObjectMeta{ 518 Name: "cluster1", 519 Namespace: "default", 520 }, 521 Spec: infrav1.AzureManagedControlPlaneSpec{ 522 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 523 Version: "v1.20.1", 524 SubscriptionID: "00000000-0000-0000-0000-000000000000", 525 IdentityRef: &corev1.ObjectReference{ 526 Name: "fake-identity", 527 Namespace: "default", 528 Kind: "AzureClusterIdentity", 529 }, 530 }, 531 }, 532 }, 533 ManagedMachinePools: []ManagedMachinePool{ 534 { 535 MachinePool: getMachinePool("pool0"), 536 InfraMachinePool: getLinuxAzureMachinePool("pool0"), 537 }, 538 { 539 MachinePool: getMachinePool("pool1"), 540 InfraMachinePool: getWindowsAzureMachinePool("pool1"), 541 }, 542 }, 543 }, 544 Err: "failed to fetch azuremanagedMachine pool with mode:System, require at least 1 system node pool", 545 }, 546 } 547 548 for _, c := range cases { 549 c := c 550 t.Run(c.Name, func(t *testing.T) { 551 g := NewWithT(t) 552 fakeIdentity := &infrav1.AzureClusterIdentity{ 553 ObjectMeta: metav1.ObjectMeta{ 554 Name: "fake-identity", 555 Namespace: "default", 556 }, 557 Spec: infrav1.AzureClusterIdentitySpec{ 558 Type: infrav1.ServicePrincipal, 559 ClientID: fakeClientID, 560 TenantID: fakeTenantID, 561 }, 562 } 563 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 564 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 565 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 566 567 c.Input.Client = fakeClient 568 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 569 g.Expect(err).To(Succeed()) 570 agentPools, err := s.GetAllAgentPoolSpecs() 571 if err != nil { 572 g.Expect(err.Error()).To(Equal(c.Err)) 573 } else { 574 g.Expect(agentPools).To(Equal(c.Expected)) 575 } 576 }) 577 } 578 } 579 580 func TestManagedControlPlaneScope_IsVnetManagedCache(t *testing.T) { 581 scheme := runtime.NewScheme() 582 _ = expv1.AddToScheme(scheme) 583 _ = infrav1.AddToScheme(scheme) 584 _ = corev1.AddToScheme(scheme) 585 586 cases := []struct { 587 Name string 588 Input ManagedControlPlaneScopeParams 589 Expected bool 590 }{ 591 { 592 Name: "no Cache value", 593 Input: ManagedControlPlaneScopeParams{ 594 Cluster: &clusterv1.Cluster{ 595 ObjectMeta: metav1.ObjectMeta{ 596 Name: "cluster1", 597 Namespace: "default", 598 }, 599 }, 600 ControlPlane: &infrav1.AzureManagedControlPlane{ 601 ObjectMeta: metav1.ObjectMeta{ 602 Name: "cluster1", 603 Namespace: "default", 604 }, 605 Spec: infrav1.AzureManagedControlPlaneSpec{ 606 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 607 Version: "v1.20.1", 608 SubscriptionID: "00000000-0000-0000-0000-000000000000", 609 IdentityRef: &corev1.ObjectReference{ 610 Name: "fake-identity", 611 Namespace: "default", 612 Kind: "AzureClusterIdentity", 613 }, 614 }, 615 }, 616 }, 617 ManagedMachinePools: []ManagedMachinePool{ 618 { 619 MachinePool: getMachinePool("pool0"), 620 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 621 }, 622 { 623 MachinePool: getMachinePool("pool1"), 624 InfraMachinePool: getLinuxAzureMachinePool("pool1"), 625 }, 626 }, 627 }, 628 Expected: false, 629 }, 630 { 631 Name: "with Cache value of true", 632 Input: ManagedControlPlaneScopeParams{ 633 Cluster: &clusterv1.Cluster{ 634 ObjectMeta: metav1.ObjectMeta{ 635 Name: "cluster1", 636 Namespace: "default", 637 }, 638 }, 639 ControlPlane: &infrav1.AzureManagedControlPlane{ 640 ObjectMeta: metav1.ObjectMeta{ 641 Name: "cluster1", 642 Namespace: "default", 643 }, 644 Spec: infrav1.AzureManagedControlPlaneSpec{ 645 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 646 Version: "v1.20.1", 647 SubscriptionID: "00000000-0000-0000-0000-000000000000", 648 IdentityRef: &corev1.ObjectReference{ 649 Name: "fake-identity", 650 Namespace: "default", 651 Kind: "AzureClusterIdentity", 652 }, 653 }, 654 }, 655 }, 656 ManagedMachinePools: []ManagedMachinePool{ 657 { 658 MachinePool: getMachinePool("pool0"), 659 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 660 }, 661 { 662 MachinePool: getMachinePool("pool1"), 663 InfraMachinePool: getLinuxAzureMachinePool("pool1"), 664 }, 665 }, 666 Cache: &ManagedControlPlaneCache{ 667 isVnetManaged: ptr.To(true), 668 }, 669 }, 670 Expected: true, 671 }, 672 { 673 Name: "with Cache value of false", 674 Input: ManagedControlPlaneScopeParams{ 675 Cluster: &clusterv1.Cluster{ 676 ObjectMeta: metav1.ObjectMeta{ 677 Name: "cluster1", 678 Namespace: "default", 679 }, 680 }, 681 ControlPlane: &infrav1.AzureManagedControlPlane{ 682 ObjectMeta: metav1.ObjectMeta{ 683 Name: "cluster1", 684 Namespace: "default", 685 }, 686 Spec: infrav1.AzureManagedControlPlaneSpec{ 687 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 688 Version: "v1.20.1", 689 SubscriptionID: "00000000-0000-0000-0000-000000000000", 690 IdentityRef: &corev1.ObjectReference{ 691 Name: "fake-identity", 692 Namespace: "default", 693 Kind: "AzureClusterIdentity", 694 }, 695 }, 696 }, 697 }, 698 ManagedMachinePools: []ManagedMachinePool{ 699 { 700 MachinePool: getMachinePool("pool0"), 701 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 702 }, 703 { 704 MachinePool: getMachinePool("pool1"), 705 InfraMachinePool: getLinuxAzureMachinePool("pool1"), 706 }, 707 }, 708 Cache: &ManagedControlPlaneCache{ 709 isVnetManaged: ptr.To(false), 710 }, 711 }, 712 Expected: false, 713 }, 714 } 715 716 for _, c := range cases { 717 c := c 718 t.Run(c.Name, func(t *testing.T) { 719 g := NewWithT(t) 720 fakeIdentity := &infrav1.AzureClusterIdentity{ 721 ObjectMeta: metav1.ObjectMeta{ 722 Name: "fake-identity", 723 Namespace: "default", 724 }, 725 Spec: infrav1.AzureClusterIdentitySpec{ 726 Type: infrav1.ServicePrincipal, 727 ClientID: fakeClientID, 728 TenantID: fakeTenantID, 729 }, 730 } 731 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 732 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 733 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 734 735 c.Input.Client = fakeClient 736 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 737 g.Expect(err).To(Succeed()) 738 isVnetManaged := s.IsVnetManaged() 739 g.Expect(isVnetManaged).To(Equal(c.Expected)) 740 }) 741 } 742 } 743 744 func TestManagedControlPlaneScope_AADProfile(t *testing.T) { 745 scheme := runtime.NewScheme() 746 _ = infrav1.AddToScheme(scheme) 747 _ = corev1.AddToScheme(scheme) 748 749 cases := []struct { 750 Name string 751 Input ManagedControlPlaneScopeParams 752 Expected *managedclusters.AADProfile 753 }{ 754 { 755 Name: "Without AADProfile", 756 Input: ManagedControlPlaneScopeParams{ 757 Cluster: &clusterv1.Cluster{ 758 ObjectMeta: metav1.ObjectMeta{ 759 Name: "cluster1", 760 Namespace: "default", 761 }, 762 }, 763 ControlPlane: &infrav1.AzureManagedControlPlane{ 764 ObjectMeta: metav1.ObjectMeta{ 765 Name: "cluster1", 766 Namespace: "default", 767 }, 768 Spec: infrav1.AzureManagedControlPlaneSpec{ 769 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 770 SubscriptionID: "00000000-0000-0000-0000-000000000000", 771 IdentityRef: &corev1.ObjectReference{ 772 Name: "fake-identity", 773 Namespace: "default", 774 Kind: "AzureClusterIdentity", 775 }, 776 }, 777 }, 778 }, 779 ManagedMachinePools: []ManagedMachinePool{ 780 { 781 MachinePool: getMachinePool("pool0"), 782 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 783 }, 784 }, 785 }, 786 Expected: nil, 787 }, 788 { 789 Name: "With AADProfile", 790 Input: ManagedControlPlaneScopeParams{ 791 Cluster: &clusterv1.Cluster{ 792 ObjectMeta: metav1.ObjectMeta{ 793 Name: "cluster1", 794 Namespace: "default", 795 }, 796 }, 797 ControlPlane: &infrav1.AzureManagedControlPlane{ 798 ObjectMeta: metav1.ObjectMeta{ 799 Name: "cluster1", 800 Namespace: "default", 801 }, 802 Spec: infrav1.AzureManagedControlPlaneSpec{ 803 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 804 SubscriptionID: "00000000-0000-0000-0000-000000000000", 805 IdentityRef: &corev1.ObjectReference{ 806 Name: "fake-identity", 807 Namespace: "default", 808 Kind: "AzureClusterIdentity", 809 }, 810 AADProfile: &infrav1.AADProfile{ 811 Managed: true, 812 AdminGroupObjectIDs: []string{"00000000-0000-0000-0000-000000000000"}, 813 }, 814 }, 815 }, 816 }, 817 ManagedMachinePools: []ManagedMachinePool{ 818 { 819 MachinePool: getMachinePool("pool0"), 820 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 821 }, 822 }, 823 }, 824 Expected: &managedclusters.AADProfile{ 825 Managed: true, 826 EnableAzureRBAC: true, 827 AdminGroupObjectIDs: []string{"00000000-0000-0000-0000-000000000000"}, 828 }, 829 }, 830 } 831 for _, c := range cases { 832 c := c 833 t.Run(c.Name, func(t *testing.T) { 834 g := NewWithT(t) 835 fakeIdentity := &infrav1.AzureClusterIdentity{ 836 ObjectMeta: metav1.ObjectMeta{ 837 Name: "fake-identity", 838 Namespace: "default", 839 }, 840 Spec: infrav1.AzureClusterIdentitySpec{ 841 Type: infrav1.ServicePrincipal, 842 ClientID: fakeClientID, 843 TenantID: fakeTenantID, 844 }, 845 } 846 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 847 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 848 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 849 850 c.Input.Client = fakeClient 851 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 852 g.Expect(err).To(Succeed()) 853 managedClusterGetter := s.ManagedClusterSpec() 854 managedCluster, ok := managedClusterGetter.(*managedclusters.ManagedClusterSpec) 855 g.Expect(ok).To(BeTrue()) 856 g.Expect(managedCluster.AADProfile).To(Equal(c.Expected)) 857 }) 858 } 859 } 860 861 func TestManagedControlPlaneScope_DisableLocalAccounts(t *testing.T) { 862 scheme := runtime.NewScheme() 863 _ = infrav1.AddToScheme(scheme) 864 _ = corev1.AddToScheme(scheme) 865 866 cases := []struct { 867 Name string 868 Input ManagedControlPlaneScopeParams 869 Expected *bool 870 }{ 871 { 872 Name: "Without DisableLocalAccounts", 873 Input: ManagedControlPlaneScopeParams{ 874 Cluster: &clusterv1.Cluster{ 875 ObjectMeta: metav1.ObjectMeta{ 876 Name: "cluster1", 877 Namespace: "default", 878 }, 879 }, 880 ControlPlane: &infrav1.AzureManagedControlPlane{ 881 ObjectMeta: metav1.ObjectMeta{ 882 Name: "cluster1", 883 Namespace: "default", 884 }, 885 Spec: infrav1.AzureManagedControlPlaneSpec{ 886 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 887 SubscriptionID: "00000000-0000-0000-0000-000000000000", 888 IdentityRef: &corev1.ObjectReference{ 889 Name: "fake-identity", 890 Namespace: "default", 891 Kind: "AzureClusterIdentity", 892 }, 893 }, 894 }, 895 }, 896 ManagedMachinePools: []ManagedMachinePool{ 897 { 898 MachinePool: getMachinePool("pool0"), 899 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 900 }, 901 }, 902 }, 903 Expected: nil, 904 }, 905 { 906 Name: "Without AAdProfile and With DisableLocalAccounts", 907 Input: ManagedControlPlaneScopeParams{ 908 Cluster: &clusterv1.Cluster{ 909 ObjectMeta: metav1.ObjectMeta{ 910 Name: "cluster1", 911 Namespace: "default", 912 }, 913 }, 914 ControlPlane: &infrav1.AzureManagedControlPlane{ 915 ObjectMeta: metav1.ObjectMeta{ 916 Name: "cluster1", 917 Namespace: "default", 918 }, 919 Spec: infrav1.AzureManagedControlPlaneSpec{ 920 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 921 SubscriptionID: "00000000-0000-0000-0000-000000000000", 922 IdentityRef: &corev1.ObjectReference{ 923 Name: "fake-identity", 924 Namespace: "default", 925 Kind: "AzureClusterIdentity", 926 }, 927 DisableLocalAccounts: ptr.To[bool](true), 928 }, 929 }, 930 }, 931 ManagedMachinePools: []ManagedMachinePool{ 932 { 933 MachinePool: getMachinePool("pool0"), 934 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 935 }, 936 }, 937 }, 938 Expected: nil, 939 }, 940 { 941 Name: "With AAdProfile and With DisableLocalAccounts", 942 Input: ManagedControlPlaneScopeParams{ 943 Cluster: &clusterv1.Cluster{ 944 ObjectMeta: metav1.ObjectMeta{ 945 Name: "cluster1", 946 Namespace: "default", 947 }, 948 }, 949 ControlPlane: &infrav1.AzureManagedControlPlane{ 950 ObjectMeta: metav1.ObjectMeta{ 951 Name: "cluster1", 952 Namespace: "default", 953 }, 954 Spec: infrav1.AzureManagedControlPlaneSpec{ 955 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 956 SubscriptionID: "00000000-0000-0000-0000-000000000000", 957 IdentityRef: &corev1.ObjectReference{ 958 Name: "fake-identity", 959 Namespace: "default", 960 Kind: "AzureClusterIdentity", 961 }, 962 AADProfile: &infrav1.AADProfile{ 963 Managed: true, 964 AdminGroupObjectIDs: []string{"00000000-0000-0000-0000-000000000000"}, 965 }, 966 DisableLocalAccounts: ptr.To[bool](true), 967 }, 968 }, 969 }, 970 ManagedMachinePools: []ManagedMachinePool{ 971 { 972 MachinePool: getMachinePool("pool0"), 973 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 974 }, 975 }, 976 }, 977 Expected: ptr.To[bool](true), 978 }, 979 } 980 for _, c := range cases { 981 c := c 982 t.Run(c.Name, func(t *testing.T) { 983 g := NewWithT(t) 984 fakeIdentity := &infrav1.AzureClusterIdentity{ 985 ObjectMeta: metav1.ObjectMeta{ 986 Name: "fake-identity", 987 Namespace: "default", 988 }, 989 Spec: infrav1.AzureClusterIdentitySpec{ 990 Type: infrav1.ServicePrincipal, 991 ClientID: fakeClientID, 992 TenantID: fakeTenantID, 993 }, 994 } 995 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 996 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 997 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 998 999 c.Input.Client = fakeClient 1000 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 1001 g.Expect(err).To(Succeed()) 1002 managedClusterGetter := s.ManagedClusterSpec() 1003 managedCluster, ok := managedClusterGetter.(*managedclusters.ManagedClusterSpec) 1004 g.Expect(ok).To(BeTrue()) 1005 g.Expect(managedCluster.DisableLocalAccounts).To(Equal(c.Expected)) 1006 }) 1007 } 1008 } 1009 1010 func TestIsAADEnabled(t *testing.T) { 1011 scheme := runtime.NewScheme() 1012 _ = infrav1.AddToScheme(scheme) 1013 _ = corev1.AddToScheme(scheme) 1014 1015 cases := []struct { 1016 Name string 1017 Input ManagedControlPlaneScopeParams 1018 Expected bool 1019 }{ 1020 { 1021 Name: "AAD is not enabled", 1022 Input: ManagedControlPlaneScopeParams{ 1023 Cluster: &clusterv1.Cluster{ 1024 ObjectMeta: metav1.ObjectMeta{ 1025 Name: "cluster1", 1026 Namespace: "default", 1027 }, 1028 }, 1029 ControlPlane: &infrav1.AzureManagedControlPlane{ 1030 ObjectMeta: metav1.ObjectMeta{ 1031 Name: "cluster1", 1032 Namespace: "default", 1033 }, 1034 Spec: infrav1.AzureManagedControlPlaneSpec{ 1035 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1036 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1037 IdentityRef: &corev1.ObjectReference{ 1038 Name: "fake-identity", 1039 Namespace: "default", 1040 Kind: "AzureClusterIdentity", 1041 }, 1042 }, 1043 }, 1044 }, 1045 ManagedMachinePools: []ManagedMachinePool{ 1046 { 1047 MachinePool: getMachinePool("pool0"), 1048 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1049 }, 1050 }, 1051 }, 1052 Expected: false, 1053 }, 1054 { 1055 Name: "AAdProfile and With DisableLocalAccounts", 1056 Input: ManagedControlPlaneScopeParams{ 1057 Cluster: &clusterv1.Cluster{ 1058 ObjectMeta: metav1.ObjectMeta{ 1059 Name: "cluster1", 1060 Namespace: "default", 1061 }, 1062 }, 1063 ControlPlane: &infrav1.AzureManagedControlPlane{ 1064 ObjectMeta: metav1.ObjectMeta{ 1065 Name: "cluster1", 1066 Namespace: "default", 1067 }, 1068 Spec: infrav1.AzureManagedControlPlaneSpec{ 1069 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1070 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1071 IdentityRef: &corev1.ObjectReference{ 1072 Name: "fake-identity", 1073 Namespace: "default", 1074 Kind: "AzureClusterIdentity", 1075 }, 1076 AADProfile: &infrav1.AADProfile{ 1077 Managed: true, 1078 AdminGroupObjectIDs: []string{"00000000-0000-0000-0000-000000000000"}, 1079 }, 1080 DisableLocalAccounts: ptr.To[bool](true), 1081 }, 1082 }, 1083 }, 1084 ManagedMachinePools: []ManagedMachinePool{ 1085 { 1086 MachinePool: getMachinePool("pool0"), 1087 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1088 }, 1089 }, 1090 }, 1091 Expected: true, 1092 }, 1093 } 1094 for _, c := range cases { 1095 c := c 1096 t.Run(c.Name, func(t *testing.T) { 1097 g := NewWithT(t) 1098 fakeIdentity := &infrav1.AzureClusterIdentity{ 1099 ObjectMeta: metav1.ObjectMeta{ 1100 Name: "fake-identity", 1101 Namespace: "default", 1102 }, 1103 Spec: infrav1.AzureClusterIdentitySpec{ 1104 Type: infrav1.ServicePrincipal, 1105 ClientID: fakeClientID, 1106 TenantID: fakeTenantID, 1107 }, 1108 } 1109 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 1110 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 1111 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 1112 1113 c.Input.Client = fakeClient 1114 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 1115 g.Expect(err).To(Succeed()) 1116 aadEnabled := s.IsAADEnabled() 1117 g.Expect(aadEnabled).To(Equal(c.Expected)) 1118 }) 1119 } 1120 } 1121 1122 func TestAreLocalAccountsDisabled(t *testing.T) { 1123 scheme := runtime.NewScheme() 1124 _ = infrav1.AddToScheme(scheme) 1125 _ = corev1.AddToScheme(scheme) 1126 1127 cases := []struct { 1128 Name string 1129 Input ManagedControlPlaneScopeParams 1130 Expected bool 1131 }{ 1132 { 1133 Name: "DisbaleLocalAccount is not enabled", 1134 Input: ManagedControlPlaneScopeParams{ 1135 Cluster: &clusterv1.Cluster{ 1136 ObjectMeta: metav1.ObjectMeta{ 1137 Name: "cluster1", 1138 Namespace: "default", 1139 }, 1140 }, 1141 ControlPlane: &infrav1.AzureManagedControlPlane{ 1142 ObjectMeta: metav1.ObjectMeta{ 1143 Name: "cluster1", 1144 Namespace: "default", 1145 }, 1146 Spec: infrav1.AzureManagedControlPlaneSpec{ 1147 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1148 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1149 IdentityRef: &corev1.ObjectReference{ 1150 Name: "fake-identity", 1151 Namespace: "default", 1152 Kind: "AzureClusterIdentity", 1153 }, 1154 }, 1155 }, 1156 }, 1157 ManagedMachinePools: []ManagedMachinePool{ 1158 { 1159 MachinePool: getMachinePool("pool0"), 1160 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1161 }, 1162 }, 1163 }, 1164 Expected: false, 1165 }, 1166 { 1167 Name: "With AAdProfile and Without DisableLocalAccounts", 1168 Input: ManagedControlPlaneScopeParams{ 1169 Cluster: &clusterv1.Cluster{ 1170 ObjectMeta: metav1.ObjectMeta{ 1171 Name: "cluster1", 1172 Namespace: "default", 1173 }, 1174 }, 1175 ControlPlane: &infrav1.AzureManagedControlPlane{ 1176 ObjectMeta: metav1.ObjectMeta{ 1177 Name: "cluster1", 1178 Namespace: "default", 1179 }, 1180 Spec: infrav1.AzureManagedControlPlaneSpec{ 1181 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1182 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1183 IdentityRef: &corev1.ObjectReference{ 1184 Name: "fake-identity", 1185 Namespace: "default", 1186 Kind: "AzureClusterIdentity", 1187 }, 1188 AADProfile: &infrav1.AADProfile{ 1189 Managed: true, 1190 AdminGroupObjectIDs: []string{"00000000-0000-0000-0000-000000000000"}, 1191 }, 1192 }, 1193 }, 1194 }, 1195 ManagedMachinePools: []ManagedMachinePool{ 1196 { 1197 MachinePool: getMachinePool("pool0"), 1198 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1199 }, 1200 }, 1201 }, 1202 Expected: false, 1203 }, 1204 { 1205 Name: "With AAdProfile and With DisableLocalAccounts", 1206 Input: ManagedControlPlaneScopeParams{ 1207 Cluster: &clusterv1.Cluster{ 1208 ObjectMeta: metav1.ObjectMeta{ 1209 Name: "cluster1", 1210 Namespace: "default", 1211 }, 1212 }, 1213 ControlPlane: &infrav1.AzureManagedControlPlane{ 1214 ObjectMeta: metav1.ObjectMeta{ 1215 Name: "cluster1", 1216 Namespace: "default", 1217 }, 1218 Spec: infrav1.AzureManagedControlPlaneSpec{ 1219 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1220 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1221 IdentityRef: &corev1.ObjectReference{ 1222 Name: "fake-identity", 1223 Namespace: "default", 1224 Kind: "AzureClusterIdentity", 1225 }, 1226 AADProfile: &infrav1.AADProfile{ 1227 Managed: true, 1228 AdminGroupObjectIDs: []string{"00000000-0000-0000-0000-000000000000"}, 1229 }, 1230 DisableLocalAccounts: ptr.To[bool](true), 1231 }, 1232 }, 1233 }, 1234 ManagedMachinePools: []ManagedMachinePool{ 1235 { 1236 MachinePool: getMachinePool("pool0"), 1237 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1238 }, 1239 }, 1240 }, 1241 Expected: true, 1242 }, 1243 } 1244 for _, c := range cases { 1245 c := c 1246 t.Run(c.Name, func(t *testing.T) { 1247 g := NewWithT(t) 1248 fakeIdentity := &infrav1.AzureClusterIdentity{ 1249 ObjectMeta: metav1.ObjectMeta{ 1250 Name: "fake-identity", 1251 Namespace: "default", 1252 }, 1253 Spec: infrav1.AzureClusterIdentitySpec{ 1254 Type: infrav1.ServicePrincipal, 1255 ClientID: fakeClientID, 1256 TenantID: fakeTenantID, 1257 }, 1258 } 1259 fakeSecret := &corev1.Secret{Data: map[string][]byte{"clientSecret": []byte("fooSecret")}} 1260 initObjects := []runtime.Object{c.Input.ControlPlane, fakeIdentity, fakeSecret} 1261 fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build() 1262 1263 c.Input.Client = fakeClient 1264 s, err := NewManagedControlPlaneScope(context.TODO(), c.Input) 1265 g.Expect(err).To(Succeed()) 1266 localAccountsDisabled := s.AreLocalAccountsDisabled() 1267 g.Expect(localAccountsDisabled).To(Equal(c.Expected)) 1268 }) 1269 } 1270 } 1271 1272 func TestManagedControlPlaneScope_PrivateEndpointSpecs(t *testing.T) { 1273 cases := []struct { 1274 Name string 1275 Input ManagedControlPlaneScopeParams 1276 Expected []azure.ASOResourceSpecGetter[*asonetworkv1.PrivateEndpoint] 1277 Err string 1278 }{ 1279 { 1280 Name: "returns empty private endpoints list if no subnets are specified", 1281 Input: ManagedControlPlaneScopeParams{ 1282 Cluster: &clusterv1.Cluster{ 1283 ObjectMeta: metav1.ObjectMeta{ 1284 Name: "cluster1", 1285 Namespace: "default", 1286 }, 1287 }, 1288 ControlPlane: &infrav1.AzureManagedControlPlane{ 1289 ObjectMeta: metav1.ObjectMeta{ 1290 Name: "cluster1", 1291 Namespace: "default", 1292 }, 1293 Spec: infrav1.AzureManagedControlPlaneSpec{ 1294 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1295 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{}, 1296 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1297 }, 1298 }, 1299 }, 1300 }, 1301 Expected: make([]azure.ASOResourceSpecGetter[*asonetworkv1.PrivateEndpoint], 0), 1302 }, 1303 { 1304 Name: "returns empty private endpoints list if no private endpoints are specified", 1305 Input: ManagedControlPlaneScopeParams{ 1306 Cluster: &clusterv1.Cluster{ 1307 ObjectMeta: metav1.ObjectMeta{ 1308 Name: "cluster1", 1309 Namespace: "default", 1310 }, 1311 }, 1312 ControlPlane: &infrav1.AzureManagedControlPlane{ 1313 ObjectMeta: metav1.ObjectMeta{ 1314 Name: "cluster1", 1315 Namespace: "default", 1316 }, 1317 Spec: infrav1.AzureManagedControlPlaneSpec{ 1318 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1319 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1320 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 1321 ManagedControlPlaneVirtualNetworkClassSpec: infrav1.ManagedControlPlaneVirtualNetworkClassSpec{ 1322 Subnet: infrav1.ManagedControlPlaneSubnet{ 1323 PrivateEndpoints: infrav1.PrivateEndpoints{}, 1324 }, 1325 }, 1326 }, 1327 }, 1328 }, 1329 }, 1330 }, 1331 Expected: make([]azure.ASOResourceSpecGetter[*asonetworkv1.PrivateEndpoint], 0), 1332 }, 1333 { 1334 Name: "returns list of private endpoint specs if private endpoints are specified", 1335 Input: ManagedControlPlaneScopeParams{ 1336 Cluster: &clusterv1.Cluster{ 1337 ObjectMeta: metav1.ObjectMeta{ 1338 Name: "my-cluster", 1339 Namespace: "dummy-ns", 1340 }, 1341 }, 1342 ControlPlane: &infrav1.AzureManagedControlPlane{ 1343 ObjectMeta: metav1.ObjectMeta{ 1344 Name: "my-cluster", 1345 Namespace: "dummy-ns", 1346 }, 1347 Spec: infrav1.AzureManagedControlPlaneSpec{ 1348 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1349 SubscriptionID: "00000000-0000-0000-0000-000000000001", 1350 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 1351 ResourceGroup: "dummy-rg", 1352 ManagedControlPlaneVirtualNetworkClassSpec: infrav1.ManagedControlPlaneVirtualNetworkClassSpec{ 1353 Name: "vnet1", 1354 Subnet: infrav1.ManagedControlPlaneSubnet{ 1355 Name: "subnet1", 1356 PrivateEndpoints: infrav1.PrivateEndpoints{ 1357 { 1358 Name: "my-private-endpoint", 1359 Location: "westus2", 1360 PrivateLinkServiceConnections: []infrav1.PrivateLinkServiceConnection{ 1361 { 1362 Name: "my-pls-connection", 1363 PrivateLinkServiceID: "my-pls-id", 1364 GroupIDs: []string{ 1365 "my-group-id-1", 1366 }, 1367 RequestMessage: "my-request-message", 1368 }, 1369 }, 1370 CustomNetworkInterfaceName: "my-custom-nic", 1371 PrivateIPAddresses: []string{ 1372 "IP1", 1373 "IP2", 1374 }, 1375 ApplicationSecurityGroups: []string{ 1376 "ASG1", 1377 "ASG2", 1378 }, 1379 ManualApproval: true, 1380 }, 1381 }, 1382 }, 1383 }, 1384 }, 1385 }, 1386 }, 1387 }, 1388 }, 1389 Expected: []azure.ASOResourceSpecGetter[*asonetworkv1.PrivateEndpoint]{ 1390 &privateendpoints.PrivateEndpointSpec{ 1391 Name: "my-private-endpoint", 1392 ResourceGroup: "dummy-rg", 1393 Location: "westus2", 1394 CustomNetworkInterfaceName: "my-custom-nic", 1395 PrivateIPAddresses: []string{ 1396 "IP1", 1397 "IP2", 1398 }, 1399 SubnetID: "/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/dummy-rg/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/subnet1", 1400 ApplicationSecurityGroups: []string{ 1401 "ASG1", 1402 "ASG2", 1403 }, 1404 ClusterName: "my-cluster", 1405 PrivateLinkServiceConnections: []privateendpoints.PrivateLinkServiceConnection{ 1406 { 1407 Name: "my-pls-connection", 1408 RequestMessage: "my-request-message", 1409 PrivateLinkServiceID: "my-pls-id", 1410 GroupIDs: []string{ 1411 "my-group-id-1", 1412 }, 1413 }, 1414 }, 1415 ManualApproval: true, 1416 AdditionalTags: make(infrav1.Tags, 0), 1417 }, 1418 }, 1419 }, 1420 } 1421 for _, c := range cases { 1422 c := c 1423 t.Run(c.Name, func(t *testing.T) { 1424 s := &ManagedControlPlaneScope{ 1425 ControlPlane: c.Input.ControlPlane, 1426 Cluster: c.Input.Cluster, 1427 } 1428 if got := s.PrivateEndpointSpecs(); !reflect.DeepEqual(got, c.Expected) { 1429 t.Errorf("PrivateEndpointSpecs() = %s, want %s", specArrayToString(got), specArrayToString(c.Expected)) 1430 } 1431 }) 1432 } 1433 } 1434 1435 func TestManagedControlPlaneScope_AKSExtensionSpecs(t *testing.T) { 1436 cases := []struct { 1437 Name string 1438 Input ManagedControlPlaneScopeParams 1439 Expected []azure.ASOResourceSpecGetter[*asokubernetesconfigurationv1.Extension] 1440 Err string 1441 }{ 1442 { 1443 Name: "returns empty AKS extensions list if no extensions are specified", 1444 Input: ManagedControlPlaneScopeParams{ 1445 Cluster: &clusterv1.Cluster{ 1446 ObjectMeta: metav1.ObjectMeta{ 1447 Name: "cluster1", 1448 Namespace: "dummy-ns", 1449 }, 1450 }, 1451 ControlPlane: &infrav1.AzureManagedControlPlane{ 1452 ObjectMeta: metav1.ObjectMeta{ 1453 Name: "my-cluster", 1454 Namespace: "dummy-ns", 1455 }, 1456 Spec: infrav1.AzureManagedControlPlaneSpec{ 1457 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{}, 1458 }, 1459 }, 1460 }, 1461 }, 1462 { 1463 Name: "returns list of AKS extensions if extensions are specified", 1464 Input: ManagedControlPlaneScopeParams{ 1465 Cluster: &clusterv1.Cluster{ 1466 ObjectMeta: metav1.ObjectMeta{ 1467 Name: "my-cluster", 1468 Namespace: "dummy-ns", 1469 }, 1470 }, 1471 ControlPlane: &infrav1.AzureManagedControlPlane{ 1472 ObjectMeta: metav1.ObjectMeta{ 1473 Name: "my-cluster", 1474 Namespace: "dummy-ns", 1475 }, 1476 Spec: infrav1.AzureManagedControlPlaneSpec{ 1477 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1478 Extensions: []infrav1.AKSExtension{ 1479 { 1480 Name: "my-extension", 1481 AutoUpgradeMinorVersion: ptr.To(true), 1482 ConfigurationSettings: map[string]string{ 1483 "my-key": "my-value", 1484 }, 1485 ExtensionType: ptr.To("my-extension-type"), 1486 ReleaseTrain: ptr.To("my-release-train"), 1487 Version: ptr.To("my-version"), 1488 Plan: &infrav1.ExtensionPlan{ 1489 Name: "my-plan-name", 1490 Product: "my-product", 1491 Publisher: "my-publisher", 1492 }, 1493 AKSAssignedIdentityType: infrav1.AKSAssignedIdentitySystemAssigned, 1494 Identity: infrav1.ExtensionIdentitySystemAssigned, 1495 }, 1496 }, 1497 }, 1498 }, 1499 }, 1500 }, 1501 Expected: []azure.ASOResourceSpecGetter[*asokubernetesconfigurationv1.Extension]{ 1502 &aksextensions.AKSExtensionSpec{ 1503 Name: "my-extension", 1504 Namespace: "dummy-ns", 1505 AutoUpgradeMinorVersion: ptr.To(true), 1506 ConfigurationSettings: map[string]string{ 1507 "my-key": "my-value", 1508 }, 1509 ExtensionType: ptr.To("my-extension-type"), 1510 ReleaseTrain: ptr.To("my-release-train"), 1511 Version: ptr.To("my-version"), 1512 Owner: "/subscriptions//resourceGroups//providers/Microsoft.ContainerService/managedClusters/my-cluster", 1513 Plan: &infrav1.ExtensionPlan{ 1514 Name: "my-plan-name", 1515 Product: "my-product", 1516 Publisher: "my-publisher", 1517 }, 1518 AKSAssignedIdentityType: infrav1.AKSAssignedIdentitySystemAssigned, 1519 ExtensionIdentity: infrav1.ExtensionIdentitySystemAssigned, 1520 }, 1521 }, 1522 }, 1523 } 1524 1525 for _, c := range cases { 1526 c := c 1527 t.Run(c.Name, func(t *testing.T) { 1528 s := &ManagedControlPlaneScope{ 1529 ControlPlane: c.Input.ControlPlane, 1530 Cluster: c.Input.Cluster, 1531 } 1532 if got := s.AKSExtensionSpecs(); !reflect.DeepEqual(got, c.Expected) { 1533 t.Errorf("AKSExtensionSpecs() = %s, want %s", specArrayToString(got), specArrayToString(c.Expected)) 1534 } 1535 }) 1536 } 1537 } 1538 1539 func TestManagedControlPlaneScope_AutoUpgradeProfile(t *testing.T) { 1540 cases := []struct { 1541 name string 1542 input ManagedControlPlaneScopeParams 1543 expected *managedclusters.ManagedClusterAutoUpgradeProfile 1544 }{ 1545 { 1546 name: "Without AutoUpgradeProfile", 1547 input: ManagedControlPlaneScopeParams{ 1548 Cluster: &clusterv1.Cluster{ 1549 ObjectMeta: metav1.ObjectMeta{ 1550 Name: "cluster1", 1551 Namespace: "default", 1552 }, 1553 }, 1554 ControlPlane: &infrav1.AzureManagedControlPlane{ 1555 ObjectMeta: metav1.ObjectMeta{ 1556 Name: "cluster1", 1557 Namespace: "default", 1558 }, 1559 Spec: infrav1.AzureManagedControlPlaneSpec{ 1560 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1561 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1562 }, 1563 }, 1564 }, 1565 ManagedMachinePools: []ManagedMachinePool{ 1566 { 1567 MachinePool: getMachinePool("pool0"), 1568 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1569 }, 1570 }, 1571 }, 1572 expected: nil, 1573 }, 1574 { 1575 name: "With AutoUpgradeProfile UpgradeChannelNodeImage", 1576 input: ManagedControlPlaneScopeParams{ 1577 Cluster: &clusterv1.Cluster{ 1578 ObjectMeta: metav1.ObjectMeta{ 1579 Name: "cluster1", 1580 Namespace: "default", 1581 }, 1582 }, 1583 ControlPlane: &infrav1.AzureManagedControlPlane{ 1584 ObjectMeta: metav1.ObjectMeta{ 1585 Name: "cluster1", 1586 Namespace: "default", 1587 }, 1588 Spec: infrav1.AzureManagedControlPlaneSpec{ 1589 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1590 SubscriptionID: "00000000-0000-0000-0000-000000000000", 1591 AutoUpgradeProfile: &infrav1.ManagedClusterAutoUpgradeProfile{ 1592 UpgradeChannel: ptr.To(infrav1.UpgradeChannelNodeImage), 1593 }, 1594 }, 1595 }, 1596 }, 1597 ManagedMachinePools: []ManagedMachinePool{ 1598 { 1599 MachinePool: getMachinePool("pool0"), 1600 InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem), 1601 }, 1602 }, 1603 }, 1604 expected: &managedclusters.ManagedClusterAutoUpgradeProfile{ 1605 UpgradeChannel: ptr.To(infrav1.UpgradeChannelNodeImage), 1606 }, 1607 }, 1608 } 1609 for _, c := range cases { 1610 c := c 1611 t.Run(c.name, func(t *testing.T) { 1612 g := NewWithT(t) 1613 s := &ManagedControlPlaneScope{ 1614 ControlPlane: c.input.ControlPlane, 1615 Cluster: c.input.Cluster, 1616 } 1617 managedClusterGetter := s.ManagedClusterSpec() 1618 managedCluster, ok := managedClusterGetter.(*managedclusters.ManagedClusterSpec) 1619 g.Expect(ok).To(BeTrue()) 1620 g.Expect(managedCluster.AutoUpgradeProfile).To(Equal(c.expected)) 1621 }) 1622 } 1623 } 1624 1625 func TestManagedControlPlaneScope_GroupSpecs(t *testing.T) { 1626 cases := []struct { 1627 name string 1628 input ManagedControlPlaneScopeParams 1629 expected []azure.ASOResourceSpecGetter[*asoresourcesv1.ResourceGroup] 1630 }{ 1631 { 1632 name: "virtualNetwork belongs to a different resource group", 1633 input: ManagedControlPlaneScopeParams{ 1634 Cluster: &clusterv1.Cluster{ 1635 ObjectMeta: metav1.ObjectMeta{ 1636 Name: "cluster1", 1637 }, 1638 }, 1639 ControlPlane: &infrav1.AzureManagedControlPlane{ 1640 Spec: infrav1.AzureManagedControlPlaneSpec{ 1641 ResourceGroupName: "dummy-rg", 1642 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1643 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 1644 ResourceGroup: "different-rg", 1645 }, 1646 }, 1647 }, 1648 }, 1649 }, 1650 expected: []azure.ASOResourceSpecGetter[*asoresourcesv1.ResourceGroup]{ 1651 &groups.GroupSpec{ 1652 Name: "dummy-rg", 1653 AzureName: "dummy-rg", 1654 ClusterName: "cluster1", 1655 Location: "", 1656 AdditionalTags: make(infrav1.Tags, 0), 1657 }, 1658 &groups.GroupSpec{ 1659 Name: "different-rg", 1660 AzureName: "different-rg", 1661 ClusterName: "cluster1", 1662 Location: "", 1663 AdditionalTags: make(infrav1.Tags, 0), 1664 }, 1665 }, 1666 }, 1667 { 1668 name: "virtualNetwork belongs to a same resource group", 1669 input: ManagedControlPlaneScopeParams{ 1670 Cluster: &clusterv1.Cluster{ 1671 ObjectMeta: metav1.ObjectMeta{ 1672 Name: "cluster1", 1673 }, 1674 }, 1675 ControlPlane: &infrav1.AzureManagedControlPlane{ 1676 Spec: infrav1.AzureManagedControlPlaneSpec{ 1677 ResourceGroupName: "dummy-rg", 1678 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1679 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 1680 ResourceGroup: "dummy-rg", 1681 }, 1682 }, 1683 }, 1684 }, 1685 }, 1686 expected: []azure.ASOResourceSpecGetter[*asoresourcesv1.ResourceGroup]{ 1687 &groups.GroupSpec{ 1688 Name: "dummy-rg", 1689 AzureName: "dummy-rg", 1690 ClusterName: "cluster1", 1691 Location: "", 1692 AdditionalTags: make(infrav1.Tags, 0), 1693 }, 1694 }, 1695 }, 1696 { 1697 name: "virtualNetwork resource group not specified", 1698 input: ManagedControlPlaneScopeParams{ 1699 Cluster: &clusterv1.Cluster{ 1700 ObjectMeta: metav1.ObjectMeta{ 1701 Name: "cluster1", 1702 Namespace: "default", 1703 }, 1704 }, 1705 ControlPlane: &infrav1.AzureManagedControlPlane{ 1706 Spec: infrav1.AzureManagedControlPlaneSpec{ 1707 ResourceGroupName: "dummy-rg", 1708 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1709 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 1710 ManagedControlPlaneVirtualNetworkClassSpec: infrav1.ManagedControlPlaneVirtualNetworkClassSpec{ 1711 Name: "vnet1", 1712 }, 1713 }, 1714 }, 1715 }, 1716 }, 1717 }, 1718 expected: []azure.ASOResourceSpecGetter[*asoresourcesv1.ResourceGroup]{ 1719 &groups.GroupSpec{ 1720 Name: "dummy-rg", 1721 AzureName: "dummy-rg", 1722 ClusterName: "cluster1", 1723 Location: "", 1724 AdditionalTags: make(infrav1.Tags, 0), 1725 }, 1726 }, 1727 }, 1728 { 1729 name: "virtualNetwork belongs to different resource group with non-k8s name", 1730 input: ManagedControlPlaneScopeParams{ 1731 Cluster: &clusterv1.Cluster{ 1732 ObjectMeta: metav1.ObjectMeta{ 1733 Name: "cluster1", 1734 Namespace: "default", 1735 }, 1736 }, 1737 ControlPlane: &infrav1.AzureManagedControlPlane{ 1738 Spec: infrav1.AzureManagedControlPlaneSpec{ 1739 ResourceGroupName: "dummy-rg", 1740 AzureManagedControlPlaneClassSpec: infrav1.AzureManagedControlPlaneClassSpec{ 1741 VirtualNetwork: infrav1.ManagedControlPlaneVirtualNetwork{ 1742 ResourceGroup: "my_custom_rg", 1743 ManagedControlPlaneVirtualNetworkClassSpec: infrav1.ManagedControlPlaneVirtualNetworkClassSpec{ 1744 Name: "vnet1", 1745 }, 1746 }, 1747 }, 1748 }, 1749 }, 1750 }, 1751 expected: []azure.ASOResourceSpecGetter[*asoresourcesv1.ResourceGroup]{ 1752 &groups.GroupSpec{ 1753 Name: "dummy-rg", 1754 AzureName: "dummy-rg", 1755 ClusterName: "cluster1", 1756 Location: "", 1757 AdditionalTags: make(infrav1.Tags, 0), 1758 }, 1759 &groups.GroupSpec{ 1760 Name: "my-custom-rg", 1761 AzureName: "my_custom_rg", 1762 ClusterName: "cluster1", 1763 Location: "", 1764 AdditionalTags: make(infrav1.Tags, 0), 1765 }, 1766 }, 1767 }, 1768 } 1769 1770 for _, c := range cases { 1771 c := c 1772 t.Run(c.name, func(t *testing.T) { 1773 s := &ManagedControlPlaneScope{ 1774 ControlPlane: c.input.ControlPlane, 1775 Cluster: c.input.Cluster, 1776 } 1777 if got := s.GroupSpecs(); !reflect.DeepEqual(got, c.expected) { 1778 t.Errorf("GroupSpecs() = %s, want %s", specArrayToString(got), specArrayToString(c.expected)) 1779 } 1780 }) 1781 } 1782 }