Skip to content
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 @@ -20,6 +20,10 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.Cmdlet

public abstract class DeploymentWhatIfCmdlet: DeploymentCmdletBase, IDynamicParameters
{
[Parameter(Mandatory = false, HelpMessage = "Sets the validation level for validate/what-if. ValidationLevel can be Template(Skips provider validation), Provider(Performs full validation), " +
"or ProviderNoRbac(Performs full validation using RBAC read checks instead of RBAC write checks for provider validation).")]
public string ValidationLevel { get; set; }

/// <summary>
/// It's important not to call this function more than once during an invocation, as it can call the Bicep CLI.
/// This is slow, and can also cause diagnostics to be emitted multiple times.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public abstract class TestDeploymentCmdletBase : DeploymentCmdletBase, IDynamicP
[Parameter(Mandatory = false, HelpMessage = "The query string (for example, a SAS token) to be used with the TemplateUri parameter. Would be used in case of linked templates")]
public string QueryString { get; set; }

[Parameter(Mandatory = false, HelpMessage = "Sets the validation level for validate/what-if. ValidationLevel can be Template(Skips provider validation), Provider(Performs full validation), " +
"or ProviderNoRbac(Performs full validation using RBAC read checks instead of RBAC write checks for provider validation).")]
public string ValidationLevel { get; set; }

public override object GetDynamicParameters()
{
if (!string.IsNullOrEmpty(QueryString))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public class GetAzureManagementGroupDeploymentWhatIfResultCmdlet : DeploymentWha
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: GetTemplateParameterObject(),
resultFormat: this.ResultFormat,
excludeChangeTypes: this.ExcludeChangeType);
excludeChangeTypes: this.ExcludeChangeType,
validationLevel: this.ValidationLevel);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class GetAzureSubscriptionDeploymentWhatIfResultCmdlet : DeploymentWhatIf
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: GetTemplateParameterObject(),
resultFormat: this.ResultFormat,
excludeChangeTypes: this.ExcludeChangeType);
excludeChangeTypes: this.ExcludeChangeType,
validationLevel: this.ValidationLevel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public class GetAzureTenantDeploymentWhatIfResultCmdlet : DeploymentWhatIfCmdlet
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: GetTemplateParameterObject(),
resultFormat: this.ResultFormat,
excludeChangeTypes: this.ExcludeChangeType);
excludeChangeTypes: this.ExcludeChangeType,
validationLevel: this.ValidationLevel);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public class NewAzureManagementGroupDeploymentCmdlet : DeploymentCreateCmdlet
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: GetTemplateParameterObject(),
resultFormat: this.WhatIfResultFormat,
excludeChangeTypes: this.WhatIfExcludeChangeType);
excludeChangeTypes: this.WhatIfExcludeChangeType,
validationLevel: this.ValidationLevel);

protected override bool ShouldSkipConfirmationIfNoChange() => this.ProceedIfNoChange;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public class NewAzureSubscriptionDeploymentCmdlet : DeploymentCreateCmdlet
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: GetTemplateParameterObject(),
resultFormat: this.WhatIfResultFormat,
excludeChangeTypes: this.WhatIfExcludeChangeType);
excludeChangeTypes: this.WhatIfExcludeChangeType,
validationLevel: this.ValidationLevel);

protected override bool ShouldSkipConfirmationIfNoChange() => this.ProceedIfNoChange;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public class NewAzureTenantDeploymentCmdlet: DeploymentCreateCmdlet
templateParametersUri : this.TemplateParameterUri,
templateParametersObject : GetTemplateParameterObject(),
resultFormat : this.WhatIfResultFormat,
excludeChangeTypes: this.WhatIfExcludeChangeType
excludeChangeTypes: this.WhatIfExcludeChangeType,
validationLevel: this.ValidationLevel
);

protected override bool ShouldSkipConfirmationIfNoChange() => this.ProceedIfNoChange;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ protected override void OnProcessRecord()
TemplateFile = this.TemplateUri ?? this.TryResolvePath(this.TemplateFile),
TemplateObject = this.TemplateObject,
TemplateParameterObject = this.GetTemplateParameterObject(),
ParameterUri = this.TemplateParameterUri
ParameterUri = this.TemplateParameterUri,
ValidationLevel = this.ValidationLevel
};

var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ protected override void OnProcessRecord()
TemplateObject = TemplateObject,
QueryString = QueryString,
TemplateParameterObject = GetTemplateParameterObject(),
ParameterUri = TemplateParameterUri
ParameterUri = TemplateParameterUri,
ValidationLevel = ValidationLevel
};

var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ protected override void OnProcessRecord()
TemplateObject = this.TemplateObject,
QueryString = QueryString,
TemplateParameterObject = this.GetTemplateParameterObject(),
ParameterUri = this.TemplateParameterUri
ParameterUri = this.TemplateParameterUri,
ValidationLevel = this.ValidationLevel
};

var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class GetAzureResourceGroupDeploymentWhatIfResultCmdlet : DeploymentWhatI
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: GetTemplateParameterObject(),
resultFormat: this.ResultFormat,
excludeChangeTypes: this.ExcludeChangeType);
excludeChangeTypes: this.ExcludeChangeType,
validationLevel: this.ValidationLevel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public class NewAzureResourceGroupDeploymentCmdlet : DeploymentCreateCmdlet
templateParametersUri: this.TemplateParameterUri,
templateParametersObject: this.GetTemplateParameterObject(),
resultFormat: this.WhatIfResultFormat,
excludeChangeTypes: this.WhatIfExcludeChangeType);
excludeChangeTypes: this.WhatIfExcludeChangeType,
validationLevel: this.ValidationLevel);

protected override void OnProcessRecord()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ protected override void OnProcessRecord()
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
}
: null
: null,
ValidationLevel = ValidationLevel
};

var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,11 @@ private Deployment CreateBasicDeployment(PSDeploymentCmdletParameters parameters
deployment.Tags = parameters?.Tags == null ? null : new Dictionary<string, string>(parameters.Tags);
deployment.Properties.OnErrorDeployment = parameters.OnErrorDeployment;

if (!string.IsNullOrEmpty(parameters.ValidationLevel))
{
deployment.Properties.ValidationLevel = parameters.ValidationLevel;
}

return deployment;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ public class PSDeploymentCmdletParameters
public OnErrorDeployment OnErrorDeployment { get; set; }

public IDictionary<string, IList<string>> AuxTenantHeaders { get; set; }

public string ValidationLevel { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public PSDeploymentWhatIfCmdletParameters(
Hashtable templateObject = null,
Hashtable templateParametersObject = null,
WhatIfResultFormat resultFormat = WhatIfResultFormat.FullResourcePayloads,
string[] excludeChangeTypes = null)
string[] excludeChangeTypes = null,
string validationLevel = null)
{
this.DeploymentName = deploymentName ?? this.GenerateDeployName();
this.ScopeType = scopeType;
Expand All @@ -53,6 +54,7 @@ public PSDeploymentWhatIfCmdletParameters(
.Select(changeType => changeType.ToLowerInvariant())
.Distinct()
.Select(changeType => (ChangeType)Enum.Parse(typeof(ChangeType), changeType, true));
this.ValidationLevel = validationLevel;
}

public string DeploymentName
Expand Down Expand Up @@ -87,6 +89,8 @@ public string DeploymentName

public IEnumerable<ChangeType> ExcludeChangeTypes { get; }

public string ValidationLevel { get; set; }

public DeploymentWhatIf ToDeploymentWhatIf()
{
var properties = new DeploymentWhatIfProperties
Expand Down Expand Up @@ -134,6 +138,11 @@ public DeploymentWhatIf ToDeploymentWhatIf()
: null;
}

if (!string.IsNullOrEmpty(this.ValidationLevel))
{
properties.ValidationLevel = this.ValidationLevel;
}

return new DeploymentWhatIf(properties, this.Location);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Formatters;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions;
using FluentAssertions;

namespace Microsoft.Azure.Commands.Resources.Test.Resources
{
Expand Down Expand Up @@ -147,5 +148,36 @@ public void ValidatesPSResourceGroupDeploymentWithUserTemplateWithDiagnostics()
commandRuntimeMock.Verify(f => f.WriteObject(expectedObject, true), Times.Once());
commandRuntimeMock.Verify(f => f.WriteObject(It.IsAny<List<PSResourceManagerError>>()), Times.Never());
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void ValidatesPSResourceGroupDeploymentWithUserTemplateProviderNoRbac()
{
PSDeploymentCmdletParameters expectedParameters = new PSDeploymentCmdletParameters()
{
TemplateFile = templateFile,
ValidationLevel = ValidationLevel.ProviderNoRbac
};
PSDeploymentCmdletParameters actualParameters = new PSDeploymentCmdletParameters();

TemplateValidationInfo expectedResults = new(new DeploymentValidateResult());

resourcesClientMock.Setup(f => f.ValidateDeployment(
It.IsAny<PSDeploymentCmdletParameters>()))
.Returns(expectedResults)
.Callback((PSDeploymentCmdletParameters p) => { actualParameters = p; });

cmdlet.ResourceGroupName = resourceGroupName;
cmdlet.TemplateFile = expectedParameters.TemplateFile;
cmdlet.ValidationLevel = ValidationLevel.ProviderNoRbac;

cmdlet.ExecuteCmdlet();

actualParameters.TemplateFile.Should().Equals(expectedParameters.TemplateFile);

actualParameters.ValidationLevel.Should().Be(ValidationLevel.ProviderNoRbac);

Assert.NotNull(actualParameters.TemplateParameterObject);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,34 @@ public void TenantLevelWhatIf_SetExcludeChangeType_HidesResourceChanges()
{
TestRunner.RunTestScript("Test-WhatIfExcludeChangeTypesAtTenantScope");
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void TenantLevelWhatIf_ProviderNoRbacAtTenantScope()
{
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtTenantScope");
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void MGLevelWhatIf_ProviderNoRbacAtManagementGroupScope()
{
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtManagementGroupScope");
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void SubLevelWhatIf_ProviderNoRbacAtSubscriptionScope()
{
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtSubscriptionScope");
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void RGLevelWhatIf_ProviderNoRbacAtResourceGroupScope()
{
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtResourceGroupScope");
}
}
}

Loading
Loading