-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Add policy set definition commands #4515
Conversation
@vivsriaus https://pypi.python.org/pypi/azure-mgmt-resource/1.2.0rc3 with your 404 fix |
helps['policy setdefinition list'] = """ | ||
type: command | ||
short-summary: List policy set definitions. | ||
""" |
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.
There is no description for az policy setdefinition -h
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.
Done
help='policy set definition name or fully qualified id') | ||
c.register_cli_argument('policy assignment create', 'sku', options_list=('--sku', '-s'), | ||
help='policy sku. One of Free or Standard.') | ||
|
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.
There is no help for --params
of az policy setdefinition create
and az policy setdefinition update
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.
Will add, 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.
Done
@@ -189,6 +189,39 @@ | |||
type: command | |||
short-summary: List policy definitions. | |||
""" | |||
helps['policy setdefinition create'] = """ |
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.
IMO setdefinition
should be set-definition
for all these new commands.
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.
Or even just set
unless there are "set" commands and "set-definition" commands...
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.
set-definition sounds more apt. thanks
@@ -189,6 +189,39 @@ | |||
type: command | |||
short-summary: List policy definitions. | |||
""" | |||
helps['policy setdefinition create'] = """ |
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 need group help text for the setdefinition command group.
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.
Added
az policy setdefinition create -n readOnlyStorage --definitions \\ | ||
[ \\ | ||
{ \\ | ||
"policyDefinitionId": "/subscriptions/mySubId/providers/Microsoft.Authorization/policyDefinitions/storagePolicy" \\ |
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 a policy set just a collection of IDs, or is there more to it? If it is, it seems you could get away from the JSON object approach and just accepts a list of names and/or IDs to assemble the set definition.
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.
Not just IDs, it can have the entire policy rule as json 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.
Got it
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'm sorry I misspoke above. The policy set cannot contain entire policy rule, but it can have a multiples of policyDefinitionId and parameters (which is json object), so either way, this is a complex object that requires file handling
parameters: | ||
- name: --definitions | ||
type: string | ||
short-summary: Policy definitions in JSON format, or a path to a file containing JSON rules. |
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.
Recommendations: 1) don't accept JSON unless you truly have to. 2) If you do need this to be JSON, then just accept the JSON string. The help text would look like JSON string containing the policy definition. Use @{file} to load from a file.
We are trying to move away from sniffing whether an input is JSON or a path through the @ symbol (which loads the contents of the 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 should be a json, since it takes a json array which can have:
- policy definition id or
- policy rule
With regards to help, the definitions can also be a uri that points to a valid json file, just like the rules in policy definition
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.
Since you are going for parity with policy definition create
then disregard my comment. However, do make sure the help and behavior is consistent.
c.register_cli_argument('policy assignment create', 'policysetdefinition', options_list=('--policy-set-definition', '-d'), | ||
help='policy set definition name or fully qualified id') | ||
c.register_cli_argument('policy assignment create', 'sku', options_list=('--sku', '-s'), | ||
help='policy sku. One of Free or Standard.') |
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.
Instead of calling out the allowed values via help text, this should use the **enum_choice_list(...)
approach to reflect on the SDK's enum type. If there is no enum type, you can give it a list ['Free', 'Standard']
help='JSON formatted string or a path to a file or uri with such content', | ||
type=file_type, completer=FilesCompleter()) | ||
c.register_cli_argument('policy assignment create', 'policysetdefinition', options_list=('--policy-set-definition', '-d'), | ||
help='policy set definition name or fully qualified id') |
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 common way of expressing this is "Name or ID of the policy set definition." Ditto for the --policy
argument.
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
resource_group_name=None, scope=None, sku=None): | ||
if policy and policysetdefinition: | ||
raise CLIError('usage error: must specify only one --policy POLICY | \ | ||
--policy-set-definition POLICYSETDEFINITION') |
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.
recommend:
usage error: --policy NAME_OR_ID | --policy-set-definition NAME_OR_ID
Also, shouldn't you raise this error if the user supplies neither? You can use if bool(policy) == bool(policysetdefinition):
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.
Good catch!
policy_client = _resource_policy_client_factory() | ||
scope = _build_policy_scope(policy_client.config.subscription_id, | ||
resource_group_name, scope) | ||
policy_id = _resolve_policy_id(policy, policy_client) | ||
policy_id = _resolve_policy_id(policy, policysetdefinition, policy_client) |
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.
recommend parameter name policy_set_definition
or just policy_set
for clarity.
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
if os.path.exists(definitions): | ||
definitions = get_file_json(definitions) | ||
else: | ||
definitions = shell_safe_json_parse(definitions) |
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.
If you just accept JSON and point of the @{file} syntax, you can eliminate this source of potential bugs.
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.
Reading your above comment I understand the reason to keep these commands similar, so this is fine.
policy_definitions=definitions if definitions is not None else definition.policy_definitions, | ||
description=description if description is not None else definition.description, | ||
display_name=display_name if display_name is not None else definition.display_name, | ||
parameters=params if params is not None else definition.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.
Recommend you change "params" to "parameters" for consistency with the group deployment commands. Additionally, just like group deployment create
, and as recommended for the policy object, I'd recommend you simply make the argument take a JSON string, and call out the @{file}
syntax to load from a 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.
Since you are going for parity with the policy definition create
command, this is fine.
@vivsriaus I cancelled the CI run. I will restart CI after #4523 has been merged. |
Restarted. |
…olicySet # Conflicts: # src/command_modules/azure-cli-vm/setup.py
@derekbekoe @tjprescott @yugangw-msft Can you please review the latest changes? 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.
Couple comments on use of \
but LGTM otherwise.
""" | ||
if bool(policy) == bool(policy_set_definition): | ||
raise CLIError('usage error: --policy NAME_OR_ID | \ | ||
--policy-set-definition NAME_OR_ID') |
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.
nit: The formatting here is not quite right. When I run it, I see the following:
# az policy assignment create
usage error: --policy NAME_OR_ID | --policy-set-definition NAME_OR_ID
You need to add a couple extra quotes to avoid the line-wrap from showing in the output.
raise CLIError('usage error: --policy NAME_OR_ID | '\
'--policy-set-definition NAME_OR_ID')
kwargs_list.append(id_arg) | ||
else: | ||
logger.error('az policy assignment create error: argument --not-scopes: \ | ||
invalid notscopes value: \'%s\'' % id_arg) |
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.
Same here with the use of \
.
Right now, you are doing:
'My-first-line-of-text\
My-second-line-of-text'
Rather, it should be:
'My-first-line-of-text'\
'My-second-line-of-text'
@vivsriaus CI is failing due to style. |
@derekbekoe Thanks, done. |
This checklist is used to make sure that common guidelines for a pull request are followed.
General Guidelines
Command Guidelines
(see Authoring Command Modules)