Skip to content
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

resource: support resource id for show/delete/tag #1280

Merged
merged 4 commits into from
Nov 10, 2016

Conversation

yugangw-msft
Copy link
Contributor

No description provided.

@yugangw-msft yugangw-msft changed the title [do not merge]resource: support resource id for show/delete/tag resource: support resource id for show/delete/tag Nov 10, 2016
@yugangw-msft
Copy link
Contributor Author

@tjprescott, could you please take a look?

Copy link
Member

@tjprescott tjprescott left a comment

Choose a reason for hiding this comment

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

A few questions and some minor tweaks requested, but otherwise LGTM (and no I don't know why I'm reviewing PRs at 5 am)


register_cli_argument('resource', 'resource_type', help='The resource type in <namespace>/<type> format.', type=validate_resource_type, validator=resolve_resource_parameters)
register_cli_argument('resource', 'parent_resource_path', help='The parent resource type in <type>/<name> format.', type=validate_parent, required=False, options_list=('--parent',))
register_cli_argument('resource', 'resource_id', options_list=('--id',), help='resource id')
Copy link
Member

Choose a reason for hiding this comment

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

Should we reasonably expect the --ids semantic (of looping through multiple ids) to work here? If it can be done easily, I would suggest that we do. If it can't, then I wouldn't worry about it for this PR.

Copy link
Contributor Author

@yugangw-msft yugangw-msft Nov 10, 2016

Choose a reason for hiding this comment

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

Thought about it, the ids will have to pair with api-versions, and have a many to many association between 2 value groups won't make command easier to use. So let us punt for now

help="resource namespaces like 'Microsoft.Network'. You can also specify it through --resource-type parameter")
register_cli_argument('resource', 'resource_type', help="types such as 'virtualNetworks', or optional include namespace such as 'Microsoft.Network/virtualNetworks'")
register_cli_argument('resource', 'parent_resource_path', required=False, options_list=('--parent',),
help="path in formats of '<parent-type>/<parent-name>' or '<grandparent-type>/<grandparent-name>/<parent-type>/<parent-name>'")
Copy link
Member

Choose a reason for hiding this comment

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

Here it might be better to give examples such as a SQL server and database path for the grandparent case and pretty much any normal one for the parent-type/parent-name case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sql Server and database is still parent-child relationship. I have added a concrete example.
For grand parent relationship, I searched across cli, looks like we only have one case on app gateway url-path-map rules. Do you have related resource types detail?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, no, you're right.

register_cli_argument('resource', 'resource_id', options_list=('--id',), help='resource id')
register_cli_argument('resource', 'resource_provider_namespace', options_list=('--namespace',), completer=get_providers_completion_list,
help="resource namespaces like 'Microsoft.Network'. You can also specify it through --resource-type parameter")
register_cli_argument('resource', 'resource_type', help="types such as 'virtualNetworks', or optional include namespace such as 'Microsoft.Network/virtualNetworks'")
Copy link
Member

Choose a reason for hiding this comment

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

Should there be a completer on this? Are we maintaining the ability to optionally include the namespace here to avoid breaking changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, we are still maintaining this ability. This one is a redundant, so I have removed. We have another similar registration at a few lines above which does have a completer

'API version is required and could not be resolved for resource {}/{}'
.format(resource_type.namespace, resource_type.type))

def resolve_resource_parameters(namespace):
Copy link
Member

Choose a reason for hiding this comment

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

If we maintain the ability to specify resource_type as 'provider/type' then where do we do that sniffing/parsing/checking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, we still maintain the logic, check out the new code in _ResourceUtils.__init__

api_version,
parameters)
except CloudError as ex:
# TODO: Remove workaround once Swagger and SDK fix is implemented (#120123723)
Copy link
Member

Choose a reason for hiding this comment

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

I'm assuming this block of logic has been moved and not removed. Is this workaround still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, this is the existing code, but agree we can remove now
the related issue is still active, but current generated code already handles 202 , I think we are good. The new tests I added also worked. So we can close that issue as well

parent_resource_path or resource_provider_namespace or
resource_name):
raise IncorrectUsageError(
"You must specify either 'id' or other individual pieces, but not both")
Copy link
Member

Choose a reason for hiding this comment

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

You might put this in usage statement form, like the error for incorrect use of --ids does. So something like (--id ID | --resource-group RG --name NAME --provider ...)

register_cli_argument('resource', 'resource_provider_namespace', options_list=('--namespace',), completer=get_providers_completion_list,
help="resource namespaces like 'Microsoft.Network'. You can also specify it through --resource-type parameter")
register_cli_argument('resource', 'resource_type', help="types such as 'virtualNetworks', or optional include namespace such as 'Microsoft.Network/virtualNetworks'")
register_cli_argument('resource', 'parent_resource_path', required=False, options_list=('--parent',),
Copy link
Member

Choose a reason for hiding this comment

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

I think we should add these parameters to the same arg_group as is automatically done with the --ids parameter. This would be a more consistent experience even if we don't support the automatic looping mechanic of --ids.

@@ -398,7 +397,7 @@ def __init__(self, resource_group_name=None, resource_provider_namespace=None,
parent_resource_path or resource_provider_namespace or
resource_name):
raise IncorrectUsageError(
"You must specify either 'id' or other individual pieces, but not both")
"(--id ID | --resource-group RG --name NAME --namespace NAMESPACE --resource-type TYPE -n NAME)") #pylint: disable=line-too-long
Copy link
Member

Choose a reason for hiding this comment

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

I think the usage string would be (--id ID | --resource-group RG --name NAME [--namespace NAMESPACE] --resource-type TYPE) since namespace is optional and you don't need --name NAME and -n NAME.

@yugangw-msft yugangw-msft merged commit a71319f into Azure:master Nov 10, 2016
Copy link
Contributor

@vivsriaus vivsriaus left a comment

Choose a reason for hiding this comment

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

Thanks for making this in!

type: command
short-summary: list resource
examples:
- name: list all resource in a region
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this is not related to resource Id change, but "list all resource in a region" ? Why? Does it list all resources in a subscription?

text: >
az resource show -g mygroup -n mywebapp --resource-type "Microsoft.web/sites"
az resource show -g myGroup --namespace Microsoft.Network --parent applicationGateways/ag1/urlPathMaps/map1 --resource-type pathRules -n rule1
Copy link
Contributor

Choose a reason for hiding this comment

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

We want to move away from this "parent" parameter - only makes it harder for users to identify a resource.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

user can use --id, we can't hide the --parent


helps['resource tag'] = """
type: command
short-summary: tag a resource. Reference the examples for help with arguments.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would have expected "resource tag create" to actually add a tag on a resource.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

please open an issue, imo, tag is good enough, unless we will have list, 'delete', etc

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, we should definitely have a way to delete a tag (unless removal of tag by using update command with nulled out tag properties is already supported)


helps['resource update'] = """
type: command
short-summary: update a resource
Copy link
Contributor

Choose a reason for hiding this comment

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

No help for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is so called generic update, help for common flags is already provided

help="Provider namespace (Ex: 'Microsoft.Provider')")
register_cli_argument('resource', 'resource_type',
completer=get_resource_types_completion_list,
help="The resource type (Ex: 'resC'). Can also accept namespace/type format (Ex: 'Microsoft.Provider/resC')")
Copy link
Contributor

Choose a reason for hiding this comment

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

Why would a resource type also accept provider namespace, like Microsoft.Provider/resc format? Does that mean the provider namespace parameter above is optional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct, the namespace is optional. We saw vm show, vnet show etc, all return namespace/type, so we decided to support it then people can pipe output

@@ -409,3 +389,124 @@ def get_policy_assignment_completion_list(prefix, **kwargs):#pylint: disable=unu
result = policy_client.policy_assignments.list()
return [i.name for i in result]

class _ResourceUtils(object): #pylint: disable=too-many-instance-attributes
def __init__(self, resource_group_name=None, resource_provider_namespace=None,
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we validate the provided --id is in the correct format (/subscriptions/subId/resourceGroups/rgName/providers/Microsoft.Compute/vm) before making the request?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By default we don't want to validate input for API which is not LRO and server error is clear. But for this command, we do validation when api-version is missing, which we expect would be the majority case

raise IncorrectUsageError('Resource type {} not found.'
.format(resource_type_str))
if len(rt) == 1 and rt[0].api_versions:
npv = [v for v in rt[0].api_versions if 'preview' not in v.lower()]
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious - what does the var npv stand for? It isn't obvious to me.

raise IncorrectUsageError('Resource type {} not found.'
.format(resource_type_str))
if len(rt) == 1 and rt[0].api_versions:
npv = [v for v in rt[0].api_versions if 'preview' not in v.lower()]
Copy link
Contributor

Choose a reason for hiding this comment

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

So, we ignore the preview api versions here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

correct. let us know we should use

return npv[0] if npv else rt[0].api_versions[0]
else:
raise IncorrectUsageError(
'API version is required and could not be resolved for resource {}'
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if this is even possible. All resource types WILL have an api-version

Copy link
Contributor Author

@yugangw-msft yugangw-msft Nov 11, 2016

Choose a reason for hiding this comment

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

this is mostly for when the type providerd by users are invalid

@vivsriaus
Copy link
Contributor

@yugangw-msft Thanks for making the changes for us. Do all ARM commands work for tenant level (no subscription) resources as well?

@yugangw-msft
Copy link
Contributor Author

Do all ARM commands work for tenant level (no subscription) resources as well?

@vivsriaus I don't think so. Does xplat work for that? Please provide more information

@vivsriaus
Copy link
Contributor

@yugangw-msft xplat doesn't, but the generic resource cmdlets in powershell do (New-Resource, Get-Resource, Set-Resource, Remove-Resource). For example, to get a tenant level powerapps resource:

Get-AzureRmResource -ResourceId providers/Microsoft.PowerApps/apps/69fb28f7-9bb3-2766-2b0e-b9449f10fa3c -ApiVersion 2015-02-01-preview

@yugangw-msft
Copy link
Contributor Author

@vivsriaus, good to know. Since only limited resource types can be tenant level, including Intune and PowerApps, we don't need to do it right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants