Skip to content

Commit ccdd553

Browse files
Add ValidationLevel parameter to WhatIf/Test (#27352)
Co-authored-by: Yash <[email protected]>
1 parent 93fe2cb commit ccdd553

25 files changed

+1520
-13
lines changed

src/Resources/ResourceManager/Implementation/CmdletBase/DeploymentWhatIfCmdlet.cs

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.Cmdlet
2020

2121
public abstract class DeploymentWhatIfCmdlet: DeploymentCmdletBase, IDynamicParameters
2222
{
23+
[Parameter(Mandatory = false, HelpMessage = "Sets the validation level for validate/what-if. ValidationLevel can be Template(Skips provider validation), Provider(Performs full validation), " +
24+
"or ProviderNoRbac(Performs full validation using RBAC read checks instead of RBAC write checks for provider validation).")]
25+
public string ValidationLevel { get; set; }
26+
2327
/// <summary>
2428
/// It's important not to call this function more than once during an invocation, as it can call the Bicep CLI.
2529
/// This is slow, and can also cause diagnostics to be emitted multiple times.

src/Resources/ResourceManager/Implementation/CmdletBase/TestDeploymentCmdletBase.cs

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ public abstract class TestDeploymentCmdletBase : DeploymentCmdletBase, IDynamicP
1717
[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")]
1818
public string QueryString { get; set; }
1919

20+
[Parameter(Mandatory = false, HelpMessage = "Sets the validation level for validate/what-if. ValidationLevel can be Template(Skips provider validation), Provider(Performs full validation), " +
21+
"or ProviderNoRbac(Performs full validation using RBAC read checks instead of RBAC write checks for provider validation).")]
22+
public string ValidationLevel { get; set; }
23+
2024
public override object GetDynamicParameters()
2125
{
2226
if (!string.IsNullOrEmpty(QueryString))

src/Resources/ResourceManager/Implementation/Deployments/GetAzureManagementGroupDeploymentWhatIfResultCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ public class GetAzureManagementGroupDeploymentWhatIfResultCmdlet : DeploymentWha
6464
templateParametersUri: this.TemplateParameterUri,
6565
templateParametersObject: GetTemplateParameterObject(),
6666
resultFormat: this.ResultFormat,
67-
excludeChangeTypes: this.ExcludeChangeType);
67+
excludeChangeTypes: this.ExcludeChangeType,
68+
validationLevel: this.ValidationLevel);
6869
}
6970
}
7071

src/Resources/ResourceManager/Implementation/Deployments/GetAzureSubscriptionDeploymentWhatIfResultCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public class GetAzureSubscriptionDeploymentWhatIfResultCmdlet : DeploymentWhatIf
6161
templateParametersUri: this.TemplateParameterUri,
6262
templateParametersObject: GetTemplateParameterObject(),
6363
resultFormat: this.ResultFormat,
64-
excludeChangeTypes: this.ExcludeChangeType);
64+
excludeChangeTypes: this.ExcludeChangeType,
65+
validationLevel: this.ValidationLevel);
6566
}
6667
}

src/Resources/ResourceManager/Implementation/Deployments/GetAzureTenantDeploymentWhatIfResultCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ public class GetAzureTenantDeploymentWhatIfResultCmdlet : DeploymentWhatIfCmdlet
5959
templateParametersUri: this.TemplateParameterUri,
6060
templateParametersObject: GetTemplateParameterObject(),
6161
resultFormat: this.ResultFormat,
62-
excludeChangeTypes: this.ExcludeChangeType);
62+
excludeChangeTypes: this.ExcludeChangeType,
63+
validationLevel: this.ValidationLevel);
6364
}
6465
}
6566

src/Resources/ResourceManager/Implementation/Deployments/NewAzureManagementGroupDeploymentCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ public class NewAzureManagementGroupDeploymentCmdlet : DeploymentCreateCmdlet
105105
templateParametersUri: this.TemplateParameterUri,
106106
templateParametersObject: GetTemplateParameterObject(),
107107
resultFormat: this.WhatIfResultFormat,
108-
excludeChangeTypes: this.WhatIfExcludeChangeType);
108+
excludeChangeTypes: this.WhatIfExcludeChangeType,
109+
validationLevel: this.ValidationLevel);
109110

110111
protected override bool ShouldSkipConfirmationIfNoChange() => this.ProceedIfNoChange;
111112
}

src/Resources/ResourceManager/Implementation/Deployments/NewAzureSubscriptionDeploymentCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public class NewAzureSubscriptionDeploymentCmdlet : DeploymentCreateCmdlet
100100
templateParametersUri: this.TemplateParameterUri,
101101
templateParametersObject: GetTemplateParameterObject(),
102102
resultFormat: this.WhatIfResultFormat,
103-
excludeChangeTypes: this.WhatIfExcludeChangeType);
103+
excludeChangeTypes: this.WhatIfExcludeChangeType,
104+
validationLevel: this.ValidationLevel);
104105

105106
protected override bool ShouldSkipConfirmationIfNoChange() => this.ProceedIfNoChange;
106107
}

src/Resources/ResourceManager/Implementation/Deployments/NewAzureTenantDeploymentCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ public class NewAzureTenantDeploymentCmdlet: DeploymentCreateCmdlet
9999
templateParametersUri : this.TemplateParameterUri,
100100
templateParametersObject : GetTemplateParameterObject(),
101101
resultFormat : this.WhatIfResultFormat,
102-
excludeChangeTypes: this.WhatIfExcludeChangeType
102+
excludeChangeTypes: this.WhatIfExcludeChangeType,
103+
validationLevel: this.ValidationLevel
103104
);
104105

105106
protected override bool ShouldSkipConfirmationIfNoChange() => this.ProceedIfNoChange;

src/Resources/ResourceManager/Implementation/Deployments/TestAzureManagementGroupDeploymentCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ protected override void OnProcessRecord()
5555
TemplateFile = this.TemplateUri ?? this.TryResolvePath(this.TemplateFile),
5656
TemplateObject = this.TemplateObject,
5757
TemplateParameterObject = this.GetTemplateParameterObject(),
58-
ParameterUri = this.TemplateParameterUri
58+
ParameterUri = this.TemplateParameterUri,
59+
ValidationLevel = this.ValidationLevel
5960
};
6061

6162
var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);

src/Resources/ResourceManager/Implementation/Deployments/TestAzureSubscriptionDeploymentCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ protected override void OnProcessRecord()
5151
TemplateObject = TemplateObject,
5252
QueryString = QueryString,
5353
TemplateParameterObject = GetTemplateParameterObject(),
54-
ParameterUri = TemplateParameterUri
54+
ParameterUri = TemplateParameterUri,
55+
ValidationLevel = ValidationLevel
5556
};
5657

5758
var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);

src/Resources/ResourceManager/Implementation/Deployments/TestAzureTenantDeploymentCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ protected override void OnProcessRecord()
5151
TemplateObject = this.TemplateObject,
5252
QueryString = QueryString,
5353
TemplateParameterObject = this.GetTemplateParameterObject(),
54-
ParameterUri = this.TemplateParameterUri
54+
ParameterUri = this.TemplateParameterUri,
55+
ValidationLevel = this.ValidationLevel
5556
};
5657

5758
var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);

src/Resources/ResourceManager/Implementation/ResourceGroupDeployments/GetAzureResourceGroupDeploymentWhatIfResultCmdlet.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public class GetAzureResourceGroupDeploymentWhatIfResultCmdlet : DeploymentWhatI
6161
templateParametersUri: this.TemplateParameterUri,
6262
templateParametersObject: GetTemplateParameterObject(),
6363
resultFormat: this.ResultFormat,
64-
excludeChangeTypes: this.ExcludeChangeType);
64+
excludeChangeTypes: this.ExcludeChangeType,
65+
validationLevel: this.ValidationLevel);
6566
}
6667
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ public class NewAzureResourceGroupDeploymentCmdlet : DeploymentCreateCmdlet
121121
templateParametersUri: this.TemplateParameterUri,
122122
templateParametersObject: this.GetTemplateParameterObject(),
123123
resultFormat: this.WhatIfResultFormat,
124-
excludeChangeTypes: this.WhatIfExcludeChangeType);
124+
excludeChangeTypes: this.WhatIfExcludeChangeType,
125+
validationLevel: this.ValidationLevel);
125126

126127
protected override void OnProcessRecord()
127128
{

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ protected override void OnProcessRecord()
7676
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
7777
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
7878
}
79-
: null
79+
: null,
80+
ValidationLevel = ValidationLevel
8081
};
8182

8283
var validationInfo = NewResourceManagerSdkClient.ValidateDeployment(parameters);

src/Resources/ResourceManager/SdkClient/NewResourceManagerSdkClient.cs

+5
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,11 @@ private Deployment CreateBasicDeployment(PSDeploymentCmdletParameters parameters
481481
deployment.Tags = parameters?.Tags == null ? null : new Dictionary<string, string>(parameters.Tags);
482482
deployment.Properties.OnErrorDeployment = parameters.OnErrorDeployment;
483483

484+
if (!string.IsNullOrEmpty(parameters.ValidationLevel))
485+
{
486+
deployment.Properties.ValidationLevel = parameters.ValidationLevel;
487+
}
488+
484489
return deployment;
485490
}
486491

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

+2
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,7 @@ public class PSDeploymentCmdletParameters
4343
public OnErrorDeployment OnErrorDeployment { get; set; }
4444

4545
public IDictionary<string, IList<string>> AuxTenantHeaders { get; set; }
46+
47+
public string ValidationLevel { get; set; }
4648
}
4749
}

src/Resources/ResourceManager/SdkModels/Deployments/PSDeploymentWhatIfCmdletParameters.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public PSDeploymentWhatIfCmdletParameters(
3434
Hashtable templateObject = null,
3535
Hashtable templateParametersObject = null,
3636
WhatIfResultFormat resultFormat = WhatIfResultFormat.FullResourcePayloads,
37-
string[] excludeChangeTypes = null)
37+
string[] excludeChangeTypes = null,
38+
string validationLevel = null)
3839
{
3940
this.DeploymentName = deploymentName ?? this.GenerateDeployName();
4041
this.ScopeType = scopeType;
@@ -53,6 +54,7 @@ public PSDeploymentWhatIfCmdletParameters(
5354
.Select(changeType => changeType.ToLowerInvariant())
5455
.Distinct()
5556
.Select(changeType => (ChangeType)Enum.Parse(typeof(ChangeType), changeType, true));
57+
this.ValidationLevel = validationLevel;
5658
}
5759

5860
public string DeploymentName
@@ -87,6 +89,8 @@ public string DeploymentName
8789

8890
public IEnumerable<ChangeType> ExcludeChangeTypes { get; }
8991

92+
public string ValidationLevel { get; set; }
93+
9094
public DeploymentWhatIf ToDeploymentWhatIf()
9195
{
9296
var properties = new DeploymentWhatIfProperties
@@ -134,6 +138,11 @@ public DeploymentWhatIf ToDeploymentWhatIf()
134138
: null;
135139
}
136140

141+
if (!string.IsNullOrEmpty(this.ValidationLevel))
142+
{
143+
properties.ValidationLevel = this.ValidationLevel;
144+
}
145+
137146
return new DeploymentWhatIf(properties, this.Location);
138147
}
139148

src/Resources/Resources.Test/ResourceGroupDeployments/TestAzureResourceGroupDeploymentCommandTests.cs

+32
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Formatters;
3232
using Newtonsoft.Json.Linq;
3333
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions;
34+
using FluentAssertions;
3435

3536
namespace Microsoft.Azure.Commands.Resources.Test.Resources
3637
{
@@ -147,5 +148,36 @@ public void ValidatesPSResourceGroupDeploymentWithUserTemplateWithDiagnostics()
147148
commandRuntimeMock.Verify(f => f.WriteObject(expectedObject, true), Times.Once());
148149
commandRuntimeMock.Verify(f => f.WriteObject(It.IsAny<List<PSResourceManagerError>>()), Times.Never());
149150
}
151+
152+
[Fact]
153+
[Trait(Category.AcceptanceType, Category.CheckIn)]
154+
public void ValidatesPSResourceGroupDeploymentWithUserTemplateProviderNoRbac()
155+
{
156+
PSDeploymentCmdletParameters expectedParameters = new PSDeploymentCmdletParameters()
157+
{
158+
TemplateFile = templateFile,
159+
ValidationLevel = ValidationLevel.ProviderNoRbac
160+
};
161+
PSDeploymentCmdletParameters actualParameters = new PSDeploymentCmdletParameters();
162+
163+
TemplateValidationInfo expectedResults = new(new DeploymentValidateResult());
164+
165+
resourcesClientMock.Setup(f => f.ValidateDeployment(
166+
It.IsAny<PSDeploymentCmdletParameters>()))
167+
.Returns(expectedResults)
168+
.Callback((PSDeploymentCmdletParameters p) => { actualParameters = p; });
169+
170+
cmdlet.ResourceGroupName = resourceGroupName;
171+
cmdlet.TemplateFile = expectedParameters.TemplateFile;
172+
cmdlet.ValidationLevel = ValidationLevel.ProviderNoRbac;
173+
174+
cmdlet.ExecuteCmdlet();
175+
176+
actualParameters.TemplateFile.Should().Equals(expectedParameters.TemplateFile);
177+
178+
actualParameters.ValidationLevel.Should().Be(ValidationLevel.ProviderNoRbac);
179+
180+
Assert.NotNull(actualParameters.TemplateParameterObject);
181+
}
150182
}
151183
}

src/Resources/Resources.Test/ScenarioTests/DeploymentWhatIfTests.cs

+28
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,34 @@ public void TenantLevelWhatIf_SetExcludeChangeType_HidesResourceChanges()
152152
{
153153
TestRunner.RunTestScript("Test-WhatIfExcludeChangeTypesAtTenantScope");
154154
}
155+
156+
[Fact]
157+
[Trait(Category.AcceptanceType, Category.CheckIn)]
158+
public void TenantLevelWhatIf_ProviderNoRbacAtTenantScope()
159+
{
160+
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtTenantScope");
161+
}
162+
163+
[Fact]
164+
[Trait(Category.AcceptanceType, Category.CheckIn)]
165+
public void MGLevelWhatIf_ProviderNoRbacAtManagementGroupScope()
166+
{
167+
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtManagementGroupScope");
168+
}
169+
170+
[Fact]
171+
[Trait(Category.AcceptanceType, Category.CheckIn)]
172+
public void SubLevelWhatIf_ProviderNoRbacAtSubscriptionScope()
173+
{
174+
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtSubscriptionScope");
175+
}
176+
177+
[Fact]
178+
[Trait(Category.AcceptanceType, Category.CheckIn)]
179+
public void RGLevelWhatIf_ProviderNoRbacAtResourceGroupScope()
180+
{
181+
TestRunner.RunTestScript("Test-WhatIfProviderNoRbacAtResourceGroupScope");
182+
}
155183
}
156184
}
157185

0 commit comments

Comments
 (0)