-
Notifications
You must be signed in to change notification settings - Fork 4k
Policy parameters support in New-AzureRmPolicyDefinition and New-AzureRmPolicyAssignment #3476
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
Conversation
Hi @luanshixia, I'm your friendly neighborhood Azure Pull Request Bot (You can call me AZPRBOT). Thanks for your contribution!
TTYL, AZPRBOT; |
Can one of the admins verify this patch? |
@@ -54,6 +61,19 @@ public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase | |||
public PSObject PolicyDefinition { get; set; } | |||
|
|||
/// <summary> | |||
/// Gets or sets the policy assignment policy parameter object. | |||
/// </summary> | |||
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The pollicy parameter object.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in the help message "pollicy" should be "policy"
/// <summary> | ||
/// Gets or sets the policy assignment policy parameter file or string. | ||
/// </summary> | ||
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The pollicy parameter file or string.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in the help message "pollicy"
@@ -112,11 +132,88 @@ private JToken GetResource() | |||
{ | |||
DisplayName = this.DisplayName ?? null, | |||
PolicyDefinitionId = this.PolicyDefinition.Properties["policyDefinitionId"].Value.ToString(), | |||
Scope = this.Scope | |||
Scope = this.Scope, | |||
Parameters = GetParameters() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we usually scope the function calls, so this should be this.GetParameters()
/// Gets or sets the policy assignment policy parameter object. | ||
/// </summary> | ||
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The pollicy parameter object.")] | ||
public Hashtable PolicyParameterObject { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have validation so that user cannot specify both PolicyParameterObject and PolicyParameters.
This can be implemented using parameter sets.
/// </summary> | ||
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The pollicy parameter file or string.")] | ||
[ValidateNotNullOrEmpty] | ||
public string PolicyParameters { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we rename this to PolicyParametersFile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just confirmed with Mike that it is the expected behavior.
// Load parameters from local file or literal | ||
if (PolicyParameters != null) | ||
{ | ||
string policyParameterFilePath = this.TryResolvePath(PolicyParameters); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is confusing to use a single parameter as maybe a file name or maybe a string representing parameters.
We should explicitly make them two separate parameters. So in total we should have three parameters:
PolicyParameters
PolicyParametersFile
PolicyParametersObject.
Each should be in its own ParameterSet so that user can only specify one of them.
Were you specifically asked to use just two parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For how to use ParameterSets u can refer to this documentation https://msdn.microsoft.com/en-us/library/dd878348(v=vs.85).aspx. Also several of our existing cmdlets use parameter sets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the 1st one: Just confirmed with Mike that it is the expected behavior.
For the 2nd one: Yes will do that.
{ | ||
return null; | ||
} | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need of else here since you are returning control from if
|
||
object IDynamicParameters.GetDynamicParameters() | ||
{ | ||
if (PolicyDefinition != null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scope it as this.PolicyDefinition, everywhere
/// </summary> | ||
private JToken GetParametersObject() | ||
{ | ||
string parametersFilePath = this.TryResolvePath(this.Parameters); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above I think we shouldn't use the same parameter as maybe a filePath or a parameter. It would be cleaner to have two separate parameters in two different parameter sets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just confirmed with Mike that it is the expected behavior.
} | ||
}; | ||
|
||
return policyassignmentObject.ToJToken(); | ||
} | ||
|
||
object IDynamicParameters.GetDynamicParameters() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
who calls this method and can u point me to how dynamic parameters work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This interface method is called by the PowerShell engine (thus a callback), so PowerShell can know what parameters are defined dynamically in the cmdlet and allow users to provide values for them.
@@ -113,7 +120,8 @@ private JToken GetResource() | |||
{ | |||
Description = this.Description ?? null, | |||
DisplayName = this.DisplayName ?? null, | |||
PolicyRule = JObject.Parse(GetPolicyRuleObject().ToString()) | |||
PolicyRule = JObject.Parse(GetPolicyRuleObject().ToString()), | |||
Parameters = this.Parameters == null ? null : JObject.Parse(GetParametersObject().ToString()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.GetParametersObject
@@ -15,6 +15,7 @@ | |||
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Policy | |||
{ | |||
using Newtonsoft.Json; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it has 3 commits. We should squash changes to a single commit, so that it is easy to revert the entire change if required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be a 1-click when merging on this page, though I don't have permission to do that now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok please squash before merging then.
return File.Exists(parametersFilePath) | ||
? JToken.FromObject(FileUtilities.DataStore.ReadFileAsText(parametersFilePath)) | ||
: JToken.FromObject(this.Policy); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add scenario tests once you have addressed the PR comments.
Also get this PR reviewed by vivsrini.
@azuresdkci add to whitelist |
} | ||
}; | ||
|
||
return policyassignmentObject.ToJToken(); | ||
} | ||
|
||
object IDynamicParameters.GetDynamicParameters() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look like it belongs here. Can we move this out to a common/util file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the implementation of the interface IDynamicParameters, which the class conforms to.
|
||
/// <summary> | ||
/// Creates a policy assignment. | ||
/// </summary> | ||
[Cmdlet(VerbsCommon.New, "AzureRmPolicyAssignment"), OutputType(typeof(PSObject))] | ||
public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase | ||
public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase, IDynamicParameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add scenario tests/moq tests for both these cmdlets
/// The parameters declaration. | ||
/// </summary> | ||
[JsonProperty(Required = Required.Default)] | ||
public JObject Parameters { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please confirm that there are no changes required for other policy cmdlets? i.e.,
- Get/set/remove policy definition works with and without parameters
- Get/set/remove policy assignment works with and without parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, no impact at this time.
/// </summary> | ||
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The parameters for policy definition. This can either be a path to a file name containing the parameters declaration, or the parameters declaration as string.")] | ||
[ValidateNotNullOrEmpty] | ||
public string Parameters { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PolicyDefinitionParameters?
[Parameter(ParameterSetName = PolicyParametersStringParameterSetName, | ||
Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The policy parameters file path or policy parameters string.")] | ||
[ValidateNotNullOrEmpty] | ||
public string PolicyParameters { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PolicyAssignmentParameters?
TBH, the names are confusing as-is (what is the difference between parameters in policy def vs policy assignment?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, please ensure the help files are updated accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For 1: So the parameters in policy def are declarations and those in policy assignment are actual values. I know the names are confusing, but I have confirmed with Mike about these names.
For 2: Will do that.
@@ -59,6 +59,13 @@ public class NewAzurePolicyDefinitionCmdlet : PolicyDefinitionCmdletBase | |||
public string Policy { get; set; } | |||
|
|||
/// <summary> | |||
/// Gets or sets the parameters parameter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
|
||
/// <summary> | ||
/// Creates a policy assignment. | ||
/// </summary> | ||
[Cmdlet(VerbsCommon.New, "AzureRmPolicyAssignment"), OutputType(typeof(PSObject))] | ||
public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase | ||
public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase, IDynamicParameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No api-version change for policy cmdlets?
@luanshixia the build is failing since you are introducing parameters |
@@ -63,7 +63,7 @@ public static class Constants | |||
/// <summary> | |||
/// The default policy API version. | |||
/// </summary> | |||
public static readonly string PolicyApiVersion = "2016-04-01"; | |||
public static readonly string PolicyApiVersion = "2016-12-01"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious as to why the new API version date is set to December instead of a more recent date?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per the resource schema seen on Azure Portal, the latest version for policy is 2016-12-01:
{
"resourceType": "policyDefinitions",
"locations": [],
"apiVersions": [
"2016-12-01",
"2016-04-01",
"2015-10-01-preview"
]
},
{
"resourceType": "policyAssignments",
"locations": [],
"apiVersions": [
"2016-12-01",
"2016-04-01",
"2015-10-01-preview"
]
},
/// The parameter values. | ||
/// </summary> | ||
[JsonProperty(Required = Required.Default)] | ||
public JObject Parameters { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can rename this to Parameter to be consistent with the PolicyDefinitionProperties class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this property cannot be renamed because that should match the REST API. (I also only realized this when I caught an error after trying to keep consistency). Of course we can match names using JsonProperty attribute, but no need.
@cormacpayne Thanks so much for the help. I will rollback my workaround once you have a fix. |
parameterObject.Add(paramKey, valueObject); | ||
} | ||
return parameterObject; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a newline at end of file.
keys = dict.Keys; | ||
} | ||
var parameterObject = new JObject(); | ||
foreach (string paramKey in keys) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use var instead of string as is the convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here "keys" is of type IEnumerable not IEnumerable<string> so paramKey will not be inferred as string unless declared specific.
/// <param name="dict">The <see cref="IDictionary"/> object.</param> | ||
/// <param name="keys">The key set to extract from the <see cref="IDictionary"/> object. Default is all keys.</param> | ||
/// <returns>The conversion result.</returns> | ||
public static JObject ToParameterObject(this IDictionary dict, IEnumerable keys = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method name ToParameterObject is specific to its use in the policy commandlet.
Since this is a utility method it can be used from elsewhere. Can we use a more generic name like ToJsonObject or ToJObject?
@@ -50,10 +61,31 @@ public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase | |||
/// <summary> | |||
/// Gets or sets the policy assignment policy definition parameter. | |||
/// </summary> | |||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The pollicy definition object.")] | |||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The policy definition object.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this line required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So @cormacpayne is working on a fix for BreakingChangeAnalyzer which prevents this PR from passing the build (the reason: the analyzer compares the parameter set with the previous build. In previous build this property belongs to the default parameter set, so it enforces this for later builds). This line is a workaround which can be removed after his fix.
} | ||
|
||
return null; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add newline at end of file.
@@ -113,7 +120,8 @@ private JToken GetResource() | |||
{ | |||
Description = this.Description ?? null, | |||
DisplayName = this.DisplayName ?? null, | |||
PolicyRule = JObject.Parse(GetPolicyRuleObject().ToString()) | |||
PolicyRule = JObject.Parse(GetPolicyRuleObject().ToString()), | |||
Parameters = this.Parameter == null ? null : JObject.Parse(GetParametersObject().ToString()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scope local method calls as this.GetParametersObject()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@cormacpayne I have already got two peer approvals but I don't have the permission to merge it. Could you please merge it so that it can make the 2/15 deadline? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia a couple of comments
@@ -50,10 +61,31 @@ public class NewAzurePolicyAssignmentCmdlet : PolicyAssignmentCmdletBase | |||
/// <summary> | |||
/// Gets or sets the policy assignment policy definition parameter. | |||
/// </summary> | |||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The pollicy definition object.")] | |||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The policy definition object.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia if this parameter is required in every single parameter set, why make this change? Previously it was a globally required parameter, so it was required in any parameter set you used. The same applies now with the changes you are trying to make here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne So there are 3 usages:
PolicyDefinition
onlyPolicyDefinition
+PolicyParameterObject
PolicyDefinition
+PolicyParameter
We don't want users to set both PolicyParameterObject
and PolicyParameter
, so we use two different sets for them. But we also need to allow users to set none of PolicyParameterObject
and PolicyParameter
, which comes the third set. Note we have to set Mandatory=true
for PolicyParameterObject
and PolicyParameter
or we will get parameter set resolving conflict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia I am fine with the three different parameter sets, but there is no need to change PolicyDefinition
from a global parameter to a parameter that's in each of the three parameter sets (that is what is implied by being a global parameter).
|
||
protected const string PolicyParameterObjectParameterSetName = "Policy assignment with parameters via policy parameter object"; | ||
protected const string PolicyParameterStringParameterSetName = "Policy assignment with parameters via policy parameter string"; | ||
protected const string ParameterlessPolicyParameterSetName = "Policy assignment without parameters"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia the name of this parameter set is misleading - Name
and Scope
(and PolicyDefinition
based on its implementation) parameters are globally required parameters, so you are always going to need to provide a value for them, meaning you'll never have a parameter set that is "parameterless"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne No, "parameter" here refers to the policy parameters, not the cmdlet parameters.. This is similar to what is done for template parameters in NewAzureRmResourceGroupDeployment.
} | ||
}; | ||
|
||
return policyassignmentObject.ToJToken(); | ||
} | ||
|
||
object IDynamicParameters.GetDynamicParameters() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia why do you need to add dynamic parameters to this cmdlet? We try to avoid using them as much as possible since they cannot be picked up by our StaticAnalysis tooling and don't allow us to easily check any public interface changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne Because we want to allow users to specify the policy parameters through cmdlet parameters, so we have to dynamically parse the policy definition and extract a list of defined parameters. That is from the requirements. In the future, we also want to add IntelliSense for the dynamic parameters, just like what we did for template deployment.
@@ -175,6 +190,32 @@ Accept pipeline input: False | |||
Accept wildcard characters: False | |||
``` | |||
|
|||
### -PolicyParameter | |||
The policy parameter file path or policy parameter string.```yaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia please move "```yaml" to a new line since it is causing errors with the displayed markdown
``` | ||
|
||
### -PolicyParameterObject | ||
The policy parameter object.```yaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia same comment
@@ -171,6 +171,19 @@ Accept pipeline input: False | |||
Accept wildcard characters: False | |||
``` | |||
|
|||
### -Parameter | |||
The parameters declaration for policy definition. This can either be a path to a file name containing the parameters declaration, or the parameters declaration as string.```yaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia same comment
@vivsriaus can you approve the review you have started? You commented with LGTM, but it still says you have changes requested. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia a couple of more comments after talking with @markcowl
var dp = new RuntimeDefinedParameter | ||
{ | ||
Name = param.Name, | ||
ParameterType = typeString.Equals("array", StringComparison.OrdinalIgnoreCase) ? typeof(object[]) : typeof(string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia can you leverage typeString
to include a switch case for types you would want to define (e.g., int
, bool
, etc.)? It seems like a bad idea to have the default type of non-arrays as string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne Per Policy doc, "the type of a parameter can be either string or array".
dp.Attributes.Add(new ParameterAttribute | ||
{ | ||
Mandatory = false, | ||
ValueFromPipelineByPropertyName = true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia what kind of scenario would lend users to use the ValueFromPipelineByPropertyName
for these dynamic parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne Similarly, the user can put dynamic parameters in an object (say $param) and say: $param | New-AzureRmPolicyAssignment
{ | ||
Mandatory = false, | ||
ValueFromPipelineByPropertyName = true, | ||
HelpMessage = param.Name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia this is not good help for users, it's just repeating the parameter name
Name = param.Name, | ||
ParameterType = typeString.Equals("array", StringComparison.OrdinalIgnoreCase) ? typeof(object[]) : typeof(string) | ||
}; | ||
dp.Attributes.Add(new ParameterAttribute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia the dynamic parameters will need to be in the Parameterless
parameter set, or else users will be able to use them with the provided hashtable or json, which will defeat the purpose of having the dynamic parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne Good catch.
[Parameter(ParameterSetName = PolicyParameterObjectParameterSetName, | ||
Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The policy definition object.")] | ||
[Parameter(ParameterSetName = PolicyParameterStringParameterSetName, | ||
Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The policy definition object.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luanshixia how will users use this ValueFromPipelineByPropertyName
attribute for this parameter? Will there be an object they can pass through the pipeline to this cmdlet that contains the PolicyDefinition
property? Will it also include the below parameters you are trying to add since they also have the ValueFromPipelineByPropertyName
attribute as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cormacpayne I checked the existing code and found pipeline usage is supported across all Resources cmdlets. So the user can do like: @{"PolicyDefinition": @{...} ...} | New-AzureRmPolicyAssignment
…viding more useful help messages.
LGTM once on-demand passes |
Description
Added support for policy parameters to the 2 cmdlets to use the feature provided by API version 2016-12-01.
This checklist is used to make sure that common guidelines for a pull request are followed. You can find a more complete discussion of PowerShell cmdlet best practices here.
General Guidelines
Testing Guidelines
Cmdlet Signature Guidelines
ShouldProcess
and haveSupportShouldProcess=true
specified in the cmdlet attribute. You can find more information onShouldProcess
here.OutputType
attribute if any output is produced - if the cmdlet produces no output, it should implement aPassThru
parameter.Cmdlet Parameter Guidelines