Skip to content

Add Rollback option to resource group level resources #7134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 13, 2018
Merged
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 @@ -18,6 +18,7 @@
using ProjectResources = Microsoft.Azure.Commands.ResourceManager.Cmdlets.Properties.Resources;
using System.Management.Automation;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using System;

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

[Parameter(Mandatory = false, HelpMessage = "Rollback to the last successful deployment in the resource group, should not be present if -RollBackDeploymentName is used.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these need to be in separate parameter sets - any parameter that is not in any parameter set is in all parameter sets. I can put a PR into your branch to show how this is done.

public SwitchParameter RollbackToLastDeployment { get; set; }

[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.")]
public string RollBackDeploymentName { get; set; }

[Parameter(Mandatory = false, HelpMessage = "Do not ask for confirmation.")]
public SwitchParameter Force { get; set; }

Expand All @@ -66,6 +73,11 @@ public override void ExecuteCmdlet()
ResourceGroupName,
() =>
{
if (RollbackToLastDeployment && !string.IsNullOrEmpty(RollBackDeploymentName))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, we shoudl do this with parameter sets,

{
WriteExceptionError(new ArgumentException(ProjectResources.InvalidRollbackParameters));
}

var parameters = new PSDeploymentCmdletParameters()
{
ResourceGroupName = ResourceGroupName,
Expand All @@ -74,7 +86,14 @@ public override void ExecuteCmdlet()
TemplateFile = TemplateUri ?? this.TryResolvePath(TemplateFile),
TemplateParameterObject = GetTemplateParameterObject(TemplateParameterObject),
ParameterUri = TemplateParameterUri,
DeploymentDebugLogLevel = GetDeploymentDebugLogLevel(DeploymentDebugLogLevel)
DeploymentDebugLogLevel = GetDeploymentDebugLogLevel(DeploymentDebugLogLevel),
OnErrorDeployment = RollbackToLastDeployment || !string.IsNullOrEmpty(RollBackDeploymentName)
? new OnErrorDeployment
{
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
}
: null
};

if (!string.IsNullOrEmpty(parameters.DeploymentDebugLogLevel))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.ResourceManager.Models;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using ProjectResources = Microsoft.Azure.Commands.ResourceManager.Cmdlets.Properties.Resources;
using System;
using System.Collections.Generic;
using System.Management.Automation;

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

[Parameter(Mandatory = false, HelpMessage = "Rollback to the last successful deployment in the resource group, should not be present if -RollBackDeploymentName is used.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment

public SwitchParameter RollbackToLastDeployment { get; set; }

[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.")]
public string RollBackDeploymentName { get; set; }

public TestAzureResourceGroupDeploymentCmdlet()
{
this.Mode = DeploymentMode.Incremental;
}

public override void ExecuteCmdlet()
{
if (RollbackToLastDeployment && !string.IsNullOrEmpty(RollBackDeploymentName))
{
WriteExceptionError(new ArgumentException(ProjectResources.InvalidRollbackParameters));
}

PSDeploymentCmdletParameters parameters = new PSDeploymentCmdletParameters()
{
ResourceGroupName = ResourceGroupName,
TemplateFile = TemplateUri ?? this.TryResolvePath(TemplateFile),
TemplateParameterObject = GetTemplateParameterObject(TemplateParameterObject),
ParameterUri = TemplateParameterUri
ParameterUri = TemplateParameterUri,
OnErrorDeployment = RollbackToLastDeployment || !string.IsNullOrEmpty(RollBackDeploymentName)
? new OnErrorDeployment
{
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
}
: null
};

WriteObject(ResourceManagerSdkClient.ValidateDeployment(parameters, Mode));
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@
<data name="WarnOnDeploymentDebugSetting" xml:space="preserve">
<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>
</data>
<data name="InvalidRollbackParameters" xml:space="preserve">
<value>The paramater -RollbackToLastDeployment and -RollBackDeploymentName can't be defined at the same time.</value>
</data>
<data name="CheckingDeploymentStatus" xml:space="preserve">
<value>Checking deployment status in {0} seconds</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ private Deployment CreateBasicDeployment(PSDeploymentCmdletParameters parameters
}

deployment.Location = parameters.Location;
deployment.Properties.OnErrorDeployment = parameters.OnErrorDeployment;

return deployment;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ public class PSDeploymentCmdletParameters
public string ParameterUri { get; set; }

public string DeploymentDebugLogLevel { get; set; }

public OnErrorDeployment OnErrorDeployment { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels
public class PSResourceGroupDeployment: PSDeploymentObject
{
public string ResourceGroupName { get; set; }

public OnErrorDeploymentExtended OnErrorDeployment { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class NewAzureResourceGroupDeploymentCommandTests : RMTestBase

private string deploymentName = "fooDeployment";

private string lastDeploymentName = "oldfooDeployment";

private string templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\sampleTemplateFile.json");

public NewAzureResourceGroupDeploymentCommandTests(ITestOutputHelper output)
Expand Down Expand Up @@ -107,6 +109,139 @@ public void CreatesNewPSResourceGroupDeploymentWithUserTemplate()
Assert.Equal(expectedParameters.DeploymentName, actualParameters.DeploymentName);
Assert.Equal(expectedParameters.TemplateFile, actualParameters.TemplateFile);
Assert.NotNull(actualParameters.TemplateParameterObject);
Assert.Null(actualParameters.OnErrorDeployment);

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

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void CreatesNewPSResourceGroupDeploymentWithUserTemplateSpecificRollback()
{
PSDeploymentCmdletParameters expectedParameters = new PSDeploymentCmdletParameters()
{
TemplateFile = templateFile,
DeploymentName = deploymentName,
OnErrorDeployment = new OnErrorDeployment
{
Type = OnErrorDeploymentType.SpecificDeployment,
DeploymentName = lastDeploymentName
}
};
PSDeploymentCmdletParameters actualParameters = new PSDeploymentCmdletParameters();
PSResourceGroupDeployment expected = new PSResourceGroupDeployment()
{
Mode = DeploymentMode.Incremental,
DeploymentName = deploymentName,
CorrelationId = "123",
Outputs = new Dictionary<string, DeploymentVariable>()
{
{ "Variable1", new DeploymentVariable() { Value = "true", Type = "bool" } },
{ "Variable2", new DeploymentVariable() { Value = "10", Type = "int" } },
{ "Variable3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
},
Parameters = new Dictionary<string, DeploymentVariable>()
{
{ "Parameter1", new DeploymentVariable() { Value = "true", Type = "bool" } },
{ "Parameter2", new DeploymentVariable() { Value = "10", Type = "int" } },
{ "Parameter3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
},
ProvisioningState = ProvisioningState.Succeeded.ToString(),
ResourceGroupName = resourceGroupName,
TemplateLink = new TemplateLink()
{
ContentVersion = "1.0",
Uri = "http://mytemplate.com"
},
Timestamp = new DateTime(2014, 2, 13),
OnErrorDeployment = new OnErrorDeploymentExtended
{
Type = OnErrorDeploymentType.SpecificDeployment,
DeploymentName = lastDeploymentName
}
};
resourcesClientMock.Setup(f => f.ExecuteDeployment(
It.IsAny<PSDeploymentCmdletParameters>()))
.Returns(expected)
.Callback((PSDeploymentCmdletParameters p) => { actualParameters = p; });

cmdlet.ResourceGroupName = resourceGroupName;
cmdlet.Name = expectedParameters.DeploymentName;
cmdlet.TemplateFile = expectedParameters.TemplateFile;
cmdlet.RollBackDeploymentName = lastDeploymentName;
cmdlet.ExecuteCmdlet();

Assert.Equal(expectedParameters.DeploymentName, actualParameters.DeploymentName);
Assert.Equal(expectedParameters.TemplateFile, actualParameters.TemplateFile);
Assert.NotNull(actualParameters.TemplateParameterObject);
Assert.NotNull(actualParameters.OnErrorDeployment);
Assert.Equal(expectedParameters.OnErrorDeployment.Type, actualParameters.OnErrorDeployment.Type);
Assert.Equal(expectedParameters.OnErrorDeployment.DeploymentName, actualParameters.OnErrorDeployment.DeploymentName);

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

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void CreatesNewPSResourceGroupDeploymentWithUserTemplateEmptyRollback()
{
PSDeploymentCmdletParameters expectedParameters = new PSDeploymentCmdletParameters()
{
TemplateFile = templateFile,
DeploymentName = deploymentName,
OnErrorDeployment = new OnErrorDeployment
{
Type = OnErrorDeploymentType.LastSuccessful,
}
};
PSDeploymentCmdletParameters actualParameters = new PSDeploymentCmdletParameters();
PSResourceGroupDeployment expected = new PSResourceGroupDeployment()
{
Mode = DeploymentMode.Incremental,
DeploymentName = deploymentName,
CorrelationId = "123",
Outputs = new Dictionary<string, DeploymentVariable>()
{
{ "Variable1", new DeploymentVariable() { Value = "true", Type = "bool" } },
{ "Variable2", new DeploymentVariable() { Value = "10", Type = "int" } },
{ "Variable3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
},
Parameters = new Dictionary<string, DeploymentVariable>()
{
{ "Parameter1", new DeploymentVariable() { Value = "true", Type = "bool" } },
{ "Parameter2", new DeploymentVariable() { Value = "10", Type = "int" } },
{ "Parameter3", new DeploymentVariable() { Value = "hello world", Type = "string" } }
},
ProvisioningState = ProvisioningState.Succeeded.ToString(),
ResourceGroupName = resourceGroupName,
TemplateLink = new TemplateLink()
{
ContentVersion = "1.0",
Uri = "http://mytemplate.com"
},
Timestamp = new DateTime(2014, 2, 13),
OnErrorDeployment = new OnErrorDeploymentExtended
{
Type = OnErrorDeploymentType.LastSuccessful,
}
};
resourcesClientMock.Setup(f => f.ExecuteDeployment(
It.IsAny<PSDeploymentCmdletParameters>()))
.Returns(expected)
.Callback((PSDeploymentCmdletParameters p) => { actualParameters = p; });

cmdlet.ResourceGroupName = resourceGroupName;
cmdlet.Name = expectedParameters.DeploymentName;
cmdlet.TemplateFile = expectedParameters.TemplateFile;
cmdlet.RollbackToLastDeployment = true;
cmdlet.ExecuteCmdlet();

Assert.Equal(expectedParameters.DeploymentName, actualParameters.DeploymentName);
Assert.Equal(expectedParameters.TemplateFile, actualParameters.TemplateFile);
Assert.NotNull(actualParameters.TemplateParameterObject);
Assert.NotNull(actualParameters.OnErrorDeployment);
Assert.Equal(expectedParameters.OnErrorDeployment.Type, actualParameters.OnErrorDeployment.Type);
Assert.Equal(expectedParameters.OnErrorDeployment.DeploymentName, actualParameters.OnErrorDeployment.DeploymentName);

commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Once());
}
Expand Down
2 changes: 2 additions & 0 deletions src/ResourceManager/Resources/Commands.Resources/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
- Additional information about change #1
-->
## Current Release
* Update New-AzureRmResourceGroupDeployment with new parameter RollbackAction
- Add support for OnErrorDeployment with the new parameter.
* Support managed identity on policy assignments.
* Parameters with default values are no longer requred when assigning a policy with `New-AzureRmPolicyAssignment`
* Add new cmdlet Get-AzureRmPolicyAlias for retrieving policy aliases
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,7 @@ public string OutputsString
{
get { return ResourcesExtensions.ConstructDeploymentVariableTable(Outputs); }
}

public OnErrorDeploymentExtended OnErrorDeployment { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ private static PSResourceGroupDeployment CreatePSResourceGroupDeployment(
deploymentObject.ProvisioningState = properties.ProvisioningState;
deploymentObject.TemplateLink = properties.TemplateLink;
deploymentObject.CorrelationId = properties.CorrelationId;
deploymentObject.OnErrorDeployment = properties.OnErrorDeployment;

if (properties.DebugSetting() != null && !string.IsNullOrEmpty(properties.DebugSetting().DetailLevel()))
{
Expand Down
Loading