sigs.k8s.io/cluster-api-provider-azure@v1.17.0/azure/services/scalesets/spec_test.go (about) 1 /* 2 Copyright 2023 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 scalesets 18 19 import ( 20 "context" 21 "reflect" 22 "testing" 23 24 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" 25 "github.com/google/go-cmp/cmp" 26 . "github.com/onsi/gomega" 27 "k8s.io/apimachinery/pkg/api/resource" 28 "k8s.io/utils/ptr" 29 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 30 "sigs.k8s.io/cluster-api-provider-azure/azure" 31 "sigs.k8s.io/cluster-api-provider-azure/azure/services/resourceskus" 32 ) 33 34 var ( 35 defaultSpec, defaultVMSS = getDefaultVMSS() 36 windowsSpec, windowsVMSS = getDefaultWindowsVMSS() 37 acceleratedNetworkingSpec, acceleratedNetworkingVMSS = getAcceleratedNetworkingVMSS() 38 customSubnetSpec, customSubnetVMSS = getCustomSubnetVMSS() 39 customNetworkingSpec, customNetworkingVMSS = getCustomNetworkingVMSS() 40 spotVMSpec, spotVMVMSS = getSpotVMVMSS() 41 ephemeralSpec, ephemeralVMSS = getEPHVMSSS() 42 resourceDiskSpec, resourceDiskVMSS = getResourceDiskVMSS() 43 evictionSpec, evictionVMSS = getEvictionPolicyVMSS() 44 maxPriceSpec, maxPriceVMSS = getMaxPriceVMSS() 45 encryptionSpec, encryptionVMSS = getEncryptionVMSS() 46 userIdentitySpec, userIdentityVMSS = getUserIdentityVMSS() 47 hostEncryptionSpec, hostEncryptionVMSS = getHostEncryptionVMSS() 48 hostEncryptionUnsupportedSpec = getHostEncryptionUnsupportedSpec() 49 ephemeralReadSpec, ephemeralReadVMSS = getEphemeralReadOnlyVMSS() 50 defaultExistingSpec, defaultExistingVMSS, defaultExistingVMSSClone = getExistingDefaultVMSS() 51 userManagedStorageAccountDiagnosticsSpec, userManagedStorageAccountDiagnosticsVMSS = getUserManagedAndStorageAcccountDiagnosticsVMSS() 52 managedDiagnosticsSpec, managedDiagnoisticsVMSS = getManagedDiagnosticsVMSS() 53 disabledDiagnosticsSpec, disabledDiagnosticsVMSS = getDisabledDiagnosticsVMSS() 54 nilDiagnosticsProfileSpec, nilDiagnosticsProfileVMSS = getNilDiagnosticsProfileVMSS() 55 ) 56 57 func getDefaultVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 58 spec := newDefaultVMSSSpec() 59 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 60 NameSuffix: "my_disk_with_ultra_disks", 61 DiskSizeGB: 128, 62 Lun: ptr.To[int32](3), 63 ManagedDisk: &infrav1.ManagedDiskParameters{ 64 StorageAccountType: "UltraSSD_LRS", 65 }, 66 }) 67 68 vmss := newDefaultVMSS("VM_SIZE") 69 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 70 71 return spec, vmss 72 } 73 74 func getDefaultWindowsVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 75 spec := newWindowsVMSSSpec() 76 // Do we want this here? 77 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 78 NameSuffix: "my_disk_with_ultra_disks", 79 DiskSizeGB: 128, 80 Lun: ptr.To[int32](3), 81 ManagedDisk: &infrav1.ManagedDiskParameters{ 82 StorageAccountType: "UltraSSD_LRS", 83 }, 84 }) 85 vmss := newDefaultWindowsVMSS() 86 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 87 88 return spec, vmss 89 } 90 91 func getAcceleratedNetworkingVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 92 spec := newDefaultVMSSSpec() 93 spec.Size = "VM_SIZE_AN" 94 spec.AcceleratedNetworking = ptr.To(true) 95 spec.NetworkInterfaces[0].AcceleratedNetworking = ptr.To(true) 96 vmss := newDefaultVMSS("VM_SIZE_AN") 97 vmss.Properties.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].Properties.EnableAcceleratedNetworking = ptr.To(true) 98 99 return spec, vmss 100 } 101 102 func getCustomSubnetVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 103 spec := newDefaultVMSSSpec() 104 spec.Size = "VM_SIZE_AN" 105 spec.AcceleratedNetworking = ptr.To(true) 106 spec.NetworkInterfaces = []infrav1.NetworkInterface{ 107 { 108 SubnetName: "somesubnet", 109 PrivateIPConfigs: 1, // defaulter sets this to one 110 }, 111 } 112 customSubnetVMSS := newDefaultVMSS("VM_SIZE_AN") 113 netConfigs := customSubnetVMSS.Properties.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations 114 netConfigs[0].Name = ptr.To("my-vmss-nic-0") 115 netConfigs[0].Properties.EnableIPForwarding = ptr.To(true) 116 netConfigs[0].Properties.EnableAcceleratedNetworking = ptr.To(true) 117 nic1IPConfigs := netConfigs[0].Properties.IPConfigurations 118 nic1IPConfigs[0].Name = ptr.To("ipConfig0") 119 nic1IPConfigs[0].Properties.PrivateIPAddressVersion = ptr.To(armcompute.IPVersionIPv4) 120 nic1IPConfigs[0].Properties.Subnet = &armcompute.APIEntityReference{ 121 ID: ptr.To("/subscriptions/123/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/somesubnet"), 122 } 123 netConfigs[0].Properties.EnableAcceleratedNetworking = ptr.To(true) 124 netConfigs[0].Properties.Primary = ptr.To(true) 125 126 return spec, customSubnetVMSS 127 } 128 129 func getCustomNetworkingVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 130 spec := newDefaultVMSSSpec() 131 spec.NetworkInterfaces = []infrav1.NetworkInterface{ 132 { 133 SubnetName: "my-subnet", 134 PrivateIPConfigs: 1, 135 AcceleratedNetworking: ptr.To(true), 136 }, 137 { 138 SubnetName: "subnet2", 139 PrivateIPConfigs: 2, 140 AcceleratedNetworking: ptr.To(true), 141 }, 142 } 143 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 144 NameSuffix: "my_disk_with_ultra_disks", 145 DiskSizeGB: 128, 146 Lun: ptr.To[int32](3), 147 ManagedDisk: &infrav1.ManagedDiskParameters{ 148 StorageAccountType: "UltraSSD_LRS", 149 }, 150 }) 151 vmss := newDefaultVMSS("VM_SIZE") 152 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 153 netConfigs := vmss.Properties.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations 154 netConfigs[0].Name = ptr.To("my-vmss-nic-0") 155 netConfigs[0].Properties.EnableIPForwarding = ptr.To(true) 156 nic1IPConfigs := netConfigs[0].Properties.IPConfigurations 157 nic1IPConfigs[0].Name = ptr.To("ipConfig0") 158 nic1IPConfigs[0].Properties.PrivateIPAddressVersion = ptr.To(armcompute.IPVersionIPv4) 159 netConfigs[0].Properties.EnableAcceleratedNetworking = ptr.To(true) 160 netConfigs[0].Properties.Primary = ptr.To(true) 161 vmssIPConfigs := []armcompute.VirtualMachineScaleSetIPConfiguration{ 162 { 163 Name: ptr.To("ipConfig0"), 164 Properties: &armcompute.VirtualMachineScaleSetIPConfigurationProperties{ 165 Primary: ptr.To(true), 166 PrivateIPAddressVersion: ptr.To(armcompute.IPVersionIPv4), 167 Subnet: &armcompute.APIEntityReference{ 168 ID: ptr.To("/subscriptions/123/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/subnet2"), 169 }, 170 }, 171 }, 172 { 173 Name: ptr.To("ipConfig1"), 174 Properties: &armcompute.VirtualMachineScaleSetIPConfigurationProperties{ 175 PrivateIPAddressVersion: ptr.To(armcompute.IPVersionIPv4), 176 Subnet: &armcompute.APIEntityReference{ 177 ID: ptr.To("/subscriptions/123/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/subnet2"), 178 }, 179 }, 180 }, 181 } 182 netConfigs = append(netConfigs, &armcompute.VirtualMachineScaleSetNetworkConfiguration{ 183 Name: ptr.To("my-vmss-nic-1"), 184 Properties: &armcompute.VirtualMachineScaleSetNetworkConfigurationProperties{ 185 EnableAcceleratedNetworking: ptr.To(true), 186 IPConfigurations: azure.PtrSlice(&vmssIPConfigs), 187 EnableIPForwarding: ptr.To(true), 188 }, 189 }) 190 vmss.Properties.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations = netConfigs 191 192 return spec, vmss 193 } 194 195 func getSpotVMVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 196 spec := newDefaultVMSSSpec() 197 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 198 NameSuffix: "my_disk_with_ultra_disks", 199 DiskSizeGB: 128, 200 Lun: ptr.To[int32](3), 201 ManagedDisk: &infrav1.ManagedDiskParameters{ 202 StorageAccountType: "UltraSSD_LRS", 203 }, 204 }) 205 spec.SpotVMOptions = &infrav1.SpotVMOptions{} 206 vmss := newDefaultVMSS("VM_SIZE") 207 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 208 vmss.Properties.VirtualMachineProfile.Priority = ptr.To(armcompute.VirtualMachinePriorityTypesSpot) 209 210 return spec, vmss 211 } 212 213 func getEPHVMSSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 214 spec := newDefaultVMSSSpec() 215 spec.Size = vmSizeEPH 216 spec.SKU = resourceskus.SKU{ 217 Capabilities: []*armcompute.ResourceSKUCapabilities{ 218 { 219 Name: ptr.To(resourceskus.EphemeralOSDisk), 220 Value: ptr.To("True"), 221 }, 222 }, 223 } 224 spec.SpotVMOptions = &infrav1.SpotVMOptions{} 225 spec.OSDisk.DiffDiskSettings = &infrav1.DiffDiskSettings{ 226 Option: string(armcompute.DiffDiskOptionsLocal), 227 } 228 vmss := newDefaultVMSS(vmSizeEPH) 229 vmss.Properties.VirtualMachineProfile.StorageProfile.OSDisk.DiffDiskSettings = &armcompute.DiffDiskSettings{ 230 Option: ptr.To(armcompute.DiffDiskOptionsLocal), 231 } 232 vmss.Properties.VirtualMachineProfile.Priority = ptr.To(armcompute.VirtualMachinePriorityTypesSpot) 233 234 return spec, vmss 235 } 236 237 func getResourceDiskVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 238 spec := newDefaultVMSSSpec() 239 spec.Size = vmSizeEPH 240 spec.SKU = resourceskus.SKU{ 241 Capabilities: []*armcompute.ResourceSKUCapabilities{ 242 { 243 Name: ptr.To(resourceskus.EphemeralOSDisk), 244 Value: ptr.To("True"), 245 }, 246 }, 247 } 248 spec.SpotVMOptions = &infrav1.SpotVMOptions{} 249 spec.OSDisk.DiffDiskSettings = &infrav1.DiffDiskSettings{ 250 Option: string(armcompute.DiffDiskOptionsLocal), 251 Placement: ptr.To(infrav1.DiffDiskPlacementResourceDisk), 252 } 253 vmss := newDefaultVMSS(vmSizeEPH) 254 vmss.Properties.VirtualMachineProfile.StorageProfile.OSDisk.DiffDiskSettings = &armcompute.DiffDiskSettings{ 255 Option: ptr.To(armcompute.DiffDiskOptionsLocal), 256 Placement: ptr.To(armcompute.DiffDiskPlacementResourceDisk), 257 } 258 vmss.Properties.VirtualMachineProfile.Priority = ptr.To(armcompute.VirtualMachinePriorityTypesSpot) 259 260 return spec, vmss 261 } 262 263 func getEvictionPolicyVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 264 spec := newDefaultVMSSSpec() 265 spec.Size = vmSizeEPH 266 deletePolicy := infrav1.SpotEvictionPolicyDelete 267 spec.SpotVMOptions = &infrav1.SpotVMOptions{EvictionPolicy: &deletePolicy} 268 vmss := newDefaultVMSS(vmSizeEPH) 269 vmss.Properties.VirtualMachineProfile.Priority = ptr.To(armcompute.VirtualMachinePriorityTypesSpot) 270 vmss.Properties.VirtualMachineProfile.EvictionPolicy = ptr.To(armcompute.VirtualMachineEvictionPolicyTypesDelete) 271 272 return spec, vmss 273 } 274 275 func getMaxPriceVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 276 spec := newDefaultVMSSSpec() 277 maxPrice := resource.MustParse("0.001") 278 spec.SpotVMOptions = &infrav1.SpotVMOptions{ 279 MaxPrice: &maxPrice, 280 } 281 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 282 NameSuffix: "my_disk_with_ultra_disks", 283 DiskSizeGB: 128, 284 Lun: ptr.To[int32](3), 285 ManagedDisk: &infrav1.ManagedDiskParameters{ 286 StorageAccountType: "UltraSSD_LRS", 287 }, 288 }) 289 vmss := newDefaultVMSS("VM_SIZE") 290 vmss.Properties.VirtualMachineProfile.Priority = ptr.To(armcompute.VirtualMachinePriorityTypesSpot) 291 vmss.Properties.VirtualMachineProfile.BillingProfile = &armcompute.BillingProfile{ 292 MaxPrice: ptr.To[float64](0.001), 293 } 294 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 295 296 return spec, vmss 297 } 298 299 func getEncryptionVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 300 spec := newDefaultVMSSSpec() 301 spec.OSDisk.ManagedDisk.DiskEncryptionSet = &infrav1.DiskEncryptionSetParameters{ 302 ID: "my-diskencryptionset-id", 303 } 304 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 305 NameSuffix: "my_disk_with_ultra_disks", 306 DiskSizeGB: 128, 307 Lun: ptr.To[int32](3), 308 ManagedDisk: &infrav1.ManagedDiskParameters{ 309 StorageAccountType: "UltraSSD_LRS", 310 }, 311 }) 312 vmss := newDefaultVMSS("VM_SIZE") 313 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 314 osdisk := vmss.Properties.VirtualMachineProfile.StorageProfile.OSDisk 315 osdisk.ManagedDisk = &armcompute.VirtualMachineScaleSetManagedDiskParameters{ 316 StorageAccountType: ptr.To(armcompute.StorageAccountTypesPremiumLRS), 317 DiskEncryptionSet: &armcompute.DiskEncryptionSetParameters{ 318 ID: ptr.To("my-diskencryptionset-id"), 319 }, 320 } 321 322 return spec, vmss 323 } 324 325 func getUserIdentityVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 326 spec := newDefaultVMSSSpec() 327 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 328 NameSuffix: "my_disk_with_ultra_disks", 329 DiskSizeGB: 128, 330 Lun: ptr.To[int32](3), 331 ManagedDisk: &infrav1.ManagedDiskParameters{ 332 StorageAccountType: "UltraSSD_LRS", 333 }, 334 }) 335 spec.Identity = infrav1.VMIdentityUserAssigned 336 spec.UserAssignedIdentities = []infrav1.UserAssignedIdentity{ 337 { 338 ProviderID: "azure:///subscriptions/123/resourcegroups/456/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id1", 339 }, 340 } 341 vmss := newDefaultVMSS("VM_SIZE") 342 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 343 vmss.Identity = &armcompute.VirtualMachineScaleSetIdentity{ 344 Type: ptr.To(armcompute.ResourceIdentityTypeUserAssigned), 345 UserAssignedIdentities: map[string]*armcompute.UserAssignedIdentitiesValue{ 346 "/subscriptions/123/resourcegroups/456/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id1": {}, 347 }, 348 } 349 350 return spec, vmss 351 } 352 353 func getHostEncryptionVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 354 spec := newDefaultVMSSSpec() 355 spec.Size = "VM_SIZE_EAH" 356 spec.SecurityProfile = &infrav1.SecurityProfile{EncryptionAtHost: ptr.To(true)} 357 spec.SKU = resourceskus.SKU{ 358 Capabilities: []*armcompute.ResourceSKUCapabilities{ 359 { 360 Name: ptr.To(resourceskus.EncryptionAtHost), 361 Value: ptr.To("True"), 362 }, 363 }, 364 } 365 vmss := newDefaultVMSS("VM_SIZE_EAH") 366 vmss.Properties.VirtualMachineProfile.SecurityProfile = &armcompute.SecurityProfile{ 367 EncryptionAtHost: ptr.To(true), 368 } 369 vmss.SKU.Name = ptr.To(spec.Size) 370 371 return spec, vmss 372 } 373 374 func getHostEncryptionUnsupportedSpec() ScaleSetSpec { 375 spec, _ := getHostEncryptionVMSS() 376 spec.SKU = resourceskus.SKU{} 377 return spec 378 } 379 380 func getEphemeralReadOnlyVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 381 spec := newDefaultVMSSSpec() 382 spec.Size = "VM_SIZE_EPH" 383 spec.OSDisk.DiffDiskSettings = &infrav1.DiffDiskSettings{ 384 Option: "Local", 385 } 386 spec.OSDisk.CachingType = "ReadOnly" 387 spec.SKU = resourceskus.SKU{ 388 Capabilities: []*armcompute.ResourceSKUCapabilities{ 389 { 390 Name: ptr.To(resourceskus.EphemeralOSDisk), 391 Value: ptr.To("True"), 392 }, 393 }, 394 } 395 396 vmss := newDefaultVMSS("VM_SIZE_EPH") 397 vmss.Properties.VirtualMachineProfile.StorageProfile.OSDisk.DiffDiskSettings = &armcompute.DiffDiskSettings{ 398 Option: ptr.To(armcompute.DiffDiskOptionsLocal), 399 } 400 vmss.Properties.VirtualMachineProfile.StorageProfile.OSDisk.Caching = ptr.To(armcompute.CachingTypesReadOnly) 401 402 return spec, vmss 403 } 404 405 func getExistingDefaultVMSS() (s ScaleSetSpec, existing armcompute.VirtualMachineScaleSet, result armcompute.VirtualMachineScaleSet) { 406 spec := newDefaultVMSSSpec() 407 spec.Capacity = 2 408 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 409 NameSuffix: "my_disk_with_ultra_disks", 410 DiskSizeGB: 128, 411 Lun: ptr.To[int32](3), 412 ManagedDisk: &infrav1.ManagedDiskParameters{ 413 StorageAccountType: "UltraSSD_LRS", 414 }, 415 }) 416 spec.MaxSurge = 1 417 418 spec.VMImage = &infrav1.Image{ 419 Marketplace: &infrav1.AzureMarketplaceImage{ 420 ImagePlan: infrav1.ImagePlan{ 421 Publisher: "fake-publisher", 422 Offer: "my-offer", 423 SKU: "sku-id", 424 }, 425 Version: "2.0", 426 }, 427 } 428 429 existingVMSS := newDefaultExistingVMSS("VM_SIZE") 430 existingVMSS.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 431 existingVMSS.SKU.Capacity = ptr.To[int64](2) 432 existingVMSS.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 433 434 clone := newDefaultExistingVMSS("VM_SIZE") 435 clone.SKU.Capacity = ptr.To[int64](3) 436 clone.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 437 clone.Properties.VirtualMachineProfile.NetworkProfile = nil 438 439 clone.Properties.VirtualMachineProfile.StorageProfile.ImageReference.Version = ptr.To("2.0") 440 clone.Properties.VirtualMachineProfile.NetworkProfile = nil 441 442 return spec, existingVMSS, clone 443 } 444 445 func getUserManagedAndStorageAcccountDiagnosticsVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 446 storageURI := "https://fakeurl" 447 spec := newDefaultVMSSSpec() 448 spec.DiagnosticsProfile = &infrav1.Diagnostics{ 449 Boot: &infrav1.BootDiagnostics{ 450 StorageAccountType: infrav1.UserManagedDiagnosticsStorage, 451 UserManaged: &infrav1.UserManagedBootDiagnostics{ 452 StorageAccountURI: storageURI, 453 }, 454 }, 455 } 456 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 457 NameSuffix: "my_disk_with_ultra_disks", 458 DiskSizeGB: 128, 459 Lun: ptr.To[int32](3), 460 ManagedDisk: &infrav1.ManagedDiskParameters{ 461 StorageAccountType: "UltraSSD_LRS", 462 }, 463 }) 464 465 spec.VMSSInstances = newDefaultInstances() 466 spec.MaxSurge = 1 467 468 vmss := newDefaultVMSS("VM_SIZE") 469 vmss.Properties.VirtualMachineProfile.DiagnosticsProfile = &armcompute.DiagnosticsProfile{BootDiagnostics: &armcompute.BootDiagnostics{ 470 Enabled: ptr.To(true), 471 StorageURI: &storageURI, 472 }} 473 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 474 475 return spec, vmss 476 } 477 478 func getManagedDiagnosticsVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 479 spec := newDefaultVMSSSpec() 480 spec.DiagnosticsProfile = &infrav1.Diagnostics{ 481 Boot: &infrav1.BootDiagnostics{ 482 StorageAccountType: infrav1.ManagedDiagnosticsStorage, 483 }, 484 } 485 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 486 NameSuffix: "my_disk_with_ultra_disks", 487 DiskSizeGB: 128, 488 Lun: ptr.To[int32](3), 489 ManagedDisk: &infrav1.ManagedDiskParameters{ 490 StorageAccountType: "UltraSSD_LRS", 491 }, 492 }) 493 spec.VMSSInstances = newDefaultInstances() 494 495 vmss := newDefaultVMSS("VM_SIZE") 496 vmss.Properties.VirtualMachineProfile.DiagnosticsProfile = &armcompute.DiagnosticsProfile{BootDiagnostics: &armcompute.BootDiagnostics{ 497 Enabled: ptr.To(true), 498 }} 499 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 500 501 return spec, vmss 502 } 503 504 func getDisabledDiagnosticsVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 505 spec := newDefaultVMSSSpec() 506 spec.DiagnosticsProfile = &infrav1.Diagnostics{ 507 Boot: &infrav1.BootDiagnostics{ 508 StorageAccountType: infrav1.DisabledDiagnosticsStorage, 509 }, 510 } 511 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 512 NameSuffix: "my_disk_with_ultra_disks", 513 DiskSizeGB: 128, 514 Lun: ptr.To[int32](3), 515 ManagedDisk: &infrav1.ManagedDiskParameters{ 516 StorageAccountType: "UltraSSD_LRS", 517 }, 518 }) 519 spec.VMSSInstances = newDefaultInstances() 520 521 vmss := newDefaultVMSS("VM_SIZE") 522 vmss.Properties.VirtualMachineProfile.DiagnosticsProfile = &armcompute.DiagnosticsProfile{BootDiagnostics: &armcompute.BootDiagnostics{ 523 Enabled: ptr.To(false), 524 }} 525 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 526 527 return spec, vmss 528 } 529 530 func getNilDiagnosticsProfileVMSS() (ScaleSetSpec, armcompute.VirtualMachineScaleSet) { 531 spec := newDefaultVMSSSpec() 532 spec.DiagnosticsProfile = nil 533 534 spec.DataDisks = append(spec.DataDisks, infrav1.DataDisk{ 535 NameSuffix: "my_disk_with_ultra_disks", 536 DiskSizeGB: 128, 537 Lun: ptr.To[int32](3), 538 ManagedDisk: &infrav1.ManagedDiskParameters{ 539 StorageAccountType: "UltraSSD_LRS", 540 }, 541 }) 542 spec.VMSSInstances = newDefaultInstances() 543 544 vmss := newDefaultVMSS("VM_SIZE") 545 vmss.Properties.VirtualMachineProfile.DiagnosticsProfile = nil 546 547 vmss.Properties.AdditionalCapabilities = &armcompute.AdditionalCapabilities{UltraSSDEnabled: ptr.To(true)} 548 549 return spec, vmss 550 } 551 552 func TestScaleSetParameters(t *testing.T) { 553 testcases := []struct { 554 name string 555 spec ScaleSetSpec 556 existing interface{} 557 expected interface{} 558 expectedError string 559 }{ 560 { 561 name: "get parameters for a vmss", 562 spec: defaultSpec, 563 existing: nil, 564 expected: defaultVMSS, 565 expectedError: "", 566 }, 567 { 568 name: "get parameters for a windows vmss", 569 spec: windowsSpec, 570 existing: nil, 571 expected: windowsVMSS, 572 expectedError: "", 573 }, 574 { 575 name: "windows vmss up to date", 576 spec: windowsSpec, 577 existing: windowsVMSS, 578 expected: nil, 579 expectedError: "", 580 }, 581 { 582 name: "accelerated networking vmss", 583 spec: acceleratedNetworkingSpec, 584 existing: nil, 585 expected: acceleratedNetworkingVMSS, 586 expectedError: "", 587 }, 588 { 589 name: "custom subnet vmss", 590 spec: customSubnetSpec, 591 existing: nil, 592 expected: customSubnetVMSS, 593 expectedError: "", 594 }, 595 { 596 name: "custom networking vmss", 597 spec: customNetworkingSpec, 598 existing: nil, 599 expected: customNetworkingVMSS, 600 expectedError: "", 601 }, 602 { 603 name: "spot vm vmss", 604 spec: spotVMSpec, 605 existing: nil, 606 expected: spotVMVMSS, 607 expectedError: "", 608 }, 609 { 610 name: "spot vm and ephemeral disk vmss", 611 spec: ephemeralSpec, 612 existing: nil, 613 expected: ephemeralVMSS, 614 expectedError: "", 615 }, 616 { 617 name: "spot vm and ephemeral disk with resourceDisk placement vmss", 618 spec: resourceDiskSpec, 619 existing: nil, 620 expected: resourceDiskVMSS, 621 expectedError: "", 622 }, 623 { 624 name: "spot vm and eviction policy vmss", 625 spec: evictionSpec, 626 existing: nil, 627 expected: evictionVMSS, 628 expectedError: "", 629 }, 630 { 631 name: "spot vm and max price vmss", 632 spec: maxPriceSpec, 633 existing: nil, 634 expected: maxPriceVMSS, 635 expectedError: "", 636 }, 637 { 638 name: "eviction policy vmss", 639 spec: evictionSpec, 640 existing: nil, 641 expected: evictionVMSS, 642 expectedError: "", 643 }, 644 { 645 name: "encryption vmss", 646 spec: encryptionSpec, 647 existing: nil, 648 expected: encryptionVMSS, 649 expectedError: "", 650 }, 651 { 652 name: "user assigned identity vmss", 653 spec: userIdentitySpec, 654 existing: nil, 655 expected: userIdentityVMSS, 656 expectedError: "", 657 }, 658 { 659 name: "host encryption vmss", 660 spec: hostEncryptionSpec, 661 existing: nil, 662 expected: hostEncryptionVMSS, 663 expectedError: "", 664 }, 665 { 666 name: "host encryption unsupported vmss", 667 spec: hostEncryptionUnsupportedSpec, 668 existing: nil, 669 expected: nil, 670 expectedError: "reconcile error that cannot be recovered occurred: encryption at host is not supported for VM type VM_SIZE_EAH. Object will not be requeued", 671 }, 672 { 673 name: "ephemeral os disk read only vmss", 674 spec: ephemeralReadSpec, 675 existing: nil, 676 expected: ephemeralReadVMSS, 677 expectedError: "", 678 }, 679 { 680 name: "update for existing vmss", 681 spec: defaultExistingSpec, 682 existing: defaultExistingVMSS, 683 expected: defaultExistingVMSSClone, 684 expectedError: "", 685 }, 686 { 687 name: "vm with diagnostics set to User Managed and StorageAccountURI set", 688 spec: userManagedStorageAccountDiagnosticsSpec, 689 existing: nil, 690 expected: userManagedStorageAccountDiagnosticsVMSS, 691 expectedError: "", 692 }, 693 { 694 name: "vm with diagnostics set to Managed", 695 spec: managedDiagnosticsSpec, 696 existing: nil, 697 expected: managedDiagnoisticsVMSS, 698 expectedError: "", 699 }, 700 { 701 name: "vm with diagnostics set to Disabled", 702 spec: disabledDiagnosticsSpec, 703 existing: nil, 704 expected: disabledDiagnosticsVMSS, 705 expectedError: "", 706 }, 707 { 708 name: "vm with DiagnosticsProfile set to nil, do not panic", 709 spec: nilDiagnosticsProfileSpec, 710 existing: nil, 711 expected: nilDiagnosticsProfileVMSS, 712 expectedError: "", 713 }, 714 } 715 for _, tc := range testcases { 716 tc := tc 717 t.Run(tc.name, func(t *testing.T) { 718 g := NewWithT(t) 719 t.Parallel() 720 721 param, err := tc.spec.Parameters(context.TODO(), tc.existing) 722 if tc.expectedError != "" { 723 g.Expect(err).To(HaveOccurred()) 724 g.Expect(err).To(MatchError(tc.expectedError)) 725 } else { 726 g.Expect(err).NotTo(HaveOccurred()) 727 if tc.expected == nil { 728 g.Expect(param).To(BeNil()) 729 } else { 730 result, ok := param.(armcompute.VirtualMachineScaleSet) 731 if !ok { 732 t.Fatalf("expected type VirtualMachineScaleSet, got %T", param) 733 } 734 result.Properties.VirtualMachineProfile.OSProfile.AdminPassword = nil // Override this field as it's randomly generated. We can't set anything in tc.expected to match it. 735 736 if !reflect.DeepEqual(tc.expected, result) { 737 t.Errorf("Diff between actual result and expected result:\n%s", cmp.Diff(result, tc.expected)) 738 } 739 } 740 } 741 }) 742 } 743 }