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  }