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 71f943516a41..3401e0bbe1be 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj +++ b/src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj @@ -76,6 +76,7 @@ + diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs b/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs index 778e53351e7c..43a1d254a1d2 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs @@ -19,12 +19,11 @@ public static class CreateOrUpdateAsyncOperation public static async Task CreateOrUpdateAsync( this IResourceConfig config, IClient client, - IState current, IState target, CancellationToken cancellationToken) where Model : class { - var visitor = new CreateAsyncVisitor(client, current, target, cancellationToken); + var visitor = new CreateAsyncVisitor(client, target, cancellationToken); await visitor.GetOrAdd(config); return visitor.Result; } @@ -33,10 +32,10 @@ sealed class CreateAsyncVisitor : AsyncOperationVisitor { public override async Task Visit(ResourceConfig config) { - var current = Current.GetOrNull(config); - if (current != null) + var target = Target.GetOrNull(config); + if (target == null) { - return current; + return null; } var tasks = config.Dependencies.Select(GetOrAddUntyped); await Task.WhenAll(tasks); @@ -52,22 +51,23 @@ public override async Task Visit(ResourceConfig config) public override async Task Visit( NestedResourceConfig config) { + var target = Target.GetOrNull(config); + if (target == null) + { + return null; + } var parent = await GetOrAdd(config.Parent); return config.Policy.Get(parent, config.Name); } public CreateAsyncVisitor( IClient client, - IState current, IState target, CancellationToken cancellationToken) : base(client, cancellationToken) { - Current = current; Target = target; } - - IState Current { get; } IState Target { get; } } diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/IReport.cs b/src/ResourceManager/Common/Commands.Common.Strategies/IReport.cs new file mode 100644 index 000000000000..02a5740fadbc --- /dev/null +++ b/src/ResourceManager/Common/Commands.Common.Strategies/IReport.cs @@ -0,0 +1,8 @@ +namespace Microsoft.Azure.Commands.Common.Strategies +{ + public interface IReport + { + void Start(IResourceConfig config); + void Done(IResourceConfig config); + } +} diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/IState.cs b/src/ResourceManager/Common/Commands.Common.Strategies/IState.cs index 58385a09afeb..2a2bcfd93d19 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/IState.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/IState.cs @@ -7,5 +7,7 @@ public interface IState { Model GetOrNull(IResourceConfig config) where Model : class; + + object GetOrNullUntyped(IResourceConfig config); } } diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/State.cs b/src/ResourceManager/Common/Commands.Common.Strategies/State.cs index e3c7a3dd5187..f55f816a41a3 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/State.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/State.cs @@ -5,9 +5,12 @@ namespace Microsoft.Azure.Commands.Common.Strategies { sealed class State : IState { + public object GetOrNullUntyped(IResourceConfig config) + => Map.GetOrNull(config.DefaultIdStr()); + public Model GetOrNull(IResourceConfig config) where Model : class - => Map.GetOrNull(config.DefaultIdStr()) as Model; + => GetOrNullUntyped(config) as Model; public Model GetOrAdd(IResourceConfig config, Func f) where Model : class diff --git a/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs b/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs index a690047ea3d0..a1c0693f4004 100644 --- a/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs +++ b/src/ResourceManager/Common/Commands.Common.Strategies/TargetState.cs @@ -1,22 +1,30 @@ -namespace Microsoft.Azure.Commands.Common.Strategies +using System.Linq; + +namespace Microsoft.Azure.Commands.Common.Strategies { public static class TargetState { public static IState GetTargetState( this IResourceConfig config, + IState current, string subscription, string location) where Model : class { - var visitor = new Visitor(subscription, location); - visitor.Get(config); + var visitor = new Visitor(current, subscription, location); + // create a target model onyl if the resource doesn't exist. + if (current.GetOrNull(config) == null) + { + visitor.Get(config); + } return visitor.Result; } sealed class Visitor : IResourceConfigVisitor { - public Visitor(string subscription, string location) + public Visitor(IState current, string subscription, string location) { + Current = current; Subscription = subscription; Location = location; } @@ -28,10 +36,13 @@ public Model Get(IResourceConfig config) where Model : class => GetUntyped(config) as Model; - public object Visit(ResourceConfig config) + public object Visit(ResourceConfig config) where Model : class { - foreach (var d in config.Dependencies) + // create a dependency target model only if the dependency resource doesn't exist. + foreach (var d in config + .Dependencies + .Where(d => Current.GetOrNullUntyped(d) == null)) { GetUntyped(d); } @@ -54,6 +65,8 @@ public object Visit( string Location { get; } + IState Current { get; } + public State Result { get; } = new State(); } } diff --git a/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs b/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs index 34656152d7fd..ad1d9dc1ce73 100644 --- a/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs +++ b/src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs @@ -181,23 +181,23 @@ public void StrategyExecuteCmdlet() // var client = new Client(DefaultProfile.DefaultContext); - var state = virtualMachine + var current = virtualMachine .GetAsync(client, new CancellationToken()) .GetAwaiter() .GetResult(); if (Location == null) { - Location = state.GetLocation(virtualMachine); + Location = current.GetLocation(virtualMachine); if (Location == null) { Location = "eastus"; } } - var target = virtualMachine.GetTargetState(client.SubscriptionId, Location); + var target = virtualMachine.GetTargetState(current, client.SubscriptionId, Location); var result = virtualMachine - .CreateOrUpdateAsync(client, state, target, new CancellationToken()) + .CreateOrUpdateAsync(client, target, new CancellationToken()) .GetAwaiter() .GetResult(); }