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