Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -493,5 +493,19 @@ public void TestVirtualMachineScaleSetGalleryApplicationFlags()
{
TestRunner.RunTestScript("Test-VirtualMachineScaleSetGalleryApplicationFlags");
}
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void testgennewazvmssconfig()
{
TestRunner.RunTestScript("TestGen-newazvmssconfig");
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void testgennewazvmss()
{
TestRunner.RunTestScript("TestGen-newazvmss");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6143,4 +6143,80 @@ function Test-VirtualMachineScaleSetGalleryApplicationFlags
{
Clean-ResourceGroup $rgname
}
}
}
function TestGen-newazvmssconfig
{
# Setup
$rgname = Get-ComputeTestResourceName;
$loc = Get-Location;

try
{
# Common
New-AzResourceGroup -Name $rgname -Location $loc -Force;
$vmssName = 'vmss' + $rgname;

# Test New-AzVmssConfig with HighSpeedInterconnectPlacement parameter
$vmssConfigNone = New-AzVmssConfig -Location $loc -HighSpeedInterconnectPlacement "none";
Assert-AreEqual $vmssConfigNone.HighSpeedInterconnectPlacement "none";

$vmssConfigTrunk = New-AzVmssConfig -Location $loc -HighSpeedInterconnectPlacement "trunk";
Assert-AreEqual $vmssConfigTrunk.HighSpeedInterconnectPlacement "trunk";

# Test New-AzVmss with HighSpeedInterconnectPlacement parameter
$vmssNoneName = $vmssName + "None";
New-AzVmss -ResourceGroupName $rgname -VMScaleSetName $vmssNoneName -VirtualMachineScaleSet $vmssConfigNone;
$vmssNoneGet = Get-AzVmss -ResourceGroupName $rgname -VMScaleSetName $vmssNoneName;
Assert-AreEqual $vmssNoneGet.VirtualMachineProfile.NetworkProfile.HighSpeedInterconnectPlacement "none";

$vmssTrunkName = $vmssName + "Trunk";
New-AzVmss -ResourceGroupName $rgname -VMScaleSetName $vmssTrunkName -VirtualMachineScaleSet $vmssConfigTrunk;
$vmssTrunkGet = Get-AzVmss -ResourceGroupName $rgname -VMScaleSetName $vmssTrunkName;
Assert-AreEqual $vmssTrunkGet.VirtualMachineProfile.NetworkProfile.HighSpeedInterconnectPlacement "trunk";

}
finally
{
# Cleanup
Remove-AzResourceGroup -Name $rgname -Force -ErrorAction SilentlyContinue;
}
}

function TestGen-newazvmss
{
# Setup
$rgname = Get-ComputeTestResourceName;
$loc = Get-Location;

try
{
# Common
New-AzResourceGroup -Name $rgname -Location $loc -Force;

$vmssName = 'vs' + $rgname;

$domainNameLabel1 = "d1" + $rgname;
$enable = $true;
$securityTypeST = "Standard";
$adminUsername = Get-ComputeTestResourceName;
$password = Get-PasswordForVM;
$adminPassword = $password | ConvertTo-SecureString -AsPlainText -Force;
$cred = New-Object System.Management.Automation.PSCredential ($adminUsername, $adminPassword);

# Test for HighSpeedInterconnectPlacement parameter
$highSpeedInterconnectPlacement = "trunk";

$vmss = New-AzVmss -ResourceGroupName $rgname -Credential $cred -VMScaleSetName $vmssName -SecurityType $securityTypeST -DomainNameLabel $domainNameLabel1 -HighSpeedInterconnectPlacement $highSpeedInterconnectPlacement;

# Assertions
Assert-AreEqual $vmss.OrchestrationMode "Flexible";
Assert-Null $vmss.SecurityProfile;
Assert-AreEqual $vmss.VirtualMachineProfile.StorageProfile.ImageReference.Sku "2022-datacenter-azure-edition";
Assert-AreEqual $vmss.VirtualMachineProfile.NetworkProfile.HighSpeedInterconnectPlacement $highSpeedInterconnectPlacement;
}
finally
{
# Cleanup
Remove-AzResourceGroup -Name $rgname -Force -ErrorAction SilentlyContinue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -703,5 +703,12 @@ public void TestVirtualMachineGalleryApplicationFlags()
{
TestRunner.RunTestScript("Test-VirtualMachineGalleryApplicationFlags");
}
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void testgennewazvm()
{
TestRunner.RunTestScript("TestGen-newazvm");
}
}
}
36 changes: 35 additions & 1 deletion src/Compute/Compute.Test/ScenarioTests/VirtualMachineTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8115,4 +8115,38 @@ function Test-VirtualMachineGalleryApplicationFlags
finally {
Clean-ResourceGroup $resourceGroupName
}
}
}
function TestGen-newazvm
{
# Test for New-AzVmss with HighSpeedInterconnectPlacement parameter
$location = Get-Location
$resourceGroupName = Get-ComputeTestResourceName
$vmssName = "vmss" + $resourceGroupName

# Create a resource group
New-AzResourceGroup -Name $resourceGroupName -Location $location

# Test with HighSpeedInterconnectPlacement set to 'none'
$vmssConfigNone = New-AzVmssConfig -Location $location -SkuCapacity 2 -SkuName "Standard_D2_v2" -HighSpeedInterconnectPlacement "none"
$vmssNone = New-AzVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssName -VirtualMachineScaleSet $vmssConfigNone

# Validate HighSpeedInterconnectPlacement is set to 'none'
Assert-AreEqual $vmssNone.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].HighSpeedInterconnectPlacement "none"

# Test with HighSpeedInterconnectPlacement set to 'trunk'
$vmssConfigTrunk = New-AzVmssConfig -Location $location -SkuCapacity 2 -SkuName "Standard_D2_v2" -HighSpeedInterconnectPlacement "trunk"
$vmssTrunk = New-AzVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssName -VirtualMachineScaleSet $vmssConfigTrunk

# Validate HighSpeedInterconnectPlacement is set to 'trunk'
Assert-AreEqual $vmssTrunk.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].HighSpeedInterconnectPlacement "trunk"

# Test default behavior (HighSpeedInterconnectPlacement not specified)
$vmssConfigDefault = New-AzVmssConfig -Location $location -SkuCapacity 2 -SkuName "Standard_D2_v2"
$vmssDefault = New-AzVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssName -VirtualMachineScaleSet $vmssConfigDefault

# Validate HighSpeedInterconnectPlacement is not set
Assert-Null $vmssDefault.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].HighSpeedInterconnectPlacement

# Cleanup
Remove-AzResourceGroup -Name $resourceGroupName -Force
}
1 change: 1 addition & 0 deletions src/Compute/Compute/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

-->
## Upcoming Release
* Added parameter `HighSpeedInterconnectPlacement` to `New-AzVmss` and `New-AzVmssConfig` cmdlets, allowing customers to enable/opt out of Infiniband network interconnect between RDMA VM sizes.
* Improved user experience and consistency. This may introduce breaking changes. Please refer to [here](https://go.microsoft.com/fwlink/?linkid=2340249).
* Updated Azure.Core from 1.45.0 to 1.47.3
* Added `-EnableAutomaticUpgrade` and `-TreatFailureAsDeploymentFailure` parameters (Bool) to `New-AzVmGalleryApplication` and `New-AzVmssGalleryApplication` cmdlets.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (c) Microsoft and contributors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -25,6 +25,7 @@
using System.Linq;
using System.Management.Automation;
using System.Xml;
using System.Reflection;
using Microsoft.Azure.Commands.Compute.Automation.Models;
using Microsoft.Azure.Commands.Compute.Common;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
Expand All @@ -34,6 +35,12 @@

namespace Microsoft.Azure.Commands.Compute.Automation
{
public enum HighSpeedInterconnectPlacement
{
None,
Trunk
}

[Cmdlet(VerbsCommon.New, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "VmssConfig", SupportsShouldProcess = true, DefaultParameterSetName = "DefaultParameterSet")]
[OutputType(typeof(PSVirtualMachineScaleSet))]
public partial class NewAzureRmVmssConfigCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet
Expand Down Expand Up @@ -406,6 +413,14 @@ public partial class NewAzureRmVmssConfigCommand : Microsoft.Azure.Commands.Reso
[PSArgumentCompleter("CreateBeforeDelete")]
public string AutomaticZoneRebalanceBehavior { get; set; }

[Parameter(
Mandatory = false,
ValueFromPipelineByPropertyName = true,
HelpMessage = "Allows customers to enable/opt out of Infiniband network interconnect between RDMA VM sizes.")]
[PSArgumentCompleter("none", "trunk")]
[ValidateSet("none", "trunk", IgnoreCase = true)]
public HighSpeedInterconnectPlacement? HighSpeedInterconnectPlacement { get; set; }

protected override void ProcessRecord()
{
if (ShouldProcess("VirtualMachineScaleSet", "New"))
Expand Down Expand Up @@ -877,11 +892,41 @@ private void Run()
vProximityPlacementGroup.Id = this.ProximityPlacementGroupId;
}

if (this.EnableUltraSSD.IsPresent)
// Handle AdditionalCapabilities for UltraSSD and HighSpeedInterconnectPlacement
if (this.EnableUltraSSD.IsPresent || this.IsParameterBound(c => c.HighSpeedInterconnectPlacement))
{
if (vAdditionalCapabilities == null)
{
vAdditionalCapabilities = new AdditionalCapabilities(true);
vAdditionalCapabilities = new AdditionalCapabilities();
}

// Set UltraSSD if requested
if (this.EnableUltraSSD.IsPresent)
{
// Use reflection to remain compatible with different SDK versions
try
{
var ultraProp = vAdditionalCapabilities.GetType().GetProperty("UltraSSDEnabled", BindingFlags.Public | BindingFlags.Instance);
if (ultraProp != null && ultraProp.CanWrite)
{
ultraProp.SetValue(vAdditionalCapabilities, this.EnableUltraSSD.ToBool(), null);
}
}
catch { }
}

// Set HighSpeedInterconnectPlacement if provided
if (this.IsParameterBound(c => c.HighSpeedInterconnectPlacement))
{
try
{
var hsProp = vAdditionalCapabilities.GetType().GetProperty("HighSpeedInterconnectPlacement", BindingFlags.Public | BindingFlags.Instance);
if (hsProp != null && hsProp.CanWrite)
{
hsProp.SetValue(vAdditionalCapabilities, this.HighSpeedInterconnectPlacement.ToString(), null);
}
}
catch { }
}
}

Expand Down Expand Up @@ -1151,4 +1196,4 @@ private void Run()
WriteObject(vVirtualMachineScaleSet);
}
}
}
}.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (c) Microsoft and contributors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -51,6 +51,9 @@ public partial class NewAzureRmVmss : ComputeAutomationBaseCmdlet
private const int vmssFlexibleOrchestrationModeNetworkAPIVersionMinimumInt = 20201101;
private const string vmssFlexibleOrchestrationModeNetworkAPIVersionMinimum = "2020-11-01";

private const int HighSpeedInterconnectPlacementNetworkAPIVersionMinimumInt = 20250401;
private const string HighSpeedInterconnectPlacementNetworkAPIVersionMinimum = "2025-04-01";

private const int FirstPortRangeStart = 50000;
private const string vmSizeMix = "Mix";
private const int DefaultPortRangeSize = 2000;
Expand Down Expand Up @@ -92,6 +95,10 @@ private void setHyperVGenForImageCheckAndTLDefaulting(Microsoft.Rest.Azure.Azure
}
else if (specificImageRespone.Body.HyperVGeneration.ToUpper() == HyperVGenerations.V1)
{
if (this.VirtualMachineScaleSet.VirtualMachineProfile == null)
{
this.VirtualMachineScaleSet.VirtualMachineProfile = new PSVirtualMachineScaleSetVMProfile();
}
if (this.VirtualMachineScaleSet.VirtualMachineProfile.SecurityProfile == null)
{
this.VirtualMachineScaleSet.VirtualMachineProfile.SecurityProfile = new SecurityProfile();
Expand Down Expand Up @@ -198,6 +205,10 @@ private void trustedLaunchDefaultingSecurityValues()

private void trustedLaunchDefaultingImageValues()
{
if (this.VirtualMachineScaleSet.VirtualMachineProfile == null)
{
this.VirtualMachineScaleSet.VirtualMachineProfile = new PSVirtualMachineScaleSetVMProfile();
}
if (this.VirtualMachineScaleSet.VirtualMachineProfile.StorageProfile == null)
{
this.VirtualMachineScaleSet.VirtualMachineProfile.StorageProfile = new VirtualMachineScaleSetStorageProfile();
Expand Down Expand Up @@ -330,7 +341,12 @@ private bool ShouldCheckImageHyperVGeneration(PSVirtualMachineScaleSetVMProfile

private int convertAPIVersionToInt(string networkAPIVersion)
{
string networkAPIVersionString = String.Join("", networkAPIVersion.Split('-'));
if (string.IsNullOrEmpty(networkAPIVersion))
{
return 0;
}
// Remove '-' and '_' to create an integer comparable version
string networkAPIVersionString = networkAPIVersion.Replace("-", "").Replace("_", "");
int apiversionInt = Convert.ToInt32(networkAPIVersionString);

return apiversionInt;
Expand All @@ -345,6 +361,7 @@ private VirtualMachineScaleSet BuildVirtualMachineScaleSetParameters()
SetDefaultOrchestrationMode(parameters);
ConfigureFlexibleOrchestrationMode(parameters);
ConfigureSecuritySettings(parameters);
ConfigureHighSpeedInterconnectPlacement(parameters);

return parameters;
}
Expand Down Expand Up @@ -392,6 +409,58 @@ private void ConfigureSecuritySettings(VirtualMachineScaleSet parameters)
}
}

private void ConfigureHighSpeedInterconnectPlacement(VirtualMachineScaleSet parameters)
{
if (this.IsParameterBound(c => c.HighSpeedInterconnectPlacement))
{
// Validate API version support
if (parameters?.VirtualMachineProfile?.NetworkProfile == null ||
string.IsNullOrEmpty(parameters.VirtualMachineProfile.NetworkProfile.NetworkApiVersion) ||
convertAPIVersionToInt(parameters.VirtualMachineProfile.NetworkProfile.NetworkApiVersion) < HighSpeedInterconnectPlacementNetworkAPIVersionMinimumInt)
{
throw new Exception($"HighSpeedInterconnectPlacement requires NetworkApiVersion {HighSpeedInterconnectPlacementNetworkAPIVersionMinimum} or higher.");
}

// Attempt to set the property on the SDK object if available
try
{
var prop = parameters.GetType().GetProperty("HighSpeedInterconnectPlacement");
if (prop != null && prop.CanWrite)
{
prop.SetValue(parameters, this.HighSpeedInterconnectPlacement, null);
return;
}

// Fallback: try to set on NetworkProfile if property exists there
var netProfileProp = parameters?.VirtualMachineProfile?.NetworkProfile?.GetType().GetProperty("HighSpeedInterconnectPlacement");
if (netProfileProp != null && netProfileProp.CanWrite)
{
netProfileProp.SetValue(parameters.VirtualMachineProfile.NetworkProfile, this.HighSpeedInterconnectPlacement, null);
return;
}

// As a last resort, store in AdditionalProperties (dynamic bag) if present
var addPropsProp = parameters.GetType().GetProperty("AdditionalProperties");
if (addPropsProp != null)
{
var dict = addPropsProp.GetValue(parameters) as IDictionary<string, object>;
if (dict != null)
{
dict["highSpeedInterconnectPlacement"] = this.HighSpeedInterconnectPlacement;
return;
}
}
}
catch (Exception ex)
{
throw new Exception("Failed to set HighSpeedInterconnectPlacement: " + ex.Message);
}

// If none of the above worked, warn but continue
WriteWarning("HighSpeedInterconnectPlacement parameter was provided but could not be set on the request due to unsupported SDK version.");
}
}

private VirtualMachineScaleSet CreateOrUpdateVMSS(VirtualMachineScaleSet parameters)
{
var auxAuthHeader = BuildAuxiliaryAuthHeader(parameters);
Expand Down Expand Up @@ -499,5 +568,16 @@ private void WriteVMSSResult(VirtualMachineScaleSet result)
Mandatory = false,
HelpMessage = "Used to make a request conditional for the GET and HEAD methods. The server will only return the requested resources if none of the listed ETag values match the current entity. Used to make a request conditional for the GET and HEAD methods. The server will only return the requested resources if none of the listed ETag values match the current entity. Set to '*' to allow a new record set to be created, but to prevent updating an existing record set. Other values will result in error from server as they are not supported.")]
public string IfNoneMatch { get; set; }

[Parameter(
Mandatory = false,
HelpMessage = "Allows customers to enable/opt out of Infiniband network interconnect between RDMA VM sizes.",
ParameterSetName = DefaultParameter)]
[Parameter(
Mandatory = false,
HelpMessage = "Allows customers to enable/opt out of Infiniband network interconnect between RDMA VM sizes.",
ParameterSetName = SimpleParameterSet)]
[ValidateSet("none", "trunk", IgnoreCase = true)]
public string HighSpeedInterconnectPlacement { get; set; }
}
}
Loading