Skip to content

Commit b5f78c5

Browse files
authored
Merge pull request #5307 from sergey-shandar/sergey-availabilityset
Availability Set for VM simple parameter set
2 parents 10639cc + 6bad558 commit b5f78c5

File tree

8 files changed

+116
-30
lines changed

8 files changed

+116
-30
lines changed

src/ResourceManager/Common/Commands.Common.Strategies/Extensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public static TValue GetOrNull<TKey, TValue>(
3434
this IDictionary<TKey, TValue> dictionary, TKey key)
3535
where TValue : class
3636
{
37+
if (key == null)
38+
{
39+
return null;
40+
}
3741
TValue result;
3842
dictionary.TryGetValue(key, out result);
3943
return result;

src/ResourceManager/Common/Commands.Common.Strategies/GetStateExtensions.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,20 @@ static async Task GetStateAsync<TModel>(
4747
this StateOperationContext context, ResourceConfig<TModel> config)
4848
where TModel : class
4949
=> await context.GetOrAdd(
50-
config,
51-
async () =>
50+
config,
51+
async () =>
52+
{
53+
var info = await config.GetAsync(context.Client, context.CancellationToken);
54+
// Get state of dependencies if the resource doesn't exist
55+
if (info == null)
5256
{
53-
var info = await config.GetAsync(context.Client, context.CancellationToken);
54-
// Get state of dependencies if the resource doesn't exist
55-
if (info == null)
56-
{
57-
var tasks = config
58-
.GetResourceDependencies()
59-
.Select(context.GetStateAsyncDispatch);
60-
await Task.WhenAll(tasks);
61-
}
62-
return info;
63-
});
57+
var tasks = config
58+
.GetResourceDependencies()
59+
.Select(context.GetStateAsyncDispatch);
60+
await Task.WhenAll(tasks);
61+
}
62+
return info;
63+
});
6464

6565
sealed class GetStateAsyncVisitor : IResourceConfigVisitor<StateOperationContext, Task>
6666
{

src/ResourceManager/Common/Commands.Common.Strategies/State.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ readonly ConcurrentDictionary<string, object> _Map
2727

2828
public TModel Get<TModel>(ResourceConfig<TModel> config)
2929
where TModel : class
30-
=> _Map.GetOrNull(config.DefaultIdStr()) as TModel;
30+
=> _Map.GetOrNull(config?.DefaultIdStr()) as TModel;
3131

3232
public TModel GetOrAdd<TModel>(ResourceConfig<TModel> config, Func<TModel> f)
3333
where TModel : class

src/ResourceManager/Compute/ChangeLog.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Additional information about change #1
1919
-->
2020
## Current Release
21+
* Added `AvailabilitySetName` parameter to the simplified parameterset of `New-AzureRmVm`.
2122
* Corrected usage of `Login-AzureRmAccount` to use `Connect-AzureRmAccount`
2223
* User assigned identity support for VM and VM scale set
2324
- IdentityType and IdentityId parameters are added to New-AzureRmVMConfig, New-AzureRmVmssConfig, Update-AzureRmVM and Update-AzureRmVmss
@@ -75,7 +76,7 @@
7576
- New cmdelt: 'Get-AzureRmVmssVMDiskEncryptionStatus' shows the disk encryption status of VMs in a VM scale set
7677

7778
## Version 3.3.1
78-
*
79+
*
7980
## Version 3.3.0
8081
* Set-AzureRmVMAEMExtension: Add support for new Premium Disk sizes
8182
* Set-AzureRmVMAEMExtension: Add support for M series
@@ -92,7 +93,7 @@
9293
- New-AzureRmSnapshot
9394
- Update-AzureRmDisk
9495
- Update-AzureRmSnapshot
95-
96+
9697
## Version 3.2.0
9798
* Storage account type support for Image disk:
9899
- 'StorageAccountType' parameter is added to Set-AzureRmImageOsDisk and Add-AzureRmImageDataDisk

src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@
272272
<Compile Include="StorageServices\StorageCredentialsFactory.cs" />
273273
<Compile Include="Strategies\AsyncCmdletExtensions.cs" />
274274
<Compile Include="Strategies\Client.cs" />
275+
<Compile Include="Strategies\Compute\AvailabilitySetStrategy.cs" />
275276
<Compile Include="Strategies\Compute\ComputeStrategy.cs" />
276277
<Compile Include="Strategies\Compute\Image.cs" />
277278
<Compile Include="Strategies\Compute\Images.cs" />
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Microsoft.Azure.Commands.Common.Strategies;
2+
using Microsoft.Azure.Commands.Common.Strategies.Compute;
3+
using Microsoft.Azure.Commands.Compute.Strategies.ResourceManager;
4+
using Microsoft.Azure.Management.Compute;
5+
using Microsoft.Azure.Management.Compute.Models;
6+
using Microsoft.Azure.Management.Internal.Resources.Models;
7+
8+
namespace Microsoft.Azure.Commands.Compute.Strategies.Compute
9+
{
10+
static class AvailabilitySetStrategy
11+
{
12+
public static ResourceStrategy<AvailabilitySet> Strategy { get; }
13+
= ComputePolicy.Create(
14+
type: "availability set",
15+
provider: "availabilitySets",
16+
getOperations: client => client.AvailabilitySets,
17+
getAsync: (o, p) => o.GetAsync(
18+
p.ResourceGroupName, p.Name, p.CancellationToken),
19+
createOrUpdateAsync: (o, p) => o.CreateOrUpdateAsync(
20+
p.ResourceGroupName, p.Name, p.Model, p.CancellationToken),
21+
createTime: c => 1);
22+
23+
public static ResourceConfig<AvailabilitySet> CreateAvailabilitySetConfig(
24+
this ResourceConfig<ResourceGroup> resourceGroup, string name)
25+
=> Strategy.CreateResourceConfig(
26+
resourceGroup: resourceGroup,
27+
name: name,
28+
createModel: subscription => new AvailabilitySet
29+
{
30+
Sku = new Azure.Management.Compute.Models.Sku { Name = "Aligned" },
31+
PlatformFaultDomainCount = 2,
32+
PlatformUpdateDomainCount = 2,
33+
});
34+
}
35+
}

src/ResourceManager/Compute/Commands.Compute/Strategies/Compute/VirtualMachineStrategy.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ static class VirtualMachineStrategy
3131
p.ResourceGroupName, p.Name, null, p.CancellationToken),
3232
createOrUpdateAsync: (o, p) => o.CreateOrUpdateAsync(
3333
p.ResourceGroupName, p.Name, p.Model, p.CancellationToken),
34-
createTime: c => c != null && c.OsProfile != null && c.OsProfile.WindowsConfiguration != null ? 240 : 120);
34+
createTime: c =>
35+
c != null && c.OsProfile != null && c.OsProfile.WindowsConfiguration != null
36+
? 240
37+
: 120);
3538

3639
public static ResourceConfig<VirtualMachine> CreateVirtualMachineConfig(
3740
this ResourceConfig<ResourceGroup> resourceGroup,
@@ -41,7 +44,8 @@ public static ResourceConfig<VirtualMachine> CreateVirtualMachineConfig(
4144
string adminUsername,
4245
string adminPassword,
4346
Image image,
44-
string size)
47+
string size,
48+
ResourceConfig<AvailabilitySet> availabilitySet)
4549
=> Strategy.CreateResourceConfig(
4650
resourceGroup: resourceGroup,
4751
name: name,
@@ -78,17 +82,24 @@ public static ResourceConfig<VirtualMachine> CreateVirtualMachineConfig(
7882
Sku = image.sku,
7983
Version = image.version
8084
}
81-
}
85+
},
86+
AvailabilitySet = availabilitySet == null
87+
? null
88+
: new Azure.Management.Compute.Models.SubResource
89+
{
90+
Id = availabilitySet.GetId(subscription).IdToString()
91+
}
8292
},
83-
dependencies: new[] { networkInterface });
93+
dependencies: new IResourceConfig[] { networkInterface, availabilitySet });
8494

8595
public static ResourceConfig<VirtualMachine> CreateVirtualMachineConfig(
8696
this ResourceConfig<ResourceGroup> resourceGroup,
8797
string name,
8898
ResourceConfig<NetworkInterface> networkInterface,
8999
bool isWindows,
90100
ResourceConfig<Disk> disk,
91-
string size)
101+
string size,
102+
ResourceConfig<AvailabilitySet> availabilitySet)
92103
=> Strategy.CreateResourceConfig(
93104
resourceGroup: resourceGroup,
94105
name: name,
@@ -123,7 +134,13 @@ public static ResourceConfig<VirtualMachine> CreateVirtualMachineConfig(
123134
}
124135
}
125136
},
137+
AvailabilitySet = availabilitySet == null
138+
? null
139+
: new Azure.Management.Compute.Models.SubResource
140+
{
141+
Id = availabilitySet.GetId(subscription).IdToString()
142+
}
126143
},
127-
dependencies: new IEntityConfig[] { networkInterface, disk });
144+
dependencies: new IEntityConfig[] { networkInterface, disk, availabilitySet });
128145
}
129146
}

src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
using Microsoft.Azure.Commands.Compute.Models;
2424
using Microsoft.Azure.Commands.Compute.StorageServices;
2525
using Microsoft.Azure.Commands.Compute.Strategies;
26+
using Microsoft.Azure.Commands.Compute.Strategies.Compute;
2627
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2728
using Microsoft.Azure.Management.Compute;
2829
using Microsoft.Azure.Management.Compute.Models;
2930
using Microsoft.Azure.Management.Storage;
3031
using Microsoft.Azure.Management.Storage.Models;
32+
using Microsoft.Rest.Azure;
3133
using Microsoft.WindowsAzure.Commands.Sync.Download;
3234
using Microsoft.WindowsAzure.Commands.Tools.Vhd;
3335
using Microsoft.WindowsAzure.Commands.Tools.Vhd.Model;
@@ -201,6 +203,10 @@ public class NewAzureVMCommand : VirtualMachineBaseCmdlet
201203
[Parameter(ParameterSetName = DiskFileParameterSet, Mandatory = false)]
202204
public string Size { get; set; } = "Standard_DS1_v2";
203205

206+
[Parameter(ParameterSetName = SimpleParameterSet, Mandatory = false)]
207+
[Parameter(ParameterSetName = DiskFileParameterSet, Mandatory = false)]
208+
public string AvailabilitySetName { get; set; }
209+
204210
[Parameter(Mandatory = false, HelpMessage = "Run cmdlet in the background")]
205211
public SwitchParameter AsJob { get; set; }
206212

@@ -285,8 +291,12 @@ async Task StrategyExecuteCmdletAsync(IAsyncCmdlet asyncCmdlet)
285291
openPorts: OpenPorts);
286292
var networkInterface = resourceGroup.CreateNetworkInterfaceConfig(
287293
Name, subnet, publicIpAddress, networkSecurityGroup);
288-
ResourceConfig<VirtualMachine> virtualMachine = null;
289294

295+
var availabilitySet = AvailabilitySetName == null
296+
? null
297+
: resourceGroup.CreateAvailabilitySetConfig(name: Name);
298+
299+
ResourceConfig<VirtualMachine> virtualMachine = null;
290300
if (image != null)
291301
{
292302
virtualMachine = resourceGroup.CreateVirtualMachineConfig(
@@ -296,7 +306,8 @@ async Task StrategyExecuteCmdletAsync(IAsyncCmdlet asyncCmdlet)
296306
adminUsername: Credential.UserName,
297307
adminPassword: new NetworkCredential(string.Empty, Credential.Password).Password,
298308
image: image,
299-
size: Size);
309+
size: Size,
310+
availabilitySet: availabilitySet);
300311
}
301312
else
302313
{
@@ -325,24 +336,35 @@ async Task StrategyExecuteCmdletAsync(IAsyncCmdlet asyncCmdlet)
325336
Math.DivRem(filePath.Length, divisor, out rem);
326337
if (rem != 0)
327338
{
328-
throw new ArgumentOutOfRangeException("filePath", string.Format("Given vhd file '{0}' is a corrupted fixed vhd", filePath));
339+
throw new ArgumentOutOfRangeException(
340+
"filePath",
341+
string.Format("Given vhd file '{0}' is a corrupted fixed vhd", filePath));
329342
}
330343
}
331344
}
332345
var storageAccount = storageClient.StorageAccounts.GetProperties(ResourceGroupName, Name);
333346
BlobUri destinationUri = null;
334-
BlobUri.TryParseUri(new Uri(string.Format("{0}{1}/{2}{3}", storageAccount.PrimaryEndpoints.Blob, Name.ToLower(), Name.ToLower(), ".vhd")), out destinationUri);
347+
BlobUri.TryParseUri(
348+
new Uri(string.Format(
349+
"{0}{1}/{2}{3}",
350+
storageAccount.PrimaryEndpoints.Blob,
351+
Name.ToLower(),
352+
Name.ToLower(),
353+
".vhd")),
354+
out destinationUri);
335355
if (destinationUri == null || destinationUri.Uri == null)
336356
{
337357
throw new ArgumentNullException("destinationUri");
338358
}
339-
var storageCredentialsFactory = new StorageCredentialsFactory(this.ResourceGroupName, storageClient, DefaultContext.Subscription);
359+
var storageCredentialsFactory = new StorageCredentialsFactory(
360+
this.ResourceGroupName, storageClient, DefaultContext.Subscription);
340361
var parameters = new UploadParameters(destinationUri, null, filePath, true, 2)
341362
{
342363
Cmdlet = this,
343364
BlobObjectFactory = new CloudPageBlobObjectFactory(storageCredentialsFactory, TimeSpan.FromMinutes(1))
344365
};
345-
if (!string.Equals(Environment.GetEnvironmentVariable("AZURE_TEST_MODE"), "Playback", StringComparison.OrdinalIgnoreCase))
366+
if (!string.Equals(
367+
Environment.GetEnvironmentVariable("AZURE_TEST_MODE"), "Playback", StringComparison.OrdinalIgnoreCase))
346368
{
347369
var st2 = VhdUploaderModel.Upload(parameters);
348370
}
@@ -355,7 +377,8 @@ async Task StrategyExecuteCmdletAsync(IAsyncCmdlet asyncCmdlet)
355377
networkInterface: networkInterface,
356378
isWindows: isWindows,
357379
disk: disk,
358-
size: Size);
380+
size: Size,
381+
availabilitySet: availabilitySet);
359382
}
360383

361384
var client = new Client(DefaultProfile.DefaultContext);
@@ -375,7 +398,12 @@ async Task StrategyExecuteCmdletAsync(IAsyncCmdlet asyncCmdlet)
375398
var fqdn = DomainNameLabel + "." + Location + ".cloudapp.azure.com";
376399

377400
// create target state
378-
var target = virtualMachine.GetTargetState(current, client.SubscriptionId, Location);
401+
var target = virtualMachine.GetTargetState(current, client.SubscriptionId, Location);
402+
403+
if (target.Get(availabilitySet) != null)
404+
{
405+
throw new InvalidOperationException("Availability set doesn't exist.");
406+
}
379407

380408
// apply target state
381409
var newState = await virtualMachine

0 commit comments

Comments
 (0)