sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/virtualmachines/spec_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 virtualmachines 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" 24 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4" 25 "github.com/google/go-cmp/cmp" 26 . "github.com/onsi/gomega" 27 "k8s.io/utils/ptr" 28 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 29 "sigs.k8s.io/cluster-api-provider-azure/azure" 30 "sigs.k8s.io/cluster-api-provider-azure/azure/services/resourceskus" 31 gomockinternal "sigs.k8s.io/cluster-api-provider-azure/internal/test/matchers/gomock" 32 ) 33 34 var ( 35 validSKU = resourceskus.SKU{ 36 Name: ptr.To("Standard_D2v3"), 37 Kind: ptr.To(string(resourceskus.VirtualMachines)), 38 Locations: []*string{ 39 ptr.To("test-location"), 40 }, 41 Capabilities: []*armcompute.ResourceSKUCapabilities{ 42 { 43 Name: ptr.To(resourceskus.VCPUs), 44 Value: ptr.To("2"), 45 }, 46 { 47 Name: ptr.To(resourceskus.MemoryGB), 48 Value: ptr.To("4"), 49 }, 50 }, 51 } 52 53 validSKUWithEncryptionAtHost = resourceskus.SKU{ 54 Name: ptr.To("Standard_D2v3"), 55 Kind: ptr.To(string(resourceskus.VirtualMachines)), 56 Locations: []*string{ 57 ptr.To("test-location"), 58 }, 59 Capabilities: []*armcompute.ResourceSKUCapabilities{ 60 { 61 Name: ptr.To(resourceskus.VCPUs), 62 Value: ptr.To("2"), 63 }, 64 { 65 Name: ptr.To(resourceskus.MemoryGB), 66 Value: ptr.To("4"), 67 }, 68 { 69 Name: ptr.To(resourceskus.EncryptionAtHost), 70 Value: ptr.To(string(resourceskus.CapabilitySupported)), 71 }, 72 }, 73 } 74 75 validSKUWithTrustedLaunchDisabled = resourceskus.SKU{ 76 Name: ptr.To("Standard_D2v3"), 77 Kind: ptr.To(string(resourceskus.VirtualMachines)), 78 Locations: []*string{ 79 ptr.To("test-location"), 80 }, 81 Capabilities: []*armcompute.ResourceSKUCapabilities{ 82 { 83 Name: ptr.To(resourceskus.VCPUs), 84 Value: ptr.To("2"), 85 }, 86 { 87 Name: ptr.To(resourceskus.MemoryGB), 88 Value: ptr.To("4"), 89 }, 90 { 91 Name: ptr.To(resourceskus.TrustedLaunchDisabled), 92 Value: ptr.To(string(resourceskus.CapabilitySupported)), 93 }, 94 }, 95 } 96 97 validSKUWithConfidentialComputingType = resourceskus.SKU{ 98 Name: ptr.To("Standard_D2v3"), 99 Kind: ptr.To(string(resourceskus.VirtualMachines)), 100 Locations: []*string{ 101 ptr.To("test-location"), 102 }, 103 Capabilities: []*armcompute.ResourceSKUCapabilities{ 104 { 105 Name: ptr.To(resourceskus.VCPUs), 106 Value: ptr.To("2"), 107 }, 108 { 109 Name: ptr.To(resourceskus.MemoryGB), 110 Value: ptr.To("4"), 111 }, 112 { 113 Name: ptr.To(resourceskus.ConfidentialComputingType), 114 Value: ptr.To(string(resourceskus.CapabilitySupported)), 115 }, 116 }, 117 } 118 119 validSKUWithEphemeralOS = resourceskus.SKU{ 120 Name: ptr.To("Standard_D2v3"), 121 Kind: ptr.To(string(resourceskus.VirtualMachines)), 122 Locations: []*string{ 123 ptr.To("test-location"), 124 }, 125 Capabilities: []*armcompute.ResourceSKUCapabilities{ 126 { 127 Name: ptr.To(resourceskus.VCPUs), 128 Value: ptr.To("2"), 129 }, 130 { 131 Name: ptr.To(resourceskus.MemoryGB), 132 Value: ptr.To("4"), 133 }, 134 { 135 Name: ptr.To(resourceskus.EphemeralOSDisk), 136 Value: ptr.To("True"), 137 }, 138 }, 139 } 140 141 validSKUWithUltraSSD = resourceskus.SKU{ 142 Name: ptr.To("Standard_D2v3"), 143 Kind: ptr.To(string(resourceskus.VirtualMachines)), 144 Locations: []*string{ 145 ptr.To("test-location"), 146 }, 147 LocationInfo: []*armcompute.ResourceSKULocationInfo{ 148 { 149 Location: ptr.To("test-location"), 150 Zones: []*string{ptr.To("1")}, 151 ZoneDetails: []*armcompute.ResourceSKUZoneDetails{ 152 { 153 Capabilities: []*armcompute.ResourceSKUCapabilities{ 154 { 155 Name: ptr.To("UltraSSDAvailable"), 156 Value: ptr.To("True"), 157 }, 158 }, 159 Name: []*string{ptr.To("1")}, 160 }, 161 }, 162 }, 163 }, 164 Capabilities: []*armcompute.ResourceSKUCapabilities{ 165 { 166 Name: ptr.To(resourceskus.VCPUs), 167 Value: ptr.To("2"), 168 }, 169 { 170 Name: ptr.To(resourceskus.MemoryGB), 171 Value: ptr.To("4"), 172 }, 173 }, 174 } 175 176 invalidCPUSKU = resourceskus.SKU{ 177 Name: ptr.To("Standard_D2v3"), 178 Kind: ptr.To(string(resourceskus.VirtualMachines)), 179 Locations: []*string{ 180 ptr.To("test-location"), 181 }, 182 Capabilities: []*armcompute.ResourceSKUCapabilities{ 183 { 184 Name: ptr.To(resourceskus.VCPUs), 185 Value: ptr.To("1"), 186 }, 187 { 188 Name: ptr.To(resourceskus.MemoryGB), 189 Value: ptr.To("4"), 190 }, 191 }, 192 } 193 194 invalidMemSKU = resourceskus.SKU{ 195 Name: ptr.To("Standard_D2v3"), 196 Kind: ptr.To(string(resourceskus.VirtualMachines)), 197 Locations: []*string{ 198 ptr.To("test-location"), 199 }, 200 Capabilities: []*armcompute.ResourceSKUCapabilities{ 201 { 202 Name: ptr.To(resourceskus.VCPUs), 203 Value: ptr.To("2"), 204 }, 205 { 206 Name: ptr.To(resourceskus.MemoryGB), 207 Value: ptr.To("1"), 208 }, 209 }, 210 } 211 212 deletePolicy = infrav1.SpotEvictionPolicyDelete 213 ) 214 215 func TestParameters(t *testing.T) { 216 testcases := []struct { 217 name string 218 spec *VMSpec 219 existing interface{} 220 expect func(g *WithT, result interface{}) 221 expectedError string 222 }{ 223 { 224 name: "fails if existing is not a VirtualMachine", 225 spec: &VMSpec{}, 226 existing: armnetwork.VirtualNetwork{}, 227 expect: func(g *WithT, result interface{}) { 228 g.Expect(result).To(BeNil()) 229 }, 230 expectedError: "armnetwork.VirtualNetwork is not an armcompute.VirtualMachine", 231 }, 232 { 233 name: "returns nil if vm already exists", 234 spec: &VMSpec{}, 235 existing: armcompute.VirtualMachine{}, 236 expect: func(g *WithT, result interface{}) { 237 g.Expect(result).To(BeNil()) 238 }, 239 expectedError: "", 240 }, 241 { 242 name: "fails if vm deleted out of band, should not recreate", 243 spec: &VMSpec{ 244 ProviderID: "fake/vm/id", 245 }, 246 existing: nil, 247 expect: func(g *WithT, result interface{}) { 248 g.Expect(result).To(BeNil()) 249 }, 250 expectedError: azure.VMDeletedError{ProviderID: "fake/vm/id"}.Error(), 251 }, 252 { 253 name: "can create a vm with system assigned identity ", 254 spec: &VMSpec{ 255 Name: "my-vm", 256 Role: infrav1.Node, 257 NICIDs: []string{"my-nic"}, 258 SSHKeyData: "fakesshpublickey", 259 Size: "Standard_D2v3", 260 Zone: "1", 261 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 262 Identity: infrav1.VMIdentitySystemAssigned, 263 SKU: validSKU, 264 }, 265 existing: nil, 266 expect: func(g *WithT, result interface{}) { 267 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 268 g.Expect(result.(armcompute.VirtualMachine).Identity.Type).To(Equal(ptr.To(armcompute.ResourceIdentityTypeSystemAssigned))) 269 g.Expect(result.(armcompute.VirtualMachine).Identity.UserAssignedIdentities).To(BeEmpty()) 270 }, 271 expectedError: "", 272 }, 273 { 274 name: "can create a vm with user assigned identity ", 275 spec: &VMSpec{ 276 Name: "my-vm", 277 Role: infrav1.Node, 278 NICIDs: []string{"my-nic"}, 279 SSHKeyData: "fakesshpublickey", 280 Size: "Standard_D2v3", 281 Zone: "1", 282 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 283 Identity: infrav1.VMIdentityUserAssigned, 284 UserAssignedIdentities: []infrav1.UserAssignedIdentity{{ProviderID: "my-user-id"}}, 285 SKU: validSKU, 286 }, 287 existing: nil, 288 expect: func(g *WithT, result interface{}) { 289 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 290 g.Expect(result.(armcompute.VirtualMachine).Identity.Type).To(Equal(ptr.To(armcompute.ResourceIdentityTypeUserAssigned))) 291 g.Expect(result.(armcompute.VirtualMachine).Identity.UserAssignedIdentities).To(Equal(map[string]*armcompute.UserAssignedIdentitiesValue{"my-user-id": {}})) 292 }, 293 expectedError: "", 294 }, 295 { 296 name: "can create a spot vm", 297 spec: &VMSpec{ 298 Name: "my-vm", 299 Role: infrav1.Node, 300 NICIDs: []string{"my-nic"}, 301 SSHKeyData: "fakesshpublickey", 302 Size: "Standard_D2v3", 303 Zone: "1", 304 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 305 SpotVMOptions: &infrav1.SpotVMOptions{}, 306 SKU: validSKU, 307 }, 308 existing: nil, 309 expect: func(g *WithT, result interface{}) { 310 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 311 g.Expect(result.(armcompute.VirtualMachine).Properties.Priority).To(Equal(ptr.To(armcompute.VirtualMachinePriorityTypesSpot))) 312 g.Expect(result.(armcompute.VirtualMachine).Properties.BillingProfile).To(BeNil()) 313 }, 314 expectedError: "", 315 }, 316 317 { 318 name: "can create a spot vm with evictionPolicy delete", 319 spec: &VMSpec{ 320 Name: "my-vm", 321 Role: infrav1.Node, 322 NICIDs: []string{"my-nic"}, 323 SSHKeyData: "fakesshpublickey", 324 Size: "Standard_D2v3", 325 Zone: "1", 326 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 327 SpotVMOptions: &infrav1.SpotVMOptions{EvictionPolicy: &deletePolicy}, 328 SKU: validSKU, 329 }, 330 existing: nil, 331 expect: func(g *WithT, result interface{}) { 332 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 333 g.Expect(result.(armcompute.VirtualMachine).Properties.Priority).To(Equal(ptr.To(armcompute.VirtualMachinePriorityTypesSpot))) 334 g.Expect(result.(armcompute.VirtualMachine).Properties.EvictionPolicy).To(Equal(ptr.To(armcompute.VirtualMachineEvictionPolicyTypesDelete))) 335 g.Expect(result.(armcompute.VirtualMachine).Properties.BillingProfile).To(BeNil()) 336 }, 337 expectedError: "", 338 }, 339 { 340 name: "can create a windows vm", 341 spec: &VMSpec{ 342 Name: "my-vm", 343 Role: infrav1.Node, 344 NICIDs: []string{"my-nic"}, 345 SSHKeyData: "fakesshpublickey", 346 Size: "Standard_D2v3", 347 Zone: "1", 348 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 349 OSDisk: infrav1.OSDisk{ 350 OSType: "Windows", 351 DiskSizeGB: ptr.To[int32](128), 352 ManagedDisk: &infrav1.ManagedDiskParameters{ 353 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 354 }, 355 }, 356 SKU: validSKU, 357 }, 358 existing: nil, 359 expect: func(g *WithT, result interface{}) { 360 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 361 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.OSDisk.OSType).To(Equal(ptr.To(armcompute.OperatingSystemTypesWindows))) 362 g.Expect(*result.(armcompute.VirtualMachine).Properties.OSProfile.AdminPassword).Should(HaveLen(123)) 363 g.Expect(*result.(armcompute.VirtualMachine).Properties.OSProfile.AdminUsername).Should(Equal("capi")) 364 g.Expect(*result.(armcompute.VirtualMachine).Properties.OSProfile.WindowsConfiguration.EnableAutomaticUpdates).Should(BeFalse()) 365 }, 366 expectedError: "", 367 }, 368 { 369 name: "can create a vm with encryption", 370 spec: &VMSpec{ 371 Name: "my-vm", 372 Role: infrav1.Node, 373 NICIDs: []string{"my-nic"}, 374 SSHKeyData: "fakesshpublickey", 375 Size: "Standard_D2v3", 376 Zone: "1", 377 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 378 OSDisk: infrav1.OSDisk{ 379 ManagedDisk: &infrav1.ManagedDiskParameters{ 380 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 381 DiskEncryptionSet: &infrav1.DiskEncryptionSetParameters{ 382 ID: "my-diskencryptionset-id", 383 }, 384 }, 385 }, 386 SKU: validSKU, 387 }, 388 existing: nil, 389 expect: func(g *WithT, result interface{}) { 390 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 391 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.OSDisk.ManagedDisk.DiskEncryptionSet.ID).To(Equal(ptr.To("my-diskencryptionset-id"))) 392 }, 393 expectedError: "", 394 }, 395 { 396 name: "can create a vm with encryption at host", 397 spec: &VMSpec{ 398 Name: "my-vm", 399 Role: infrav1.Node, 400 NICIDs: []string{"my-nic"}, 401 SSHKeyData: "fakesshpublickey", 402 Size: "Standard_D2v3", 403 Zone: "1", 404 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 405 SecurityProfile: &infrav1.SecurityProfile{EncryptionAtHost: ptr.To(true)}, 406 SKU: validSKUWithEncryptionAtHost, 407 }, 408 existing: nil, 409 expect: func(g *WithT, result interface{}) { 410 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 411 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.EncryptionAtHost).To(BeTrue()) 412 }, 413 expectedError: "", 414 }, 415 { 416 name: "can create a vm and assign it to an availability set", 417 spec: &VMSpec{ 418 Name: "my-vm", 419 Role: infrav1.Node, 420 NICIDs: []string{"my-nic"}, 421 SSHKeyData: "fakesshpublickey", 422 Size: "Standard_D2v3", 423 AvailabilitySetID: "fake-availability-set-id", 424 Zone: "", 425 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 426 SKU: validSKU, 427 }, 428 existing: nil, 429 expect: func(g *WithT, result interface{}) { 430 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 431 g.Expect(result.(armcompute.VirtualMachine).Zones).To(BeNil()) 432 g.Expect(result.(armcompute.VirtualMachine).Properties.AvailabilitySet.ID).To(Equal(ptr.To("fake-availability-set-id"))) 433 }, 434 expectedError: "", 435 }, 436 { 437 name: "can create a vm with EphemeralOSDisk", 438 spec: &VMSpec{ 439 Name: "my-vm", 440 Role: infrav1.Node, 441 NICIDs: []string{"my-nic"}, 442 SSHKeyData: "fakesshpublickey", 443 Size: "Standard_D2v3", 444 OSDisk: infrav1.OSDisk{ 445 OSType: "Linux", 446 DiskSizeGB: ptr.To[int32](128), 447 ManagedDisk: &infrav1.ManagedDiskParameters{ 448 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 449 }, 450 DiffDiskSettings: &infrav1.DiffDiskSettings{ 451 Option: string(armcompute.DiffDiskOptionsLocal), 452 }, 453 }, 454 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 455 SKU: validSKUWithEphemeralOS, 456 }, 457 existing: nil, 458 expect: func(g *WithT, result interface{}) { 459 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 460 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.OSDisk.DiffDiskSettings.Option).To(Equal(ptr.To(armcompute.DiffDiskOptionsLocal))) 461 }, 462 expectedError: "", 463 }, 464 { 465 name: "can create a trusted launch vm", 466 spec: &VMSpec{ 467 Name: "my-vm", 468 Role: infrav1.Node, 469 NICIDs: []string{"my-nic"}, 470 SSHKeyData: "fakesshpublickey", 471 Size: "Standard_D2v3", 472 AvailabilitySetID: "fake-availability-set-id", 473 Zone: "", 474 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 475 SecurityProfile: &infrav1.SecurityProfile{ 476 SecurityType: infrav1.SecurityTypesTrustedLaunch, 477 UefiSettings: &infrav1.UefiSettings{ 478 SecureBootEnabled: ptr.To(true), 479 VTpmEnabled: ptr.To(true), 480 }, 481 }, 482 SKU: validSKU, 483 }, 484 existing: nil, 485 expect: func(g *WithT, result interface{}) { 486 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 487 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.UefiSettings.SecureBootEnabled).To(BeTrue()) 488 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.UefiSettings.VTpmEnabled).To(BeTrue()) 489 }, 490 expectedError: "", 491 }, 492 { 493 name: "can create a confidential vm", 494 spec: &VMSpec{ 495 Name: "my-vm", 496 Role: infrav1.Node, 497 NICIDs: []string{"my-nic"}, 498 SSHKeyData: "fakesshpublickey", 499 Size: "Standard_D2v3", 500 AvailabilitySetID: "fake-availability-set-id", 501 Zone: "", 502 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 503 OSDisk: infrav1.OSDisk{ 504 OSType: "Linux", 505 DiskSizeGB: ptr.To[int32](128), 506 ManagedDisk: &infrav1.ManagedDiskParameters{ 507 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 508 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 509 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 510 }, 511 }, 512 }, 513 SecurityProfile: &infrav1.SecurityProfile{ 514 SecurityType: infrav1.SecurityTypesConfidentialVM, 515 UefiSettings: &infrav1.UefiSettings{ 516 SecureBootEnabled: ptr.To(false), 517 VTpmEnabled: ptr.To(true), 518 }, 519 }, 520 SKU: validSKUWithConfidentialComputingType, 521 }, 522 existing: nil, 523 expect: func(g *WithT, result interface{}) { 524 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 525 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.OSDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType).To(Equal(ptr.To(armcompute.SecurityEncryptionTypesVMGuestStateOnly))) 526 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.UefiSettings.VTpmEnabled).To(BeTrue()) 527 }, 528 expectedError: "", 529 }, 530 { 531 name: "creating a confidential vm without the SecurityType set to ConfidentialVM fails", 532 spec: &VMSpec{ 533 Name: "my-vm", 534 Role: infrav1.Node, 535 NICIDs: []string{"my-nic"}, 536 SSHKeyData: "fakesshpublickey", 537 Size: "Standard_D2v3", 538 AvailabilitySetID: "fake-availability-set-id", 539 Zone: "", 540 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 541 OSDisk: infrav1.OSDisk{ 542 OSType: "Linux", 543 DiskSizeGB: ptr.To[int32](128), 544 ManagedDisk: &infrav1.ManagedDiskParameters{ 545 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 546 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 547 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 548 }, 549 }, 550 }, 551 SecurityProfile: &infrav1.SecurityProfile{ 552 SecurityType: "", 553 UefiSettings: &infrav1.UefiSettings{ 554 SecureBootEnabled: ptr.To(false), 555 VTpmEnabled: ptr.To(true), 556 }, 557 }, 558 SKU: validSKUWithConfidentialComputingType, 559 }, 560 existing: nil, 561 expect: func(g *WithT, result interface{}) { 562 g.Expect(result).To(BeNil()) 563 }, 564 expectedError: "reconcile error that cannot be recovered occurred: securityType should be set to ConfidentialVM when securityEncryptionType is set. Object will not be requeued", 565 }, 566 { 567 name: "creating a vm with encryption at host enabled for unsupported VM type fails", 568 spec: &VMSpec{ 569 Name: "my-vm", 570 Role: infrav1.Node, 571 NICIDs: []string{"my-nic"}, 572 SSHKeyData: "fakesshpublickey", 573 Size: "Standard_D2v3", 574 AvailabilitySetID: "fake-availability-set-id", 575 Zone: "", 576 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 577 SecurityProfile: &infrav1.SecurityProfile{EncryptionAtHost: ptr.To(true)}, 578 SKU: validSKU, 579 }, 580 existing: nil, 581 expect: func(g *WithT, result interface{}) { 582 g.Expect(result).To(BeNil()) 583 }, 584 expectedError: "reconcile error that cannot be recovered occurred: encryption at host is not supported for VM type Standard_D2v3. Object will not be requeued", 585 }, 586 { 587 name: "creating a trusted launch vm without the SecurityType set to TrustedLaunch fails", 588 spec: &VMSpec{ 589 Name: "my-vm", 590 Role: infrav1.Node, 591 NICIDs: []string{"my-nic"}, 592 SSHKeyData: "fakesshpublickey", 593 Size: "Standard_D2v3", 594 AvailabilitySetID: "fake-availability-set-id", 595 Zone: "", 596 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 597 OSDisk: infrav1.OSDisk{ 598 OSType: "Linux", 599 DiskSizeGB: ptr.To[int32](128), 600 ManagedDisk: &infrav1.ManagedDiskParameters{ 601 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 602 }, 603 }, 604 SecurityProfile: &infrav1.SecurityProfile{ 605 SecurityType: "", 606 UefiSettings: &infrav1.UefiSettings{ 607 SecureBootEnabled: ptr.To(false), 608 VTpmEnabled: ptr.To(true), 609 }, 610 }, 611 SKU: validSKUWithConfidentialComputingType, 612 }, 613 existing: nil, 614 expect: func(g *WithT, result interface{}) { 615 g.Expect(result).To(BeNil()) 616 }, 617 expectedError: "reconcile error that cannot be recovered occurred: securityType should be set to TrustedLaunch when vTpmEnabled is true. Object will not be requeued", 618 }, 619 { 620 name: "creating a trusted launch vm with secure boot enabled on unsupported VM type fails", 621 spec: &VMSpec{ 622 Name: "my-vm", 623 Role: infrav1.Node, 624 NICIDs: []string{"my-nic"}, 625 SSHKeyData: "fakesshpublickey", 626 Size: "Standard_D2v3", 627 AvailabilitySetID: "fake-availability-set-id", 628 Zone: "", 629 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 630 SecurityProfile: &infrav1.SecurityProfile{ 631 SecurityType: infrav1.SecurityTypesTrustedLaunch, 632 UefiSettings: &infrav1.UefiSettings{ 633 SecureBootEnabled: ptr.To(true), 634 }, 635 }, 636 SKU: validSKUWithTrustedLaunchDisabled, 637 }, 638 existing: nil, 639 expect: func(g *WithT, result interface{}) { 640 g.Expect(result).To(BeNil()) 641 }, 642 expectedError: "reconcile error that cannot be recovered occurred: secure boot is not supported for VM type Standard_D2v3. Object will not be requeued", 643 }, 644 { 645 name: "creating a trusted launch vm with vTPM enabled on unsupported VM type fails", 646 spec: &VMSpec{ 647 Name: "my-vm", 648 Role: infrav1.Node, 649 NICIDs: []string{"my-nic"}, 650 SSHKeyData: "fakesshpublickey", 651 Size: "Standard_D2v3", 652 AvailabilitySetID: "fake-availability-set-id", 653 Zone: "", 654 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 655 SecurityProfile: &infrav1.SecurityProfile{ 656 SecurityType: infrav1.SecurityTypesTrustedLaunch, 657 UefiSettings: &infrav1.UefiSettings{ 658 VTpmEnabled: ptr.To(true), 659 }, 660 }, 661 SKU: validSKUWithTrustedLaunchDisabled, 662 }, 663 existing: nil, 664 expect: func(g *WithT, result interface{}) { 665 g.Expect(result).To(BeNil()) 666 }, 667 expectedError: "reconcile error that cannot be recovered occurred: vTPM is not supported for VM type Standard_D2v3. Object will not be requeued", 668 }, 669 { 670 name: "creating a confidential vm with securityTypeEncryption DiskWithVMGuestState and encryption at host enabled fails", 671 spec: &VMSpec{ 672 Name: "my-vm", 673 Role: infrav1.Node, 674 NICIDs: []string{"my-nic"}, 675 SSHKeyData: "fakesshpublickey", 676 Size: "Standard_D2v3", 677 AvailabilitySetID: "fake-availability-set-id", 678 Zone: "", 679 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 680 OSDisk: infrav1.OSDisk{ 681 OSType: "Linux", 682 DiskSizeGB: ptr.To[int32](128), 683 ManagedDisk: &infrav1.ManagedDiskParameters{ 684 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 685 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 686 SecurityEncryptionType: infrav1.SecurityEncryptionTypeDiskWithVMGuestState, 687 }, 688 }, 689 }, 690 SecurityProfile: &infrav1.SecurityProfile{ 691 EncryptionAtHost: ptr.To(true), 692 SecurityType: infrav1.SecurityTypesConfidentialVM, 693 UefiSettings: &infrav1.UefiSettings{ 694 VTpmEnabled: ptr.To(true), 695 }, 696 }, 697 SKU: validSKUWithConfidentialComputingType, 698 }, 699 existing: nil, 700 expect: func(g *WithT, result interface{}) { 701 g.Expect(result).To(BeNil()) 702 }, 703 expectedError: "reconcile error that cannot be recovered occurred: encryption at host is not supported when securityEncryptionType is set to DiskWithVMGuestState. Object will not be requeued", 704 }, 705 { 706 name: "creating a confidential vm with DiskWithVMGuestState encryption type and secure boot disabled fails", 707 spec: &VMSpec{ 708 Name: "my-vm", 709 Role: infrav1.Node, 710 NICIDs: []string{"my-nic"}, 711 SSHKeyData: "fakesshpublickey", 712 Size: "Standard_D2v3", 713 AvailabilitySetID: "fake-availability-set-id", 714 Zone: "", 715 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 716 OSDisk: infrav1.OSDisk{ 717 OSType: "Linux", 718 DiskSizeGB: ptr.To[int32](128), 719 ManagedDisk: &infrav1.ManagedDiskParameters{ 720 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 721 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 722 SecurityEncryptionType: infrav1.SecurityEncryptionTypeDiskWithVMGuestState, 723 }, 724 }, 725 }, 726 SecurityProfile: &infrav1.SecurityProfile{ 727 SecurityType: infrav1.SecurityTypesConfidentialVM, 728 UefiSettings: &infrav1.UefiSettings{ 729 SecureBootEnabled: ptr.To(false), 730 VTpmEnabled: ptr.To(true), 731 }, 732 }, 733 SKU: validSKUWithConfidentialComputingType, 734 }, 735 existing: nil, 736 expect: func(g *WithT, result interface{}) { 737 g.Expect(result).To(BeNil()) 738 }, 739 expectedError: "reconcile error that cannot be recovered occurred: secureBootEnabled should be true when securityEncryptionType is set to DiskWithVMGuestState. Object will not be requeued", 740 }, 741 { 742 name: "creating a confidential vm with vTPM disabled fails", 743 spec: &VMSpec{ 744 Name: "my-vm", 745 Role: infrav1.Node, 746 NICIDs: []string{"my-nic"}, 747 SSHKeyData: "fakesshpublickey", 748 Size: "Standard_D2v3", 749 AvailabilitySetID: "fake-availability-set-id", 750 Zone: "", 751 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 752 OSDisk: infrav1.OSDisk{ 753 OSType: "Linux", 754 DiskSizeGB: ptr.To[int32](128), 755 ManagedDisk: &infrav1.ManagedDiskParameters{ 756 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 757 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 758 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 759 }, 760 }, 761 }, 762 SecurityProfile: &infrav1.SecurityProfile{ 763 SecurityType: infrav1.SecurityTypesConfidentialVM, 764 UefiSettings: &infrav1.UefiSettings{ 765 VTpmEnabled: ptr.To(false), 766 }, 767 }, 768 SKU: validSKUWithConfidentialComputingType, 769 }, 770 existing: nil, 771 expect: func(g *WithT, result interface{}) { 772 g.Expect(result).To(BeNil()) 773 }, 774 expectedError: "reconcile error that cannot be recovered occurred: vTpmEnabled should be true when securityEncryptionType is set. Object will not be requeued", 775 }, 776 { 777 name: "creating a confidential vm with unsupported VM type fails", 778 spec: &VMSpec{ 779 Name: "my-vm", 780 Role: infrav1.Node, 781 NICIDs: []string{"my-nic"}, 782 SSHKeyData: "fakesshpublickey", 783 Size: "Standard_D2v3", 784 AvailabilitySetID: "fake-availability-set-id", 785 Zone: "", 786 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 787 OSDisk: infrav1.OSDisk{ 788 OSType: "Linux", 789 DiskSizeGB: ptr.To[int32](128), 790 ManagedDisk: &infrav1.ManagedDiskParameters{ 791 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 792 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 793 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 794 }, 795 }, 796 }, 797 SecurityProfile: &infrav1.SecurityProfile{ 798 SecurityType: infrav1.SecurityTypesConfidentialVM, 799 UefiSettings: &infrav1.UefiSettings{ 800 VTpmEnabled: ptr.To(true), 801 }, 802 }, 803 SKU: validSKU, 804 }, 805 existing: nil, 806 expect: func(g *WithT, result interface{}) { 807 g.Expect(result).To(BeNil()) 808 }, 809 expectedError: "reconcile error that cannot be recovered occurred: VM size Standard_D2v3 does not support confidential computing. Select a different VM size or remove the security profile of the OS disk. Object will not be requeued", 810 }, 811 { 812 name: "cannot create vm with EphemeralOSDisk if does not support ephemeral os", 813 spec: &VMSpec{ 814 Name: "my-vm", 815 Role: infrav1.Node, 816 NICIDs: []string{"my-nic"}, 817 SSHKeyData: "fakesshpublickey", 818 Size: "Standard_D2v3", 819 OSDisk: infrav1.OSDisk{ 820 OSType: "Linux", 821 DiskSizeGB: ptr.To[int32](128), 822 ManagedDisk: &infrav1.ManagedDiskParameters{ 823 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 824 }, 825 DiffDiskSettings: &infrav1.DiffDiskSettings{ 826 Option: string(armcompute.DiffDiskOptionsLocal), 827 }, 828 }, 829 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 830 SKU: validSKU, 831 }, 832 existing: nil, 833 expect: func(g *WithT, result interface{}) { 834 g.Expect(result).To(BeNil()) 835 }, 836 expectedError: "reconcile error that cannot be recovered occurred: VM size Standard_D2v3 does not support ephemeral os. Select a different VM size or disable ephemeral os. Object will not be requeued", 837 }, 838 { 839 name: "cannot create vm if vCPU is less than 2", 840 spec: &VMSpec{ 841 Name: "my-vm", 842 Role: infrav1.Node, 843 NICIDs: []string{"my-nic"}, 844 SSHKeyData: "fakesshpublickey", 845 Size: "Standard_D2v3", 846 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 847 SKU: invalidCPUSKU, 848 }, 849 existing: nil, 850 expect: func(g *WithT, result interface{}) { 851 g.Expect(result).To(BeNil()) 852 }, 853 expectedError: "reconcile error that cannot be recovered occurred: VM size should be bigger or equal to at least 2 vCPUs. Object will not be requeued", 854 }, 855 { 856 name: "cannot create vm if memory is less than 2Gi", 857 spec: &VMSpec{ 858 Name: "my-vm", 859 Role: infrav1.Node, 860 NICIDs: []string{"my-nic"}, 861 SSHKeyData: "fakesshpublickey", 862 Size: "Standard_D2v3", 863 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 864 SKU: invalidMemSKU, 865 }, 866 existing: nil, 867 expect: func(g *WithT, result interface{}) { 868 g.Expect(result).To(BeNil()) 869 }, 870 expectedError: "reconcile error that cannot be recovered occurred: VM memory should be bigger or equal to at least 2Gi. Object will not be requeued", 871 }, 872 { 873 name: "can create a vm with a marketplace image using a plan", 874 spec: &VMSpec{ 875 Name: "my-vm", 876 Role: infrav1.Node, 877 NICIDs: []string{"my-nic"}, 878 SSHKeyData: "fakesshpublickey", 879 Size: "Standard_D2v3", 880 Image: &infrav1.Image{ 881 Marketplace: &infrav1.AzureMarketplaceImage{ 882 ImagePlan: infrav1.ImagePlan{ 883 Publisher: "fake-publisher", 884 Offer: "my-offer", 885 SKU: "sku-id", 886 }, 887 Version: "1.0", 888 ThirdPartyImage: true, 889 }, 890 }, 891 SKU: validSKU, 892 }, 893 existing: nil, 894 expect: func(g *WithT, result interface{}) { 895 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 896 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.Offer).To(Equal(ptr.To("my-offer"))) 897 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.Publisher).To(Equal(ptr.To("fake-publisher"))) 898 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.SKU).To(Equal(ptr.To("sku-id"))) 899 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.Version).To(Equal(ptr.To("1.0"))) 900 g.Expect(result.(armcompute.VirtualMachine).Plan.Name).To(Equal(ptr.To("sku-id"))) 901 g.Expect(result.(armcompute.VirtualMachine).Plan.Publisher).To(Equal(ptr.To("fake-publisher"))) 902 g.Expect(result.(armcompute.VirtualMachine).Plan.Product).To(Equal(ptr.To("my-offer"))) 903 }, 904 expectedError: "", 905 }, 906 { 907 name: "can create a vm with a SIG image using a plan", 908 spec: &VMSpec{ 909 Name: "my-vm", 910 Role: infrav1.Node, 911 NICIDs: []string{"my-nic"}, 912 SSHKeyData: "fakesshpublickey", 913 Size: "Standard_D2v3", 914 Image: &infrav1.Image{ 915 SharedGallery: &infrav1.AzureSharedGalleryImage{ 916 SubscriptionID: "fake-sub-id", 917 ResourceGroup: "fake-rg", 918 Gallery: "fake-gallery", 919 Name: "fake-name", 920 Version: "1.0", 921 Publisher: ptr.To("fake-publisher"), 922 Offer: ptr.To("my-offer"), 923 SKU: ptr.To("sku-id"), 924 }, 925 }, 926 SKU: validSKU, 927 }, 928 existing: nil, 929 expect: func(g *WithT, result interface{}) { 930 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 931 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.ID).To(Equal(ptr.To("/subscriptions/fake-sub-id/resourceGroups/fake-rg/providers/Microsoft.Compute/galleries/fake-gallery/images/fake-name/versions/1.0"))) 932 g.Expect(result.(armcompute.VirtualMachine).Plan.Name).To(Equal(ptr.To("sku-id"))) 933 g.Expect(result.(armcompute.VirtualMachine).Plan.Publisher).To(Equal(ptr.To("fake-publisher"))) 934 g.Expect(result.(armcompute.VirtualMachine).Plan.Product).To(Equal(ptr.To("my-offer"))) 935 }, 936 expectedError: "", 937 }, 938 { 939 name: "can create a vm with ultra disk enabled", 940 spec: &VMSpec{ 941 Name: "my-ultra-ssd-vm", 942 Role: infrav1.Node, 943 NICIDs: []string{"my-nic"}, 944 SSHKeyData: "fakesshpublickey", 945 Size: "Standard_D2v3", 946 Location: "test-location", 947 Zone: "1", 948 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 949 DataDisks: []infrav1.DataDisk{ 950 { 951 NameSuffix: "mydisk", 952 DiskSizeGB: 64, 953 Lun: ptr.To[int32](0), 954 }, 955 { 956 NameSuffix: "myDiskWithUltraDisk", 957 DiskSizeGB: 128, 958 Lun: ptr.To[int32](1), 959 ManagedDisk: &infrav1.ManagedDiskParameters{ 960 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 961 }, 962 }, 963 { 964 NameSuffix: "myDiskWithManagedDisk", 965 DiskSizeGB: 128, 966 Lun: ptr.To[int32](2), 967 ManagedDisk: &infrav1.ManagedDiskParameters{ 968 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 969 }, 970 }, 971 { 972 NameSuffix: "managedDiskWithEncryption", 973 DiskSizeGB: 128, 974 Lun: ptr.To[int32](3), 975 ManagedDisk: &infrav1.ManagedDiskParameters{ 976 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 977 DiskEncryptionSet: &infrav1.DiskEncryptionSetParameters{ 978 ID: "my_id", 979 }, 980 }, 981 }, 982 }, 983 SKU: validSKUWithUltraSSD, 984 }, 985 existing: nil, 986 expect: func(g *WithT, result interface{}) { 987 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 988 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 989 expectedDataDisks := []*armcompute.DataDisk{ 990 { 991 Lun: ptr.To[int32](0), 992 Name: ptr.To("my-ultra-ssd-vm_mydisk"), 993 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 994 DiskSizeGB: ptr.To[int32](64), 995 }, 996 { 997 Lun: ptr.To[int32](1), 998 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 999 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1000 DiskSizeGB: ptr.To[int32](128), 1001 ManagedDisk: &armcompute.ManagedDiskParameters{ 1002 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1003 }, 1004 }, 1005 { 1006 Lun: ptr.To[int32](2), 1007 Name: ptr.To("my-ultra-ssd-vm_myDiskWithManagedDisk"), 1008 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1009 DiskSizeGB: ptr.To[int32](128), 1010 ManagedDisk: &armcompute.ManagedDiskParameters{ 1011 StorageAccountType: ptr.To(armcompute.StorageAccountTypesPremiumLRS), 1012 }, 1013 }, 1014 { 1015 Lun: ptr.To[int32](3), 1016 Name: ptr.To("my-ultra-ssd-vm_managedDiskWithEncryption"), 1017 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1018 DiskSizeGB: ptr.To[int32](128), 1019 ManagedDisk: &armcompute.ManagedDiskParameters{ 1020 StorageAccountType: ptr.To(armcompute.StorageAccountTypesPremiumLRS), 1021 DiskEncryptionSet: &armcompute.DiskEncryptionSetParameters{ 1022 ID: ptr.To("my_id"), 1023 }, 1024 }, 1025 }, 1026 } 1027 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1028 }, 1029 expectedError: "", 1030 }, 1031 { 1032 name: "creating vm with ultra disk enabled in unsupported location fails", 1033 spec: &VMSpec{ 1034 Name: "my-vm", 1035 Role: infrav1.Node, 1036 NICIDs: []string{"my-nic"}, 1037 SSHKeyData: "fakesshpublickey", 1038 Size: "Standard_D2v3", 1039 Location: "test-location", 1040 Zone: "1", 1041 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1042 DataDisks: []infrav1.DataDisk{ 1043 { 1044 NameSuffix: "myDiskWithUltraDisk", 1045 DiskSizeGB: 128, 1046 Lun: ptr.To[int32](1), 1047 ManagedDisk: &infrav1.ManagedDiskParameters{ 1048 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1049 }, 1050 }, 1051 }, 1052 SKU: validSKU, 1053 }, 1054 existing: nil, 1055 expect: func(g *WithT, result interface{}) { 1056 g.Expect(result).To(BeNil()) 1057 }, 1058 expectedError: "reconcile error that cannot be recovered occurred: VM size Standard_D2v3 does not support ultra disks in location test-location. Select a different VM size or disable ultra disks. Object will not be requeued", 1059 }, 1060 { 1061 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled false, if an ultra disk is specified as data disk but AdditionalCapabilities.UltraSSDEnabled is false", 1062 spec: &VMSpec{ 1063 Name: "my-ultra-ssd-vm", 1064 Role: infrav1.Node, 1065 NICIDs: []string{"my-nic"}, 1066 SSHKeyData: "fakesshpublickey", 1067 Size: "Standard_D2v3", 1068 Location: "test-location", 1069 Zone: "1", 1070 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1071 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1072 UltraSSDEnabled: ptr.To(false), 1073 }, 1074 DataDisks: []infrav1.DataDisk{ 1075 { 1076 NameSuffix: "myDiskWithUltraDisk", 1077 DiskSizeGB: 128, 1078 Lun: ptr.To[int32](1), 1079 ManagedDisk: &infrav1.ManagedDiskParameters{ 1080 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1081 }, 1082 }, 1083 }, 1084 SKU: validSKUWithUltraSSD, 1085 }, 1086 existing: nil, 1087 expect: func(g *WithT, result interface{}) { 1088 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1089 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(false))) 1090 expectedDataDisks := []*armcompute.DataDisk{ 1091 { 1092 Lun: ptr.To[int32](1), 1093 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1094 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1095 DiskSizeGB: ptr.To[int32](128), 1096 ManagedDisk: &armcompute.ManagedDiskParameters{ 1097 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1098 }, 1099 }, 1100 } 1101 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1102 }, 1103 expectedError: "", 1104 }, 1105 { 1106 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled true, if an ultra disk is specified as data disk and no AdditionalCapabilities.UltraSSDEnabled is set", 1107 spec: &VMSpec{ 1108 Name: "my-ultra-ssd-vm", 1109 Role: infrav1.Node, 1110 NICIDs: []string{"my-nic"}, 1111 SSHKeyData: "fakesshpublickey", 1112 Size: "Standard_D2v3", 1113 Location: "test-location", 1114 Zone: "1", 1115 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1116 DataDisks: []infrav1.DataDisk{ 1117 { 1118 NameSuffix: "myDiskWithUltraDisk", 1119 DiskSizeGB: 128, 1120 Lun: ptr.To[int32](1), 1121 ManagedDisk: &infrav1.ManagedDiskParameters{ 1122 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1123 }, 1124 }, 1125 }, 1126 SKU: validSKUWithUltraSSD, 1127 }, 1128 existing: nil, 1129 expect: func(g *WithT, result interface{}) { 1130 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1131 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1132 expectedDataDisks := []*armcompute.DataDisk{ 1133 { 1134 Lun: ptr.To[int32](1), 1135 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1136 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1137 DiskSizeGB: ptr.To[int32](128), 1138 ManagedDisk: &armcompute.ManagedDiskParameters{ 1139 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1140 }, 1141 }, 1142 } 1143 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1144 }, 1145 expectedError: "", 1146 }, 1147 { 1148 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled true, if an ultra disk is specified as data disk and AdditionalCapabilities.UltraSSDEnabled is true", 1149 spec: &VMSpec{ 1150 Name: "my-ultra-ssd-vm", 1151 Role: infrav1.Node, 1152 NICIDs: []string{"my-nic"}, 1153 SSHKeyData: "fakesshpublickey", 1154 Size: "Standard_D2v3", 1155 Location: "test-location", 1156 Zone: "1", 1157 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1158 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1159 UltraSSDEnabled: ptr.To(true), 1160 }, 1161 DataDisks: []infrav1.DataDisk{ 1162 { 1163 NameSuffix: "myDiskWithUltraDisk", 1164 DiskSizeGB: 128, 1165 Lun: ptr.To[int32](1), 1166 ManagedDisk: &infrav1.ManagedDiskParameters{ 1167 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1168 }, 1169 }, 1170 }, 1171 SKU: validSKUWithUltraSSD, 1172 }, 1173 existing: nil, 1174 expect: func(g *WithT, result interface{}) { 1175 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1176 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1177 expectedDataDisks := []*armcompute.DataDisk{ 1178 { 1179 Lun: ptr.To[int32](1), 1180 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1181 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1182 DiskSizeGB: ptr.To[int32](128), 1183 ManagedDisk: &armcompute.ManagedDiskParameters{ 1184 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1185 }, 1186 }, 1187 } 1188 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1189 }, 1190 expectedError: "", 1191 }, 1192 { 1193 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled true, if no ultra disk is specified as data disk and AdditionalCapabilities.UltraSSDEnabled is true", 1194 spec: &VMSpec{ 1195 Name: "my-ultra-ssd-vm", 1196 Role: infrav1.Node, 1197 NICIDs: []string{"my-nic"}, 1198 SSHKeyData: "fakesshpublickey", 1199 Size: "Standard_D2v3", 1200 Location: "test-location", 1201 Zone: "1", 1202 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1203 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1204 UltraSSDEnabled: ptr.To(true), 1205 }, 1206 SKU: validSKUWithUltraSSD, 1207 }, 1208 existing: nil, 1209 expect: func(g *WithT, result interface{}) { 1210 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1211 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1212 }, 1213 expectedError: "", 1214 }, 1215 { 1216 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled false, if no ultra disk is specified as data disk and AdditionalCapabilities.UltraSSDEnabled is false", 1217 spec: &VMSpec{ 1218 Name: "my-ultra-ssd-vm", 1219 Role: infrav1.Node, 1220 NICIDs: []string{"my-nic"}, 1221 SSHKeyData: "fakesshpublickey", 1222 Size: "Standard_D2v3", 1223 Location: "test-location", 1224 Zone: "1", 1225 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1226 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1227 UltraSSDEnabled: ptr.To(false), 1228 }, 1229 SKU: validSKUWithUltraSSD, 1230 }, 1231 existing: nil, 1232 expect: func(g *WithT, result interface{}) { 1233 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1234 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(false))) 1235 }, 1236 expectedError: "", 1237 }, 1238 { 1239 name: "creates a vm with Diagnostics disabled", 1240 spec: &VMSpec{ 1241 Name: "my-ultra-ssd-vm", 1242 Role: infrav1.Node, 1243 NICIDs: []string{"my-nic"}, 1244 SSHKeyData: "fakesshpublickey", 1245 Size: "Standard_D2v3", 1246 Location: "test-location", 1247 Zone: "1", 1248 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1249 DiagnosticsProfile: &infrav1.Diagnostics{ 1250 Boot: &infrav1.BootDiagnostics{ 1251 StorageAccountType: infrav1.DisabledDiagnosticsStorage, 1252 }, 1253 }, 1254 SKU: validSKUWithUltraSSD, 1255 }, 1256 existing: nil, 1257 expect: func(g *WithT, result interface{}) { 1258 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1259 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.Enabled).To(Equal(ptr.To(false))) 1260 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.StorageURI).To(BeNil()) 1261 }, 1262 expectedError: "", 1263 }, 1264 { 1265 name: "creates a vm with Managed Diagnostics enabled", 1266 spec: &VMSpec{ 1267 Name: "my-ultra-ssd-vm", 1268 Role: infrav1.Node, 1269 NICIDs: []string{"my-nic"}, 1270 SSHKeyData: "fakesshpublickey", 1271 Size: "Standard_D2v3", 1272 Location: "test-location", 1273 Zone: "1", 1274 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1275 DiagnosticsProfile: &infrav1.Diagnostics{ 1276 Boot: &infrav1.BootDiagnostics{ 1277 StorageAccountType: infrav1.ManagedDiagnosticsStorage, 1278 }, 1279 }, 1280 SKU: validSKUWithUltraSSD, 1281 }, 1282 existing: nil, 1283 expect: func(g *WithT, result interface{}) { 1284 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1285 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.Enabled).To(Equal(ptr.To(true))) 1286 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.StorageURI).To(BeNil()) 1287 }, 1288 expectedError: "", 1289 }, 1290 { 1291 name: "creates a vm with User Managed Diagnostics enabled", 1292 spec: &VMSpec{ 1293 Name: "my-ultra-ssd-vm", 1294 Role: infrav1.Node, 1295 NICIDs: []string{"my-nic"}, 1296 SSHKeyData: "fakesshpublickey", 1297 Size: "Standard_D2v3", 1298 Location: "test-location", 1299 Zone: "1", 1300 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1301 DiagnosticsProfile: &infrav1.Diagnostics{ 1302 Boot: &infrav1.BootDiagnostics{ 1303 StorageAccountType: infrav1.UserManagedDiagnosticsStorage, 1304 UserManaged: &infrav1.UserManagedBootDiagnostics{ 1305 StorageAccountURI: "aaa", 1306 }, 1307 }, 1308 }, 1309 SKU: validSKUWithUltraSSD, 1310 }, 1311 existing: nil, 1312 expect: func(g *WithT, result interface{}) { 1313 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1314 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.Enabled).To(Equal(ptr.To(true))) 1315 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.StorageURI).To(Equal(ptr.To("aaa"))) 1316 }, 1317 expectedError: "", 1318 }, 1319 { 1320 name: "creates a vm with User Managed Diagnostics enabled, but missing StorageAccountURI", 1321 spec: &VMSpec{ 1322 Name: "my-ultra-ssd-vm", 1323 Role: infrav1.Node, 1324 NICIDs: []string{"my-nic"}, 1325 SSHKeyData: "fakesshpublickey", 1326 Size: "Standard_D2v3", 1327 Location: "test-location", 1328 Zone: "1", 1329 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1330 DiagnosticsProfile: &infrav1.Diagnostics{ 1331 Boot: &infrav1.BootDiagnostics{ 1332 StorageAccountType: infrav1.UserManagedDiagnosticsStorage, 1333 UserManaged: &infrav1.UserManagedBootDiagnostics{ 1334 StorageAccountURI: "aaa", 1335 }, 1336 }, 1337 }, 1338 SKU: validSKUWithUltraSSD, 1339 }, 1340 existing: nil, 1341 expect: func(g *WithT, result interface{}) { 1342 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1343 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.Enabled).To(Equal(ptr.To(true))) 1344 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.StorageURI).To(Equal(ptr.To("aaa"))) 1345 }, 1346 expectedError: "", 1347 }, 1348 } 1349 for _, tc := range testcases { 1350 tc := tc 1351 t.Run(tc.name, func(t *testing.T) { 1352 g := NewWithT(t) 1353 t.Parallel() 1354 1355 result, err := tc.spec.Parameters(context.TODO(), tc.existing) 1356 if tc.expectedError != "" { 1357 g.Expect(err).To(HaveOccurred()) 1358 g.Expect(err).To(MatchError(tc.expectedError)) 1359 } else { 1360 g.Expect(err).NotTo(HaveOccurred()) 1361 } 1362 tc.expect(g, result) 1363 }) 1364 } 1365 }