sigs.k8s.io/cluster-api-provider-azure@v1.17.0/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 vm with DiffDiskPlacement ResourceDisk", 466 spec: &VMSpec{ 467 Name: "my-vm", 468 Role: infrav1.Node, 469 NICIDs: []string{"my-nic"}, 470 SSHKeyData: "fakesshpublickey", 471 Size: "Standard_D2v3", 472 OSDisk: infrav1.OSDisk{ 473 OSType: "Linux", 474 DiskSizeGB: ptr.To[int32](128), 475 ManagedDisk: &infrav1.ManagedDiskParameters{ 476 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 477 }, 478 DiffDiskSettings: &infrav1.DiffDiskSettings{ 479 Option: string(armcompute.DiffDiskOptionsLocal), 480 Placement: ptr.To(infrav1.DiffDiskPlacementResourceDisk), 481 }, 482 }, 483 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 484 SKU: validSKUWithEphemeralOS, 485 }, 486 existing: nil, 487 expect: func(g *WithT, result interface{}) { 488 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 489 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.OSDisk.DiffDiskSettings.Placement).To(Equal(ptr.To(armcompute.DiffDiskPlacementResourceDisk))) 490 }, 491 expectedError: "", 492 }, 493 { 494 name: "can create a trusted launch vm", 495 spec: &VMSpec{ 496 Name: "my-vm", 497 Role: infrav1.Node, 498 NICIDs: []string{"my-nic"}, 499 SSHKeyData: "fakesshpublickey", 500 Size: "Standard_D2v3", 501 AvailabilitySetID: "fake-availability-set-id", 502 Zone: "", 503 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 504 SecurityProfile: &infrav1.SecurityProfile{ 505 SecurityType: infrav1.SecurityTypesTrustedLaunch, 506 UefiSettings: &infrav1.UefiSettings{ 507 SecureBootEnabled: ptr.To(true), 508 VTpmEnabled: ptr.To(true), 509 }, 510 }, 511 SKU: validSKU, 512 }, 513 existing: nil, 514 expect: func(g *WithT, result interface{}) { 515 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 516 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.UefiSettings.SecureBootEnabled).To(BeTrue()) 517 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.UefiSettings.VTpmEnabled).To(BeTrue()) 518 }, 519 expectedError: "", 520 }, 521 { 522 name: "can create a confidential vm", 523 spec: &VMSpec{ 524 Name: "my-vm", 525 Role: infrav1.Node, 526 NICIDs: []string{"my-nic"}, 527 SSHKeyData: "fakesshpublickey", 528 Size: "Standard_D2v3", 529 AvailabilitySetID: "fake-availability-set-id", 530 Zone: "", 531 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 532 OSDisk: infrav1.OSDisk{ 533 OSType: "Linux", 534 DiskSizeGB: ptr.To[int32](128), 535 ManagedDisk: &infrav1.ManagedDiskParameters{ 536 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 537 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 538 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 539 }, 540 }, 541 }, 542 SecurityProfile: &infrav1.SecurityProfile{ 543 SecurityType: infrav1.SecurityTypesConfidentialVM, 544 UefiSettings: &infrav1.UefiSettings{ 545 SecureBootEnabled: ptr.To(false), 546 VTpmEnabled: ptr.To(true), 547 }, 548 }, 549 SKU: validSKUWithConfidentialComputingType, 550 }, 551 existing: nil, 552 expect: func(g *WithT, result interface{}) { 553 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 554 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.OSDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType).To(Equal(ptr.To(armcompute.SecurityEncryptionTypesVMGuestStateOnly))) 555 g.Expect(*result.(armcompute.VirtualMachine).Properties.SecurityProfile.UefiSettings.VTpmEnabled).To(BeTrue()) 556 }, 557 expectedError: "", 558 }, 559 { 560 name: "creating a confidential vm without the SecurityType set to ConfidentialVM fails", 561 spec: &VMSpec{ 562 Name: "my-vm", 563 Role: infrav1.Node, 564 NICIDs: []string{"my-nic"}, 565 SSHKeyData: "fakesshpublickey", 566 Size: "Standard_D2v3", 567 AvailabilitySetID: "fake-availability-set-id", 568 Zone: "", 569 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 570 OSDisk: infrav1.OSDisk{ 571 OSType: "Linux", 572 DiskSizeGB: ptr.To[int32](128), 573 ManagedDisk: &infrav1.ManagedDiskParameters{ 574 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 575 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 576 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 577 }, 578 }, 579 }, 580 SecurityProfile: &infrav1.SecurityProfile{ 581 SecurityType: "", 582 UefiSettings: &infrav1.UefiSettings{ 583 SecureBootEnabled: ptr.To(false), 584 VTpmEnabled: ptr.To(true), 585 }, 586 }, 587 SKU: validSKUWithConfidentialComputingType, 588 }, 589 existing: nil, 590 expect: func(g *WithT, result interface{}) { 591 g.Expect(result).To(BeNil()) 592 }, 593 expectedError: "reconcile error that cannot be recovered occurred: securityType should be set to ConfidentialVM when securityEncryptionType is set. Object will not be requeued", 594 }, 595 { 596 name: "creating a vm with encryption at host enabled for unsupported VM type fails", 597 spec: &VMSpec{ 598 Name: "my-vm", 599 Role: infrav1.Node, 600 NICIDs: []string{"my-nic"}, 601 SSHKeyData: "fakesshpublickey", 602 Size: "Standard_D2v3", 603 AvailabilitySetID: "fake-availability-set-id", 604 Zone: "", 605 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 606 SecurityProfile: &infrav1.SecurityProfile{EncryptionAtHost: ptr.To(true)}, 607 SKU: validSKU, 608 }, 609 existing: nil, 610 expect: func(g *WithT, result interface{}) { 611 g.Expect(result).To(BeNil()) 612 }, 613 expectedError: "reconcile error that cannot be recovered occurred: encryption at host is not supported for VM type Standard_D2v3. Object will not be requeued", 614 }, 615 { 616 name: "creating a trusted launch vm without the SecurityType set to TrustedLaunch fails", 617 spec: &VMSpec{ 618 Name: "my-vm", 619 Role: infrav1.Node, 620 NICIDs: []string{"my-nic"}, 621 SSHKeyData: "fakesshpublickey", 622 Size: "Standard_D2v3", 623 AvailabilitySetID: "fake-availability-set-id", 624 Zone: "", 625 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 626 OSDisk: infrav1.OSDisk{ 627 OSType: "Linux", 628 DiskSizeGB: ptr.To[int32](128), 629 ManagedDisk: &infrav1.ManagedDiskParameters{ 630 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 631 }, 632 }, 633 SecurityProfile: &infrav1.SecurityProfile{ 634 SecurityType: "", 635 UefiSettings: &infrav1.UefiSettings{ 636 SecureBootEnabled: ptr.To(false), 637 VTpmEnabled: ptr.To(true), 638 }, 639 }, 640 SKU: validSKUWithConfidentialComputingType, 641 }, 642 existing: nil, 643 expect: func(g *WithT, result interface{}) { 644 g.Expect(result).To(BeNil()) 645 }, 646 expectedError: "reconcile error that cannot be recovered occurred: securityType should be set to TrustedLaunch when vTpmEnabled is true. Object will not be requeued", 647 }, 648 { 649 name: "creating a trusted launch vm with secure boot enabled on unsupported VM type fails", 650 spec: &VMSpec{ 651 Name: "my-vm", 652 Role: infrav1.Node, 653 NICIDs: []string{"my-nic"}, 654 SSHKeyData: "fakesshpublickey", 655 Size: "Standard_D2v3", 656 AvailabilitySetID: "fake-availability-set-id", 657 Zone: "", 658 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 659 SecurityProfile: &infrav1.SecurityProfile{ 660 SecurityType: infrav1.SecurityTypesTrustedLaunch, 661 UefiSettings: &infrav1.UefiSettings{ 662 SecureBootEnabled: ptr.To(true), 663 }, 664 }, 665 SKU: validSKUWithTrustedLaunchDisabled, 666 }, 667 existing: nil, 668 expect: func(g *WithT, result interface{}) { 669 g.Expect(result).To(BeNil()) 670 }, 671 expectedError: "reconcile error that cannot be recovered occurred: secure boot is not supported for VM type Standard_D2v3. Object will not be requeued", 672 }, 673 { 674 name: "creating a trusted launch vm with vTPM enabled on unsupported VM type fails", 675 spec: &VMSpec{ 676 Name: "my-vm", 677 Role: infrav1.Node, 678 NICIDs: []string{"my-nic"}, 679 SSHKeyData: "fakesshpublickey", 680 Size: "Standard_D2v3", 681 AvailabilitySetID: "fake-availability-set-id", 682 Zone: "", 683 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 684 SecurityProfile: &infrav1.SecurityProfile{ 685 SecurityType: infrav1.SecurityTypesTrustedLaunch, 686 UefiSettings: &infrav1.UefiSettings{ 687 VTpmEnabled: ptr.To(true), 688 }, 689 }, 690 SKU: validSKUWithTrustedLaunchDisabled, 691 }, 692 existing: nil, 693 expect: func(g *WithT, result interface{}) { 694 g.Expect(result).To(BeNil()) 695 }, 696 expectedError: "reconcile error that cannot be recovered occurred: vTPM is not supported for VM type Standard_D2v3. Object will not be requeued", 697 }, 698 { 699 name: "creating a confidential vm with securityTypeEncryption DiskWithVMGuestState and encryption at host enabled fails", 700 spec: &VMSpec{ 701 Name: "my-vm", 702 Role: infrav1.Node, 703 NICIDs: []string{"my-nic"}, 704 SSHKeyData: "fakesshpublickey", 705 Size: "Standard_D2v3", 706 AvailabilitySetID: "fake-availability-set-id", 707 Zone: "", 708 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 709 OSDisk: infrav1.OSDisk{ 710 OSType: "Linux", 711 DiskSizeGB: ptr.To[int32](128), 712 ManagedDisk: &infrav1.ManagedDiskParameters{ 713 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 714 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 715 SecurityEncryptionType: infrav1.SecurityEncryptionTypeDiskWithVMGuestState, 716 }, 717 }, 718 }, 719 SecurityProfile: &infrav1.SecurityProfile{ 720 EncryptionAtHost: ptr.To(true), 721 SecurityType: infrav1.SecurityTypesConfidentialVM, 722 UefiSettings: &infrav1.UefiSettings{ 723 VTpmEnabled: ptr.To(true), 724 }, 725 }, 726 SKU: validSKUWithConfidentialComputingType, 727 }, 728 existing: nil, 729 expect: func(g *WithT, result interface{}) { 730 g.Expect(result).To(BeNil()) 731 }, 732 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", 733 }, 734 { 735 name: "creating a confidential vm with DiskWithVMGuestState encryption type and secure boot disabled fails", 736 spec: &VMSpec{ 737 Name: "my-vm", 738 Role: infrav1.Node, 739 NICIDs: []string{"my-nic"}, 740 SSHKeyData: "fakesshpublickey", 741 Size: "Standard_D2v3", 742 AvailabilitySetID: "fake-availability-set-id", 743 Zone: "", 744 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 745 OSDisk: infrav1.OSDisk{ 746 OSType: "Linux", 747 DiskSizeGB: ptr.To[int32](128), 748 ManagedDisk: &infrav1.ManagedDiskParameters{ 749 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 750 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 751 SecurityEncryptionType: infrav1.SecurityEncryptionTypeDiskWithVMGuestState, 752 }, 753 }, 754 }, 755 SecurityProfile: &infrav1.SecurityProfile{ 756 SecurityType: infrav1.SecurityTypesConfidentialVM, 757 UefiSettings: &infrav1.UefiSettings{ 758 SecureBootEnabled: ptr.To(false), 759 VTpmEnabled: ptr.To(true), 760 }, 761 }, 762 SKU: validSKUWithConfidentialComputingType, 763 }, 764 existing: nil, 765 expect: func(g *WithT, result interface{}) { 766 g.Expect(result).To(BeNil()) 767 }, 768 expectedError: "reconcile error that cannot be recovered occurred: secureBootEnabled should be true when securityEncryptionType is set to DiskWithVMGuestState. Object will not be requeued", 769 }, 770 { 771 name: "creating a confidential vm with vTPM disabled fails", 772 spec: &VMSpec{ 773 Name: "my-vm", 774 Role: infrav1.Node, 775 NICIDs: []string{"my-nic"}, 776 SSHKeyData: "fakesshpublickey", 777 Size: "Standard_D2v3", 778 AvailabilitySetID: "fake-availability-set-id", 779 Zone: "", 780 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 781 OSDisk: infrav1.OSDisk{ 782 OSType: "Linux", 783 DiskSizeGB: ptr.To[int32](128), 784 ManagedDisk: &infrav1.ManagedDiskParameters{ 785 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 786 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 787 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 788 }, 789 }, 790 }, 791 SecurityProfile: &infrav1.SecurityProfile{ 792 SecurityType: infrav1.SecurityTypesConfidentialVM, 793 UefiSettings: &infrav1.UefiSettings{ 794 VTpmEnabled: ptr.To(false), 795 }, 796 }, 797 SKU: validSKUWithConfidentialComputingType, 798 }, 799 existing: nil, 800 expect: func(g *WithT, result interface{}) { 801 g.Expect(result).To(BeNil()) 802 }, 803 expectedError: "reconcile error that cannot be recovered occurred: vTpmEnabled should be true when securityEncryptionType is set. Object will not be requeued", 804 }, 805 { 806 name: "creating a confidential vm with unsupported VM type fails", 807 spec: &VMSpec{ 808 Name: "my-vm", 809 Role: infrav1.Node, 810 NICIDs: []string{"my-nic"}, 811 SSHKeyData: "fakesshpublickey", 812 Size: "Standard_D2v3", 813 AvailabilitySetID: "fake-availability-set-id", 814 Zone: "", 815 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 816 OSDisk: infrav1.OSDisk{ 817 OSType: "Linux", 818 DiskSizeGB: ptr.To[int32](128), 819 ManagedDisk: &infrav1.ManagedDiskParameters{ 820 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 821 SecurityProfile: &infrav1.VMDiskSecurityProfile{ 822 SecurityEncryptionType: infrav1.SecurityEncryptionTypeVMGuestStateOnly, 823 }, 824 }, 825 }, 826 SecurityProfile: &infrav1.SecurityProfile{ 827 SecurityType: infrav1.SecurityTypesConfidentialVM, 828 UefiSettings: &infrav1.UefiSettings{ 829 VTpmEnabled: ptr.To(true), 830 }, 831 }, 832 SKU: validSKU, 833 }, 834 existing: nil, 835 expect: func(g *WithT, result interface{}) { 836 g.Expect(result).To(BeNil()) 837 }, 838 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", 839 }, 840 { 841 name: "cannot create vm with EphemeralOSDisk if does not support ephemeral os", 842 spec: &VMSpec{ 843 Name: "my-vm", 844 Role: infrav1.Node, 845 NICIDs: []string{"my-nic"}, 846 SSHKeyData: "fakesshpublickey", 847 Size: "Standard_D2v3", 848 OSDisk: infrav1.OSDisk{ 849 OSType: "Linux", 850 DiskSizeGB: ptr.To[int32](128), 851 ManagedDisk: &infrav1.ManagedDiskParameters{ 852 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 853 }, 854 DiffDiskSettings: &infrav1.DiffDiskSettings{ 855 Option: string(armcompute.DiffDiskOptionsLocal), 856 }, 857 }, 858 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 859 SKU: validSKU, 860 }, 861 existing: nil, 862 expect: func(g *WithT, result interface{}) { 863 g.Expect(result).To(BeNil()) 864 }, 865 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", 866 }, 867 { 868 name: "cannot create vm if vCPU is less than 2", 869 spec: &VMSpec{ 870 Name: "my-vm", 871 Role: infrav1.Node, 872 NICIDs: []string{"my-nic"}, 873 SSHKeyData: "fakesshpublickey", 874 Size: "Standard_D2v3", 875 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 876 SKU: invalidCPUSKU, 877 }, 878 existing: nil, 879 expect: func(g *WithT, result interface{}) { 880 g.Expect(result).To(BeNil()) 881 }, 882 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", 883 }, 884 { 885 name: "cannot create vm if memory is less than 2Gi", 886 spec: &VMSpec{ 887 Name: "my-vm", 888 Role: infrav1.Node, 889 NICIDs: []string{"my-nic"}, 890 SSHKeyData: "fakesshpublickey", 891 Size: "Standard_D2v3", 892 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 893 SKU: invalidMemSKU, 894 }, 895 existing: nil, 896 expect: func(g *WithT, result interface{}) { 897 g.Expect(result).To(BeNil()) 898 }, 899 expectedError: "reconcile error that cannot be recovered occurred: VM memory should be bigger or equal to at least 2Gi. Object will not be requeued", 900 }, 901 { 902 name: "can create a vm with a marketplace image using a plan", 903 spec: &VMSpec{ 904 Name: "my-vm", 905 Role: infrav1.Node, 906 NICIDs: []string{"my-nic"}, 907 SSHKeyData: "fakesshpublickey", 908 Size: "Standard_D2v3", 909 Image: &infrav1.Image{ 910 Marketplace: &infrav1.AzureMarketplaceImage{ 911 ImagePlan: infrav1.ImagePlan{ 912 Publisher: "fake-publisher", 913 Offer: "my-offer", 914 SKU: "sku-id", 915 }, 916 Version: "1.0", 917 ThirdPartyImage: true, 918 }, 919 }, 920 SKU: validSKU, 921 }, 922 existing: nil, 923 expect: func(g *WithT, result interface{}) { 924 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 925 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.Offer).To(Equal(ptr.To("my-offer"))) 926 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.Publisher).To(Equal(ptr.To("fake-publisher"))) 927 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.SKU).To(Equal(ptr.To("sku-id"))) 928 g.Expect(result.(armcompute.VirtualMachine).Properties.StorageProfile.ImageReference.Version).To(Equal(ptr.To("1.0"))) 929 g.Expect(result.(armcompute.VirtualMachine).Plan.Name).To(Equal(ptr.To("sku-id"))) 930 g.Expect(result.(armcompute.VirtualMachine).Plan.Publisher).To(Equal(ptr.To("fake-publisher"))) 931 g.Expect(result.(armcompute.VirtualMachine).Plan.Product).To(Equal(ptr.To("my-offer"))) 932 }, 933 expectedError: "", 934 }, 935 { 936 name: "can create a vm with a SIG image using a plan", 937 spec: &VMSpec{ 938 Name: "my-vm", 939 Role: infrav1.Node, 940 NICIDs: []string{"my-nic"}, 941 SSHKeyData: "fakesshpublickey", 942 Size: "Standard_D2v3", 943 Image: &infrav1.Image{ 944 SharedGallery: &infrav1.AzureSharedGalleryImage{ 945 SubscriptionID: "fake-sub-id", 946 ResourceGroup: "fake-rg", 947 Gallery: "fake-gallery", 948 Name: "fake-name", 949 Version: "1.0", 950 Publisher: ptr.To("fake-publisher"), 951 Offer: ptr.To("my-offer"), 952 SKU: ptr.To("sku-id"), 953 }, 954 }, 955 SKU: validSKU, 956 }, 957 existing: nil, 958 expect: func(g *WithT, result interface{}) { 959 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 960 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"))) 961 g.Expect(result.(armcompute.VirtualMachine).Plan.Name).To(Equal(ptr.To("sku-id"))) 962 g.Expect(result.(armcompute.VirtualMachine).Plan.Publisher).To(Equal(ptr.To("fake-publisher"))) 963 g.Expect(result.(armcompute.VirtualMachine).Plan.Product).To(Equal(ptr.To("my-offer"))) 964 }, 965 expectedError: "", 966 }, 967 { 968 name: "can create a vm with ultra disk enabled", 969 spec: &VMSpec{ 970 Name: "my-ultra-ssd-vm", 971 Role: infrav1.Node, 972 NICIDs: []string{"my-nic"}, 973 SSHKeyData: "fakesshpublickey", 974 Size: "Standard_D2v3", 975 Location: "test-location", 976 Zone: "1", 977 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 978 DataDisks: []infrav1.DataDisk{ 979 { 980 NameSuffix: "mydisk", 981 DiskSizeGB: 64, 982 Lun: ptr.To[int32](0), 983 }, 984 { 985 NameSuffix: "myDiskWithUltraDisk", 986 DiskSizeGB: 128, 987 Lun: ptr.To[int32](1), 988 ManagedDisk: &infrav1.ManagedDiskParameters{ 989 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 990 }, 991 }, 992 { 993 NameSuffix: "myDiskWithManagedDisk", 994 DiskSizeGB: 128, 995 Lun: ptr.To[int32](2), 996 ManagedDisk: &infrav1.ManagedDiskParameters{ 997 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 998 }, 999 }, 1000 { 1001 NameSuffix: "managedDiskWithEncryption", 1002 DiskSizeGB: 128, 1003 Lun: ptr.To[int32](3), 1004 ManagedDisk: &infrav1.ManagedDiskParameters{ 1005 StorageAccountType: string(armcompute.StorageAccountTypesPremiumLRS), 1006 DiskEncryptionSet: &infrav1.DiskEncryptionSetParameters{ 1007 ID: "my_id", 1008 }, 1009 }, 1010 }, 1011 }, 1012 SKU: validSKUWithUltraSSD, 1013 }, 1014 existing: nil, 1015 expect: func(g *WithT, result interface{}) { 1016 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1017 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1018 expectedDataDisks := []*armcompute.DataDisk{ 1019 { 1020 Lun: ptr.To[int32](0), 1021 Name: ptr.To("my-ultra-ssd-vm_mydisk"), 1022 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1023 DiskSizeGB: ptr.To[int32](64), 1024 }, 1025 { 1026 Lun: ptr.To[int32](1), 1027 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1028 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1029 DiskSizeGB: ptr.To[int32](128), 1030 ManagedDisk: &armcompute.ManagedDiskParameters{ 1031 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1032 }, 1033 }, 1034 { 1035 Lun: ptr.To[int32](2), 1036 Name: ptr.To("my-ultra-ssd-vm_myDiskWithManagedDisk"), 1037 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1038 DiskSizeGB: ptr.To[int32](128), 1039 ManagedDisk: &armcompute.ManagedDiskParameters{ 1040 StorageAccountType: ptr.To(armcompute.StorageAccountTypesPremiumLRS), 1041 }, 1042 }, 1043 { 1044 Lun: ptr.To[int32](3), 1045 Name: ptr.To("my-ultra-ssd-vm_managedDiskWithEncryption"), 1046 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1047 DiskSizeGB: ptr.To[int32](128), 1048 ManagedDisk: &armcompute.ManagedDiskParameters{ 1049 StorageAccountType: ptr.To(armcompute.StorageAccountTypesPremiumLRS), 1050 DiskEncryptionSet: &armcompute.DiskEncryptionSetParameters{ 1051 ID: ptr.To("my_id"), 1052 }, 1053 }, 1054 }, 1055 } 1056 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1057 }, 1058 expectedError: "", 1059 }, 1060 { 1061 name: "creating vm with ultra disk enabled in unsupported location fails", 1062 spec: &VMSpec{ 1063 Name: "my-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 DataDisks: []infrav1.DataDisk{ 1072 { 1073 NameSuffix: "myDiskWithUltraDisk", 1074 DiskSizeGB: 128, 1075 Lun: ptr.To[int32](1), 1076 ManagedDisk: &infrav1.ManagedDiskParameters{ 1077 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1078 }, 1079 }, 1080 }, 1081 SKU: validSKU, 1082 }, 1083 existing: nil, 1084 expect: func(g *WithT, result interface{}) { 1085 g.Expect(result).To(BeNil()) 1086 }, 1087 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", 1088 }, 1089 { 1090 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled false, if an ultra disk is specified as data disk but AdditionalCapabilities.UltraSSDEnabled is false", 1091 spec: &VMSpec{ 1092 Name: "my-ultra-ssd-vm", 1093 Role: infrav1.Node, 1094 NICIDs: []string{"my-nic"}, 1095 SSHKeyData: "fakesshpublickey", 1096 Size: "Standard_D2v3", 1097 Location: "test-location", 1098 Zone: "1", 1099 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1100 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1101 UltraSSDEnabled: ptr.To(false), 1102 }, 1103 DataDisks: []infrav1.DataDisk{ 1104 { 1105 NameSuffix: "myDiskWithUltraDisk", 1106 DiskSizeGB: 128, 1107 Lun: ptr.To[int32](1), 1108 ManagedDisk: &infrav1.ManagedDiskParameters{ 1109 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1110 }, 1111 }, 1112 }, 1113 SKU: validSKUWithUltraSSD, 1114 }, 1115 existing: nil, 1116 expect: func(g *WithT, result interface{}) { 1117 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1118 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(false))) 1119 expectedDataDisks := []*armcompute.DataDisk{ 1120 { 1121 Lun: ptr.To[int32](1), 1122 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1123 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1124 DiskSizeGB: ptr.To[int32](128), 1125 ManagedDisk: &armcompute.ManagedDiskParameters{ 1126 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1127 }, 1128 }, 1129 } 1130 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1131 }, 1132 expectedError: "", 1133 }, 1134 { 1135 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled true, if an ultra disk is specified as data disk and no AdditionalCapabilities.UltraSSDEnabled is set", 1136 spec: &VMSpec{ 1137 Name: "my-ultra-ssd-vm", 1138 Role: infrav1.Node, 1139 NICIDs: []string{"my-nic"}, 1140 SSHKeyData: "fakesshpublickey", 1141 Size: "Standard_D2v3", 1142 Location: "test-location", 1143 Zone: "1", 1144 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1145 DataDisks: []infrav1.DataDisk{ 1146 { 1147 NameSuffix: "myDiskWithUltraDisk", 1148 DiskSizeGB: 128, 1149 Lun: ptr.To[int32](1), 1150 ManagedDisk: &infrav1.ManagedDiskParameters{ 1151 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1152 }, 1153 }, 1154 }, 1155 SKU: validSKUWithUltraSSD, 1156 }, 1157 existing: nil, 1158 expect: func(g *WithT, result interface{}) { 1159 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1160 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1161 expectedDataDisks := []*armcompute.DataDisk{ 1162 { 1163 Lun: ptr.To[int32](1), 1164 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1165 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1166 DiskSizeGB: ptr.To[int32](128), 1167 ManagedDisk: &armcompute.ManagedDiskParameters{ 1168 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1169 }, 1170 }, 1171 } 1172 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1173 }, 1174 expectedError: "", 1175 }, 1176 { 1177 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled true, if an ultra disk is specified as data disk and AdditionalCapabilities.UltraSSDEnabled is true", 1178 spec: &VMSpec{ 1179 Name: "my-ultra-ssd-vm", 1180 Role: infrav1.Node, 1181 NICIDs: []string{"my-nic"}, 1182 SSHKeyData: "fakesshpublickey", 1183 Size: "Standard_D2v3", 1184 Location: "test-location", 1185 Zone: "1", 1186 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1187 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1188 UltraSSDEnabled: ptr.To(true), 1189 }, 1190 DataDisks: []infrav1.DataDisk{ 1191 { 1192 NameSuffix: "myDiskWithUltraDisk", 1193 DiskSizeGB: 128, 1194 Lun: ptr.To[int32](1), 1195 ManagedDisk: &infrav1.ManagedDiskParameters{ 1196 StorageAccountType: string(armcompute.StorageAccountTypesUltraSSDLRS), 1197 }, 1198 }, 1199 }, 1200 SKU: validSKUWithUltraSSD, 1201 }, 1202 existing: nil, 1203 expect: func(g *WithT, result interface{}) { 1204 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1205 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1206 expectedDataDisks := []*armcompute.DataDisk{ 1207 { 1208 Lun: ptr.To[int32](1), 1209 Name: ptr.To("my-ultra-ssd-vm_myDiskWithUltraDisk"), 1210 CreateOption: ptr.To(armcompute.DiskCreateOptionTypesEmpty), 1211 DiskSizeGB: ptr.To[int32](128), 1212 ManagedDisk: &armcompute.ManagedDiskParameters{ 1213 StorageAccountType: ptr.To(armcompute.StorageAccountTypesUltraSSDLRS), 1214 }, 1215 }, 1216 } 1217 g.Expect(gomockinternal.DiffEq(expectedDataDisks).Matches(result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)).To(BeTrue(), cmp.Diff(expectedDataDisks, result.(armcompute.VirtualMachine).Properties.StorageProfile.DataDisks)) 1218 }, 1219 expectedError: "", 1220 }, 1221 { 1222 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled true, if no ultra disk is specified as data disk and AdditionalCapabilities.UltraSSDEnabled is true", 1223 spec: &VMSpec{ 1224 Name: "my-ultra-ssd-vm", 1225 Role: infrav1.Node, 1226 NICIDs: []string{"my-nic"}, 1227 SSHKeyData: "fakesshpublickey", 1228 Size: "Standard_D2v3", 1229 Location: "test-location", 1230 Zone: "1", 1231 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1232 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1233 UltraSSDEnabled: ptr.To(true), 1234 }, 1235 SKU: validSKUWithUltraSSD, 1236 }, 1237 existing: nil, 1238 expect: func(g *WithT, result interface{}) { 1239 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1240 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(true))) 1241 }, 1242 expectedError: "", 1243 }, 1244 { 1245 name: "creates a vm with AdditionalCapabilities.UltraSSDEnabled false, if no ultra disk is specified as data disk and AdditionalCapabilities.UltraSSDEnabled is false", 1246 spec: &VMSpec{ 1247 Name: "my-ultra-ssd-vm", 1248 Role: infrav1.Node, 1249 NICIDs: []string{"my-nic"}, 1250 SSHKeyData: "fakesshpublickey", 1251 Size: "Standard_D2v3", 1252 Location: "test-location", 1253 Zone: "1", 1254 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1255 AdditionalCapabilities: &infrav1.AdditionalCapabilities{ 1256 UltraSSDEnabled: ptr.To(false), 1257 }, 1258 SKU: validSKUWithUltraSSD, 1259 }, 1260 existing: nil, 1261 expect: func(g *WithT, result interface{}) { 1262 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1263 g.Expect(result.(armcompute.VirtualMachine).Properties.AdditionalCapabilities.UltraSSDEnabled).To(Equal(ptr.To(false))) 1264 }, 1265 expectedError: "", 1266 }, 1267 { 1268 name: "creates a vm with Diagnostics disabled", 1269 spec: &VMSpec{ 1270 Name: "my-ultra-ssd-vm", 1271 Role: infrav1.Node, 1272 NICIDs: []string{"my-nic"}, 1273 SSHKeyData: "fakesshpublickey", 1274 Size: "Standard_D2v3", 1275 Location: "test-location", 1276 Zone: "1", 1277 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1278 DiagnosticsProfile: &infrav1.Diagnostics{ 1279 Boot: &infrav1.BootDiagnostics{ 1280 StorageAccountType: infrav1.DisabledDiagnosticsStorage, 1281 }, 1282 }, 1283 SKU: validSKUWithUltraSSD, 1284 }, 1285 existing: nil, 1286 expect: func(g *WithT, result interface{}) { 1287 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1288 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.Enabled).To(Equal(ptr.To(false))) 1289 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.StorageURI).To(BeNil()) 1290 }, 1291 expectedError: "", 1292 }, 1293 { 1294 name: "creates a vm with Managed Diagnostics enabled", 1295 spec: &VMSpec{ 1296 Name: "my-ultra-ssd-vm", 1297 Role: infrav1.Node, 1298 NICIDs: []string{"my-nic"}, 1299 SSHKeyData: "fakesshpublickey", 1300 Size: "Standard_D2v3", 1301 Location: "test-location", 1302 Zone: "1", 1303 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1304 DiagnosticsProfile: &infrav1.Diagnostics{ 1305 Boot: &infrav1.BootDiagnostics{ 1306 StorageAccountType: infrav1.ManagedDiagnosticsStorage, 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(BeNil()) 1316 }, 1317 expectedError: "", 1318 }, 1319 { 1320 name: "creates a vm with User Managed Diagnostics enabled", 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 name: "creates a vm with User Managed Diagnostics enabled, but missing StorageAccountURI", 1350 spec: &VMSpec{ 1351 Name: "my-ultra-ssd-vm", 1352 Role: infrav1.Node, 1353 NICIDs: []string{"my-nic"}, 1354 SSHKeyData: "fakesshpublickey", 1355 Size: "Standard_D2v3", 1356 Location: "test-location", 1357 Zone: "1", 1358 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1359 DiagnosticsProfile: &infrav1.Diagnostics{ 1360 Boot: &infrav1.BootDiagnostics{ 1361 StorageAccountType: infrav1.UserManagedDiagnosticsStorage, 1362 UserManaged: &infrav1.UserManagedBootDiagnostics{ 1363 StorageAccountURI: "aaa", 1364 }, 1365 }, 1366 }, 1367 SKU: validSKUWithUltraSSD, 1368 }, 1369 existing: nil, 1370 expect: func(g *WithT, result interface{}) { 1371 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1372 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.Enabled).To(Equal(ptr.To(true))) 1373 g.Expect(result.(armcompute.VirtualMachine).Properties.DiagnosticsProfile.BootDiagnostics.StorageURI).To(Equal(ptr.To("aaa"))) 1374 }, 1375 expectedError: "", 1376 }, 1377 { 1378 name: "creates a vm and associate it with a capacity reservation group", 1379 spec: &VMSpec{ 1380 Name: "my-vm", 1381 Role: infrav1.Node, 1382 NICIDs: []string{"my-nic"}, 1383 SSHKeyData: "fakesshpublickey", 1384 Size: "Standard_D2v3", 1385 Location: "test-location", 1386 Zone: "1", 1387 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1388 CapacityReservationGroupID: "my-crg-id", 1389 SKU: validSKU, 1390 }, 1391 existing: nil, 1392 expect: func(g *WithT, result interface{}) { 1393 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1394 g.Expect(result.(armcompute.VirtualMachine).Properties.CapacityReservation.CapacityReservationGroup.ID).To(Equal(ptr.To("my-crg-id"))) 1395 }, 1396 expectedError: "", 1397 }, 1398 { 1399 name: "creates a vm without capacity reservation group", 1400 spec: &VMSpec{ 1401 Name: "my-vm", 1402 Role: infrav1.Node, 1403 NICIDs: []string{"my-nic"}, 1404 SSHKeyData: "fakesshpublickey", 1405 Size: "Standard_D2v3", 1406 Location: "test-location", 1407 Zone: "1", 1408 Image: &infrav1.Image{ID: ptr.To("fake-image-id")}, 1409 CapacityReservationGroupID: "", 1410 SKU: validSKU, 1411 }, 1412 existing: nil, 1413 expect: func(g *WithT, result interface{}) { 1414 g.Expect(result).To(BeAssignableToTypeOf(armcompute.VirtualMachine{})) 1415 g.Expect(result.(armcompute.VirtualMachine).Properties.CapacityReservation).To(BeNil()) 1416 }, 1417 expectedError: "", 1418 }, 1419 } 1420 for _, tc := range testcases { 1421 tc := tc 1422 t.Run(tc.name, func(t *testing.T) { 1423 g := NewWithT(t) 1424 t.Parallel() 1425 1426 result, err := tc.spec.Parameters(context.TODO(), tc.existing) 1427 if tc.expectedError != "" { 1428 g.Expect(err).To(HaveOccurred()) 1429 g.Expect(err).To(MatchError(tc.expectedError)) 1430 } else { 1431 g.Expect(err).NotTo(HaveOccurred()) 1432 } 1433 tc.expect(g, result) 1434 }) 1435 } 1436 }