diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj b/src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj index 800230795777..3c97a8597ee6 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj @@ -65,6 +65,8 @@ + + @@ -77,6 +79,13 @@ + + + + + + + diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Compute/ComputeStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Compute/ComputeStrategy.cs new file mode 100644 index 000000000000..db13a0326b6b --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Compute/ComputeStrategy.cs @@ -0,0 +1,24 @@ +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using System; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.Common.Strategies.Compute +{ + public static class ComputePolicy + { + public static ResourceStrategy Create( + string header, + Func getOperations, + Func, Task> getAsync, + Func, Task> createOrUpdateAsync) + where Model : Resource + => ResourceStrategy.Create( + new[] { "Microsoft.Compute", header }, + getOperations, + getAsync, + createOrUpdateAsync, + config => config.Location, + (config, location) => config.Location = location); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Compute/VirtualMachineStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Compute/VirtualMachineStrategy.cs new file mode 100644 index 000000000000..dcd8d3f1ca76 --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Compute/VirtualMachineStrategy.cs @@ -0,0 +1,66 @@ +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.Azure.Management.Network.Models; +using Microsoft.Azure.Management.ResourceManager.Models; + +namespace Microsoft.Azure.Commands.Common.Strategies.Compute +{ + public static class VirtualMachineStrategy + { + public static ResourceStrategy Strategy { get; } + = ComputePolicy.Create( + "virtualMachines", + client => client.VirtualMachines, + p => p.Operations.GetAsync( + p.ResourceGroupName, p.Name, null, p.CancellationToken), + p => p.Operations.CreateOrUpdateAsync( + p.ResourceGroupName, p.Name, p.Model, p.CancellationToken)); + + public static ResourceConfig CreateVirtualMachineConfig( + this ResourceConfig resourceGroup, + string name, + ResourceConfig networkInterface, + string adminUsername, + string adminPassword) + => Strategy.CreateConfig( + resourceGroup, + name, + subscription => new VirtualMachine + { + OsProfile = new OSProfile + { + ComputerName = name, + WindowsConfiguration = new WindowsConfiguration + { + }, + AdminUsername = adminUsername, + AdminPassword = adminPassword, + }, + NetworkProfile = new NetworkProfile + { + NetworkInterfaces = new[] + { + new NetworkInterfaceReference + { + Id = networkInterface.GetId(subscription).IdToString() + } + } + }, + HardwareProfile = new HardwareProfile + { + VmSize = "Standard_DS1_v2" + }, + StorageProfile = new StorageProfile + { + ImageReference = new ImageReference + { + Publisher = "MicrosoftWindowsServer", + Offer = "WindowsServer", + Sku = "2016-Datacenter", + Version = "latest" + } + }, + }, + new[] { networkInterface }); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs b/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs index f7358dd127b6..0b117735638f 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs @@ -30,7 +30,7 @@ public override async Task Visit(ResourceConfig config) } var tasks = config.Dependencies.Select(GetOrAddUntyped); await Task.WhenAll(tasks); - return await config.Policy.CreateOrUpdateAsync(CreateOrUpdateAsyncParams.Create( + return await config.Strategy.CreateOrUpdateAsync(CreateOrUpdateAsyncParams.Create( Client, config.ResourceGroupName, config.Name, diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/GetAsyncOperation.cs b/src/ResourceManager/Common/Commands.Common.Strategies/GetAsyncOperation.cs index 8113e4ac3ca4..be1165efded3 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/GetAsyncOperation.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/GetAsyncOperation.cs @@ -26,7 +26,7 @@ public override async Task Visit(ResourceConfig config) Model info; try { - info = await config.Policy.GetAsync(GetAsyncParams.Create( + info = await config.Strategy.GetAsync(GetAsyncParams.Create( Client, config.ResourceGroupName, config.Name, CancellationToken)); } catch (CloudException e) when (e.Response.StatusCode == HttpStatusCode.NotFound) diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/NestedResourceStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/NestedResourceStrategy.cs index 5351f184731c..98200689ed10 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/NestedResourceStrategy.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/NestedResourceStrategy.cs @@ -22,7 +22,7 @@ public NestedResourceStrategy( } } - public static class NestedResourceStraegy + public static class NestedResourceStrategy { public static NestedResourceStrategy Create( string header, diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkInterfaceStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkInterfaceStrategy.cs new file mode 100644 index 000000000000..bb3013512a0e --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkInterfaceStrategy.cs @@ -0,0 +1,48 @@ +using Microsoft.Azure.Management.Network; +using Microsoft.Azure.Management.Network.Models; +using Microsoft.Azure.Management.ResourceManager.Models; + +namespace Microsoft.Azure.Commands.Common.Strategies.Network +{ + public static class NetworkInterfaceStrategy + { + public static ResourceStrategy Strategy { get; } + = NetworkStrategy.Create( + "networkInterfaces", + client => client.NetworkInterfaces, + p => p.Operations.GetAsync( + p.ResourceGroupName, p.Name, null, p.CancellationToken), + p => p.Operations.CreateOrUpdateAsync( + p.ResourceGroupName, p.Name, p.Model, p.CancellationToken)); + + public static ResourceConfig CreateNetworkInterfaceConfig( + this ResourceConfig resourceGroup, + string name, + NestedResourceConfig subnet, + ResourceConfig publicIPAddress, + ResourceConfig networkSecurityGroup) + => Strategy.CreateConfig( + resourceGroup, + name, + subscription => new NetworkInterface + { + IpConfigurations = new [] + { + new NetworkInterfaceIPConfiguration + { + Name = name, + Subnet = new Subnet { Id = subnet.GetId(subscription).IdToString() }, + PublicIPAddress = new PublicIPAddress + { + Id = publicIPAddress.GetId(subscription).IdToString() + } + } + }, + NetworkSecurityGroup = new NetworkSecurityGroup + { + Id = networkSecurityGroup.GetId(subscription).IdToString() + } + }, + new IResourceConfig[] { subnet, publicIPAddress, networkSecurityGroup }); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkSecurityGroupPolicy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkSecurityGroupPolicy.cs new file mode 100644 index 000000000000..283778b8aebc --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkSecurityGroupPolicy.cs @@ -0,0 +1,22 @@ +using Microsoft.Azure.Management.Network; +using Microsoft.Azure.Management.Network.Models; +using Microsoft.Azure.Management.ResourceManager.Models; + +namespace Microsoft.Azure.Commands.Common.Strategies.Network +{ + public static class NetworkSecurityGroupStrategy + { + public static ResourceStrategy Strategy { get; } + = NetworkStrategy.Create( + "networkSecurityGroups", + client => client.NetworkSecurityGroups, + p => p.Operations.GetAsync( + p.ResourceGroupName, p.Name, null, p.CancellationToken), + p => p.Operations.CreateOrUpdateAsync( + p.ResourceGroupName, p.Name, p.Model, p.CancellationToken)); + + public static ResourceConfig CreateNetworkSecurityGroupConfig( + this ResourceConfig resourceGroup, string name) + => Strategy.CreateConfig(resourceGroup, name); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkStrategy.cs new file mode 100644 index 000000000000..77173431badd --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Network/NetworkStrategy.cs @@ -0,0 +1,24 @@ +using Microsoft.Azure.Management.Network; +using Microsoft.Azure.Management.Network.Models; +using System; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.Common.Strategies.Network +{ + public static class NetworkStrategy + { + public static ResourceStrategy Create( + string header, + Func getOperations, + Func, Task> getAsync, + Func, Task> createOrUpdateAsync) + where Model : Resource + => ResourceStrategy.Create( + new [] { "Microsoft.Network", header }, + getOperations, + getAsync, + createOrUpdateAsync, + model => model.Location, + (model, location) => model.Location = location); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Network/PublicIPAddressStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Network/PublicIPAddressStrategy.cs new file mode 100644 index 000000000000..ee60ff67e42d --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Network/PublicIPAddressStrategy.cs @@ -0,0 +1,22 @@ +using Microsoft.Azure.Management.Network; +using Microsoft.Azure.Management.Network.Models; +using Microsoft.Azure.Management.ResourceManager.Models; + +namespace Microsoft.Azure.Commands.Common.Strategies.Network +{ + public static class PublicIPAddressStrategy + { + public static ResourceStrategy Strategy { get; } + = NetworkStrategy.Create( + "publicIPAddresses", + client => client.PublicIPAddresses, + p => p.Operations.GetAsync( + p.ResourceGroupName, p.Name, null, p.CancellationToken), + p => p.Operations.CreateOrUpdateAsync( + p.ResourceGroupName, p.Name, p.Model, p.CancellationToken)); + + public static ResourceConfig CreatePublicIPAddressConfig( + this ResourceConfig resourceGroup, string name) + => Strategy.CreateConfig(resourceGroup, name); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Network/SubnetStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Network/SubnetStrategy.cs new file mode 100644 index 000000000000..5adbb8491df7 --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Network/SubnetStrategy.cs @@ -0,0 +1,40 @@ +using Microsoft.Azure.Management.Network.Models; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Azure.Commands.Common.Strategies.Network +{ + public static class SubnetPolicy + { + public static NestedResourceStrategy Strategy { get; } + = NestedResourceStrategy.Create( + "subnets", + (vn, name) => vn.Subnets?.FirstOrDefault(s => s.Name == name), + (vn, name, subnet) => + { + subnet.Name = name; + if (vn.Subnets == null) + { + vn.Subnets = new List { subnet }; + return; + } + var s = vn + .Subnets + .Select((sn, i) => new { sn, i }) + .FirstOrDefault(p => p.sn.Name == name); + if (s != null) + { + vn.Subnets[s.i] = subnet; + return; + } + vn.Subnets.Add(subnet); + }); + + public static NestedResourceConfig CreateSubnet( + this ResourceConfig virtualNetwork, string name, string addressPrefix) + => Strategy.CreateConfig( + virtualNetwork, + name, + () => new Subnet { Name = name, AddressPrefix = addressPrefix }); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/Network/VirtualNetworkStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/Network/VirtualNetworkStrategy.cs new file mode 100644 index 000000000000..e7d831e6700f --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Network/VirtualNetworkStrategy.cs @@ -0,0 +1,33 @@ +using Microsoft.Azure.Management.Network; +using Microsoft.Azure.Management.Network.Models; +using Microsoft.Azure.Management.ResourceManager.Models; + +namespace Microsoft.Azure.Commands.Common.Strategies.Network +{ + public static class VirtualNetworkStrategy + { + public static ResourceStrategy Strategy { get; } + = NetworkStrategy.Create( + "virtualNetworks", + client => client.VirtualNetworks, + p => p.Operations.GetAsync( + p.ResourceGroupName, p.Name, null, p.CancellationToken), + p => p.Operations.CreateOrUpdateAsync( + p.ResourceGroupName, p.Name, p.Model, p.CancellationToken)); + + public static ResourceConfig CreateVirtualNetworkConfig( + this ResourceConfig resourceGroup, + string name, + string addressPrefix) + => Strategy.CreateConfig( + resourceGroup, + name, + _ => new VirtualNetwork + { + AddressSpace = new AddressSpace + { + AddressPrefixes = new[] { addressPrefix } + } + }); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/ResourceConfig.cs b/src/ResourceManager/Common/Commands.Common.Strategies/ResourceConfig.cs index b90933d16088..bf54855ead8a 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/ResourceConfig.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/ResourceConfig.cs @@ -8,7 +8,7 @@ namespace Microsoft.Azure.Commands.Common.Strategies public sealed class ResourceConfig : IResourceConfig where Model : class { - public ResourceStrategy Policy { get; } + public ResourceStrategy Strategy { get; } public string ResourceGroupName { get; } @@ -19,13 +19,13 @@ public sealed class ResourceConfig : IResourceConfig public IEnumerable Dependencies { get; } public ResourceConfig( - ResourceStrategy policy, + ResourceStrategy strategy, string resourceGroupName, string name, Func createModel, IEnumerable dependencies) { - Policy = policy; + Strategy = strategy; ResourceGroupName = resourceGroupName; Name = name; CreateModel = createModel; @@ -43,33 +43,33 @@ public IEnumerable GetId(string subscription) "resourceGroups", ResourceGroupName } - .Concat(Policy.GetId(Name)); + .Concat(Strategy.GetId(Name)); } public static class ResourceConfig { public static ResourceConfig CreateConfig( - this ResourceStrategy policy, + this ResourceStrategy strategy, string resourceGroupName, string name, Func createModel = null, IEnumerable dependencies = null) where Model : class, new() => new ResourceConfig( - policy, + strategy, resourceGroupName, name, createModel ?? (_ => new Model()), dependencies.EmptyIfNull()); public static ResourceConfig CreateConfig( - this ResourceStrategy policy, + this ResourceStrategy strategy, ResourceConfig resourceGroup, string name, Func createModel = null, IEnumerable dependencies = null) where Model : class, new() - => policy.CreateConfig( + => strategy.CreateConfig( resourceGroup.Name, name, createModel, diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/ResourceManager/ResourceGroupStrategy.cs b/src/ResourceManager/Common/Commands.Common.Strategies/ResourceManager/ResourceGroupStrategy.cs new file mode 100644 index 000000000000..e37b09802119 --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/ResourceManager/ResourceGroupStrategy.cs @@ -0,0 +1,21 @@ +using Microsoft.Azure.Management.ResourceManager; +using Microsoft.Azure.Management.ResourceManager.Models; +using System.Linq; + +namespace Microsoft.Azure.Commands.Common.Strategies.ResourceManager +{ + public static class ResourceGroupStrategy + { + public static ResourceStrategy Strategy { get; } + = ResourceStrategy.Create( + _ => Enumerable.Empty(), + client => client.ResourceGroups, + p => p.Operations.GetAsync(p.Name, p.CancellationToken), + p => p.Operations.CreateOrUpdateAsync(p.Name, p.Model, p.CancellationToken), + model => model.Location, + (model, location) => model.Location = location); + + public static ResourceConfig CreateResourceGroupConfig(string name) + => Strategy.CreateConfig(name, name); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/StateLocation.cs b/src/ResourceManager/Common/Commands.Common.Strategies/StateLocation.cs index 3038a9c224d7..fcbade5354fb 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/StateLocation.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/StateLocation.cs @@ -49,7 +49,7 @@ public DependencyLocation Visit(ResourceConfig config) var info = State.GetOrNull(config); return info != null ? new DependencyLocation( - config.Policy.GetLocation(info), + config.Strategy.GetLocation(info), typeof(Model) != typeof(ResourceGroup)) : config .Dependencies diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs b/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs index 547d011f2420..a690047ea3d0 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs @@ -36,7 +36,7 @@ public object Visit(ResourceConfig config) GetUntyped(d); } var model = config.CreateModel(Subscription); - config.Policy.SetLocation(model, Location); + config.Strategy.SetLocation(model, Location); return model; } diff --git a/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj b/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj index 48139d011847..120bed9a120a 100644 --- a/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj +++ b/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj @@ -67,6 +67,10 @@ ..\..\..\packages\Microsoft.Azure.Management.Network.14.0.0-preview\lib\net452\Microsoft.Azure.Management.Network.dll True + + ..\..\..\packages\Microsoft.Azure.Management.ResourceManager.1.6.0-preview\lib\net452\Microsoft.Azure.Management.ResourceManager.dll + True + ..\..\..\packages\Microsoft.Azure.Management.Storage.4.1.0-preview\lib\net45\Microsoft.Azure.Management.Storage.dll @@ -82,10 +86,22 @@ ..\..\..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll True + + ..\..\..\packages\Microsoft.Rest.ClientRuntime.2.3.9\lib\net452\Microsoft.Rest.ClientRuntime.dll + True + + + ..\..\..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.9\lib\net452\Microsoft.Rest.ClientRuntime.Azure.dll + True + ..\..\..\packages\WindowsAzure.Storage.8.1.1\lib\net45\Microsoft.WindowsAzure.Storage.dll True + + ..\..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + True + @@ -322,6 +338,10 @@ {5ee72c53-1720-4309-b54b-5fb79703195f} Commands.Common + + {eea69772-d41b-482a-9252-2b4595c59e53} + Commands.Common.Strategies + {3819d8a7-c62c-4c47-8ddd-0332d9ce1252} Commands.ResourceManager.Common diff --git a/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs b/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs index 7dfba7ef301a..c0ab3ff216d2 100644 --- a/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs +++ b/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs @@ -16,6 +16,9 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; +using Microsoft.Azure.Commands.Common.Strategies.Compute; +using Microsoft.Azure.Commands.Common.Strategies.Network; +using Microsoft.Azure.Commands.Common.Strategies.ResourceManager; using Microsoft.Azure.Commands.Compute.Common; using Microsoft.Azure.Commands.Compute.Models; using Microsoft.Azure.Management.Compute; @@ -74,7 +77,56 @@ public class NewAzureVMCommand : VirtualMachineBaseCmdlet [ValidateNotNullOrEmpty] public string LicenseType { get; set; } + public const string StrategyParameterSet = "StrategyParameterSet"; + + [Parameter( + ParameterSetName = StrategyParameterSet, + Mandatory = true)] + public string Name { get; } + + [Parameter( + ParameterSetName = StrategyParameterSet, + Mandatory = false)] + public string AddressPrefix { get; } = "192.168.0.0/16"; + + [Parameter( + ParameterSetName = StrategyParameterSet, + Mandatory = false)] + public string SubnetAddressPrefix { get; } = "192.168.1.0/24"; + + [Parameter(ParameterSetName = StrategyParameterSet, Mandatory = false)] + public PSCredential Credential { get; } + public override void ExecuteCmdlet() + { + switch (ParameterSetName) + { + case StrategyParameterSet: + StrategyExecuteCmdlet(); + break; + default: + DefaultExecuteCmdlet(); + break; + } + } + + public void StrategyExecuteCmdlet() + { + var resourceGroup = ResourceGroupStrategy.CreateResourceGroupConfig(Name); + var virtualNetwork = resourceGroup.CreateVirtualNetworkConfig(Name, AddressPrefix); + var subnet = virtualNetwork.CreateSubnet(Name, SubnetAddressPrefix); + var publicIpAddress = resourceGroup.CreatePublicIPAddressConfig(Name); + var networkSecurityGroup = resourceGroup.CreateNetworkSecurityGroupConfig(Name); + var networkInterface = resourceGroup.CreateNetworkInterfaceConfig( + Name, subnet, publicIpAddress, networkSecurityGroup); + var virtualMachine = resourceGroup.CreateVirtualMachineConfig( + Name, + networkInterface, + Credential.UserName, + new System.Net.NetworkCredential(string.Empty, Credential.Password).Password); + } + + public void DefaultExecuteCmdlet() { base.ExecuteCmdlet(); diff --git a/src/ResourceManager/Compute/Commands.Compute/packages.config b/src/ResourceManager/Compute/Commands.Compute/packages.config index 18f753dc3702..88d9b06ea6c3 100644 --- a/src/ResourceManager/Compute/Commands.Compute/packages.config +++ b/src/ResourceManager/Compute/Commands.Compute/packages.config @@ -4,6 +4,10 @@ + + + + \ No newline at end of file