Skip to content

Commit 57925fc

Browse files
authored
Merge pull request #7134 from chidmdxx/preview
Add Rollback option to resource group level resources
2 parents e1d5ab1 + faaa4f9 commit 57925fc

File tree

14 files changed

+306
-40
lines changed

14 files changed

+306
-40
lines changed

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Implementation/ResourceGroupDeployments/NewAzureResourceGroupDeploymentCmdlet.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using ProjectResources = Microsoft.Azure.Commands.ResourceManager.Cmdlets.Properties.Resources;
1919
using System.Management.Automation;
2020
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
21+
using System;
2122

2223
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation
2324
{
@@ -45,6 +46,12 @@ public class NewAzureResourceGroupDeploymentCmdlet : ResourceWithParameterCmdlet
4546
[ValidateSet("RequestContent", "ResponseContent", "All", "None", IgnoreCase = true)]
4647
public string DeploymentDebugLogLevel { get; set; }
4748

49+
[Parameter(Mandatory = false, HelpMessage = "Rollback to the last successful deployment in the resource group, should not be present if -RollBackDeploymentName is used.")]
50+
public SwitchParameter RollbackToLastDeployment { get; set; }
51+
52+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "Rollback to the successful deployment with the given name in the resource group, should not be used if -RollbackToLastDeployment is used.")]
53+
public string RollBackDeploymentName { get; set; }
54+
4855
[Parameter(Mandatory = false, HelpMessage = "Do not ask for confirmation.")]
4956
public SwitchParameter Force { get; set; }
5057

@@ -66,6 +73,11 @@ public override void ExecuteCmdlet()
6673
ResourceGroupName,
6774
() =>
6875
{
76+
if (RollbackToLastDeployment && !string.IsNullOrEmpty(RollBackDeploymentName))
77+
{
78+
WriteExceptionError(new ArgumentException(ProjectResources.InvalidRollbackParameters));
79+
}
80+
6981
var parameters = new PSDeploymentCmdletParameters()
7082
{
7183
ResourceGroupName = ResourceGroupName,
@@ -74,7 +86,14 @@ public override void ExecuteCmdlet()
7486
TemplateFile = TemplateUri ?? this.TryResolvePath(TemplateFile),
7587
TemplateParameterObject = GetTemplateParameterObject(TemplateParameterObject),
7688
ParameterUri = TemplateParameterUri,
77-
DeploymentDebugLogLevel = GetDeploymentDebugLogLevel(DeploymentDebugLogLevel)
89+
DeploymentDebugLogLevel = GetDeploymentDebugLogLevel(DeploymentDebugLogLevel),
90+
OnErrorDeployment = RollbackToLastDeployment || !string.IsNullOrEmpty(RollBackDeploymentName)
91+
? new OnErrorDeployment
92+
{
93+
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
94+
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
95+
}
96+
: null
7897
};
7998

8099
if (!string.IsNullOrEmpty(parameters.DeploymentDebugLogLevel))

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Implementation/ResourceGroupDeployments/TestAzureResourceGroupDeploymentCmdlet.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
1717
using Microsoft.Azure.Management.ResourceManager.Models;
1818
using Microsoft.WindowsAzure.Commands.Utilities.Common;
19+
using ProjectResources = Microsoft.Azure.Commands.ResourceManager.Cmdlets.Properties.Resources;
20+
using System;
1921
using System.Collections.Generic;
2022
using System.Management.Automation;
2123

@@ -35,19 +37,37 @@ public class TestAzureResourceGroupDeploymentCmdlet : ResourceWithParameterCmdle
3537
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The deployment mode.")]
3638
public DeploymentMode Mode { get; set; }
3739

40+
[Parameter(Mandatory = false, HelpMessage = "Rollback to the last successful deployment in the resource group, should not be present if -RollBackDeploymentName is used.")]
41+
public SwitchParameter RollbackToLastDeployment { get; set; }
42+
43+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "Rollback to the successful deployment with the given name in the resource group, should not be used if -RollbackToLastDeployment is used.")]
44+
public string RollBackDeploymentName { get; set; }
45+
3846
public TestAzureResourceGroupDeploymentCmdlet()
3947
{
4048
this.Mode = DeploymentMode.Incremental;
4149
}
4250

4351
public override void ExecuteCmdlet()
4452
{
53+
if (RollbackToLastDeployment && !string.IsNullOrEmpty(RollBackDeploymentName))
54+
{
55+
WriteExceptionError(new ArgumentException(ProjectResources.InvalidRollbackParameters));
56+
}
57+
4558
PSDeploymentCmdletParameters parameters = new PSDeploymentCmdletParameters()
4659
{
4760
ResourceGroupName = ResourceGroupName,
4861
TemplateFile = TemplateUri ?? this.TryResolvePath(TemplateFile),
4962
TemplateParameterObject = GetTemplateParameterObject(TemplateParameterObject),
50-
ParameterUri = TemplateParameterUri
63+
ParameterUri = TemplateParameterUri,
64+
OnErrorDeployment = RollbackToLastDeployment || !string.IsNullOrEmpty(RollBackDeploymentName)
65+
? new OnErrorDeployment
66+
{
67+
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
68+
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
69+
}
70+
: null
5171
};
5272

5373
WriteObject(ResourceManagerSdkClient.ValidateDeployment(parameters, Mode));

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Properties/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@
357357
<data name="WarnOnDeploymentDebugSetting" xml:space="preserve">
358358
<value>The DeploymentDebug setting has been enabled. This can potentially log secrets like passwords used in resource property or listKeys operations when you retrieve the deployment operations through Get-AzureRmResourceGroupDeploymentOperation</value>
359359
</data>
360+
<data name="InvalidRollbackParameters" xml:space="preserve">
361+
<value>The paramater -RollbackToLastDeployment and -RollBackDeploymentName can't be defined at the same time.</value>
362+
</data>
360363
<data name="CheckingDeploymentStatus" xml:space="preserve">
361364
<value>Checking deployment status in {0} seconds</value>
362365
</data>

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/SdkClient/ResourceManagerSdkClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ private Deployment CreateBasicDeployment(PSDeploymentCmdletParameters parameters
450450
}
451451

452452
deployment.Location = parameters.Location;
453+
deployment.Properties.OnErrorDeployment = parameters.OnErrorDeployment;
453454

454455
return deployment;
455456
}

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/SdkModels/Deployments/PSDeploymentCmdletParameters.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,7 @@ public class PSDeploymentCmdletParameters
2525
public string ParameterUri { get; set; }
2626

2727
public string DeploymentDebugLogLevel { get; set; }
28+
29+
public OnErrorDeployment OnErrorDeployment { get; set; }
2830
}
2931
}

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/SdkModels/Deployments/PSResourceGroupDeployment.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels
2222
public class PSResourceGroupDeployment: PSDeploymentObject
2323
{
2424
public string ResourceGroupName { get; set; }
25+
26+
public OnErrorDeploymentExtended OnErrorDeployment { get; set; }
2527
}
2628
}

src/ResourceManager/Resources/Commands.Resources.Test/ResourceGroupDeployments/NewAzureResourceGroupDeploymentCommandTests.cs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public class NewAzureResourceGroupDeploymentCommandTests : RMTestBase
4242

4343
private string deploymentName = "fooDeployment";
4444

45+
private string lastDeploymentName = "oldfooDeployment";
46+
4547
private string templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\sampleTemplateFile.json");
4648

4749
public NewAzureResourceGroupDeploymentCommandTests(ITestOutputHelper output)
@@ -107,6 +109,139 @@ public void CreatesNewPSResourceGroupDeploymentWithUserTemplate()
107109
Assert.Equal(expectedParameters.DeploymentName, actualParameters.DeploymentName);
108110
Assert.Equal(expectedParameters.TemplateFile, actualParameters.TemplateFile);
109111
Assert.NotNull(actualParameters.TemplateParameterObject);
112+
Assert.Null(actualParameters.OnErrorDeployment);
113+
114+
commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Once());
115+
}
116+
117+
[Fact]
118+
[Trait(Category.AcceptanceType, Category.CheckIn)]
119+
public void CreatesNewPSResourceGroupDeploymentWithUserTemplateSpecificRollback()
120+
{
121+
PSDeploymentCmdletParameters expectedParameters = new PSDeploymentCmdletParameters()
122+
{
123+
TemplateFile = templateFile,
124+
DeploymentName = deploymentName,
125+
OnErrorDeployment = new OnErrorDeployment
126+
{
127+
Type = OnErrorDeploymentType.SpecificDeployment,
128+
DeploymentName = lastDeploymentName
129+
}
130+
};
131+
PSDeploymentCmdletParameters actualParameters = new PSDeploymentCmdletParameters();
132+
PSResourceGroupDeployment expected = new PSResourceGroupDeployment()
133+
{
134+
Mode = DeploymentMode.Incremental,
135+
DeploymentName = deploymentName,
136+
CorrelationId = "123",
137+
Outputs = new Dictionary<string, DeploymentVariable>()
138+
{
139+
{ "Variable1", new DeploymentVariable() { Value = "true", Type = "bool" } },
140+
{ "Variable2", new DeploymentVariable() { Value = "10", Type = "int" } },
141+
{ "Variable3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
142+
},
143+
Parameters = new Dictionary<string, DeploymentVariable>()
144+
{
145+
{ "Parameter1", new DeploymentVariable() { Value = "true", Type = "bool" } },
146+
{ "Parameter2", new DeploymentVariable() { Value = "10", Type = "int" } },
147+
{ "Parameter3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
148+
},
149+
ProvisioningState = ProvisioningState.Succeeded.ToString(),
150+
ResourceGroupName = resourceGroupName,
151+
TemplateLink = new TemplateLink()
152+
{
153+
ContentVersion = "1.0",
154+
Uri = "http://mytemplate.com"
155+
},
156+
Timestamp = new DateTime(2014, 2, 13),
157+
OnErrorDeployment = new OnErrorDeploymentExtended
158+
{
159+
Type = OnErrorDeploymentType.SpecificDeployment,
160+
DeploymentName = lastDeploymentName
161+
}
162+
};
163+
resourcesClientMock.Setup(f => f.ExecuteDeployment(
164+
It.IsAny<PSDeploymentCmdletParameters>()))
165+
.Returns(expected)
166+
.Callback((PSDeploymentCmdletParameters p) => { actualParameters = p; });
167+
168+
cmdlet.ResourceGroupName = resourceGroupName;
169+
cmdlet.Name = expectedParameters.DeploymentName;
170+
cmdlet.TemplateFile = expectedParameters.TemplateFile;
171+
cmdlet.RollBackDeploymentName = lastDeploymentName;
172+
cmdlet.ExecuteCmdlet();
173+
174+
Assert.Equal(expectedParameters.DeploymentName, actualParameters.DeploymentName);
175+
Assert.Equal(expectedParameters.TemplateFile, actualParameters.TemplateFile);
176+
Assert.NotNull(actualParameters.TemplateParameterObject);
177+
Assert.NotNull(actualParameters.OnErrorDeployment);
178+
Assert.Equal(expectedParameters.OnErrorDeployment.Type, actualParameters.OnErrorDeployment.Type);
179+
Assert.Equal(expectedParameters.OnErrorDeployment.DeploymentName, actualParameters.OnErrorDeployment.DeploymentName);
180+
181+
commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Once());
182+
}
183+
184+
[Fact]
185+
[Trait(Category.AcceptanceType, Category.CheckIn)]
186+
public void CreatesNewPSResourceGroupDeploymentWithUserTemplateEmptyRollback()
187+
{
188+
PSDeploymentCmdletParameters expectedParameters = new PSDeploymentCmdletParameters()
189+
{
190+
TemplateFile = templateFile,
191+
DeploymentName = deploymentName,
192+
OnErrorDeployment = new OnErrorDeployment
193+
{
194+
Type = OnErrorDeploymentType.LastSuccessful,
195+
}
196+
};
197+
PSDeploymentCmdletParameters actualParameters = new PSDeploymentCmdletParameters();
198+
PSResourceGroupDeployment expected = new PSResourceGroupDeployment()
199+
{
200+
Mode = DeploymentMode.Incremental,
201+
DeploymentName = deploymentName,
202+
CorrelationId = "123",
203+
Outputs = new Dictionary<string, DeploymentVariable>()
204+
{
205+
{ "Variable1", new DeploymentVariable() { Value = "true", Type = "bool" } },
206+
{ "Variable2", new DeploymentVariable() { Value = "10", Type = "int" } },
207+
{ "Variable3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
208+
},
209+
Parameters = new Dictionary<string, DeploymentVariable>()
210+
{
211+
{ "Parameter1", new DeploymentVariable() { Value = "true", Type = "bool" } },
212+
{ "Parameter2", new DeploymentVariable() { Value = "10", Type = "int" } },
213+
{ "Parameter3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
214+
},
215+
ProvisioningState = ProvisioningState.Succeeded.ToString(),
216+
ResourceGroupName = resourceGroupName,
217+
TemplateLink = new TemplateLink()
218+
{
219+
ContentVersion = "1.0",
220+
Uri = "http://mytemplate.com"
221+
},
222+
Timestamp = new DateTime(2014, 2, 13),
223+
OnErrorDeployment = new OnErrorDeploymentExtended
224+
{
225+
Type = OnErrorDeploymentType.LastSuccessful,
226+
}
227+
};
228+
resourcesClientMock.Setup(f => f.ExecuteDeployment(
229+
It.IsAny<PSDeploymentCmdletParameters>()))
230+
.Returns(expected)
231+
.Callback((PSDeploymentCmdletParameters p) => { actualParameters = p; });
232+
233+
cmdlet.ResourceGroupName = resourceGroupName;
234+
cmdlet.Name = expectedParameters.DeploymentName;
235+
cmdlet.TemplateFile = expectedParameters.TemplateFile;
236+
cmdlet.RollbackToLastDeployment = true;
237+
cmdlet.ExecuteCmdlet();
238+
239+
Assert.Equal(expectedParameters.DeploymentName, actualParameters.DeploymentName);
240+
Assert.Equal(expectedParameters.TemplateFile, actualParameters.TemplateFile);
241+
Assert.NotNull(actualParameters.TemplateParameterObject);
242+
Assert.NotNull(actualParameters.OnErrorDeployment);
243+
Assert.Equal(expectedParameters.OnErrorDeployment.Type, actualParameters.OnErrorDeployment.Type);
244+
Assert.Equal(expectedParameters.OnErrorDeployment.DeploymentName, actualParameters.OnErrorDeployment.DeploymentName);
110245

111246
commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Once());
112247
}

src/ResourceManager/Resources/Commands.Resources/ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
- Additional information about change #1
1919
-->
2020
## Current Release
21+
* Update New-AzureRmResourceGroupDeployment with new parameter RollbackAction
22+
- Add support for OnErrorDeployment with the new parameter.
2123
* Support managed identity on policy assignments.
2224
* Parameters with default values are no longer requred when assigning a policy with `New-AzureRmPolicyAssignment`
2325
* Add new cmdlet Get-AzureRmPolicyAlias for retrieving policy aliases

src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/PSResourceGroupDeployment.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@ public string OutputsString
5252
{
5353
get { return ResourcesExtensions.ConstructDeploymentVariableTable(Outputs); }
5454
}
55+
56+
public OnErrorDeploymentExtended OnErrorDeployment { get; set; }
5557
}
5658
}

src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/ResourcesExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ private static PSResourceGroupDeployment CreatePSResourceGroupDeployment(
230230
deploymentObject.ProvisioningState = properties.ProvisioningState;
231231
deploymentObject.TemplateLink = properties.TemplateLink;
232232
deploymentObject.CorrelationId = properties.CorrelationId;
233+
deploymentObject.OnErrorDeployment = properties.OnErrorDeployment;
233234

234235
if (properties.DebugSetting() != null && !string.IsNullOrEmpty(properties.DebugSetting().DetailLevel()))
235236
{

0 commit comments

Comments
 (0)