Skip to content

Commit

Permalink
Fix lock issues, help messages, strong-typed lock commands (Azure#4608)
Browse files Browse the repository at this point in the history
* fixed lock delete help so it now shows

* worked on locks

* added all commands

* added commands and tests for lock

* fixed tests, code done

* added help, removed resource_group_name bindings for lock commands

* fixed up lock tests to account for new bindings

* changed validator test to correct argname

* help for new commands

* added history

* moved profile commands to resource

* minor help changes, fixed subscription lock param, condensed registering params

* moved notes help to _params

* fixed pep8

* fixed help mistake and removed file
  • Loading branch information
williexu authored Oct 5, 2017
1 parent 9bdd2ad commit bc50a23
Show file tree
Hide file tree
Showing 13 changed files with 1,251 additions and 624 deletions.
7 changes: 5 additions & 2 deletions src/azure-cli-core/azure/cli/core/commands/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,13 @@ def resource_id(**kwargs):
- grandchild_type Type of the grandchild resource
- grandchild_name Name of the grandchild resource
'''
kwargs = {key: value for key, value in kwargs.items() if value is not None}
rid = '/subscriptions/{subscription}'.format(**kwargs)
try:
rid = '/'.join((rid, 'resourceGroups/{resource_group}'.format(**kwargs)))
try:
rid = '/'.join((rid, 'resourceGroups/{resource_group}'.format(**kwargs)))
except KeyError:
pass
rid = '/'.join((rid, 'providers/{namespace}'.format(**kwargs)))
rid = '/'.join((rid, '{type}/{name}'.format(**kwargs)))
try:
Expand Down Expand Up @@ -174,7 +178,6 @@ def parse_resource_id(rid):
result = _populate_alternate_kwargs(result)
else:
result = dict(name=rid)

return {key: value for key, value in result.items() if value is not None}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from azure.cli.core.cloud import get_active_cloud
from azure.cli.core.commands.validators import DefaultStr


logger = get_az_logger(__name__)

_CLOUD_CONSOLE_WARNING_TEMPLATE = ("Azure Cloud Shell automatically authenticates the user account it was initially"
Expand Down
4 changes: 3 additions & 1 deletion src/command_modules/azure-cli-resource/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ Release History
unreleased
+++++++++++++++++++
* group: permit --resource-group/-g options for resource group name.

* `account lock`: lock commands to work specifically with subscription level locks
* `group lock`: lock commands to work specifically with group level locks
* `resource lock`: lock command to work specifically with resource level locks

2.0.15 (2017-09-22)
+++++++++++++++++++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,16 @@
type: command
short-summary: Create a lock.
long-summary: 'Locks can exist at three different scopes: subscription, resource group and resource.'
parameters:
- name: --notes
type: string
short-summary: Notes about this lock.
examples:
- name: Create a read-only subscription level lock.
text: >
az lock create --name lockName --resource-group group --lock-type ReadOnly
"""
helps['lock delete'] = """
type: commands
type: command
short-summary: Delete a lock.
examples:
- name: Delete a resource-group-level lock
- name: Delete a resource group-level lock
text: >
az lock delete --name lockName --resource-group group
"""
Expand All @@ -120,15 +116,55 @@
helps['lock update'] = """
type: command
short-summary: Update a lock.
parameters:
- name: --notes
type: string
short-summary: Notes about this lock.
examples:
- name: Update a resource-group level lock with new notes and type
- name: Update a resource group level lock with new notes and type
text: >
az lock update --name lockName --resource-group group --notes newNotesHere --lock-type CanNotDelete
"""
helps['account lock'] = """
type: group
short-summary: Manage Azure subscription level locks.
"""
helps['account lock create'] = """
type: command
short-summary: Create a subscription lock.
examples:
- name: Create a read-only subscription level lock.
text: >
az account lock create --lock-type ReadOnly -n lockName
"""
helps['account lock delete'] = """
type: command
short-summary: Delete a subscription lock.
examples:
- name: Delete a subscription lock
text: >
az account lock delete --name lockName
"""
helps['account lock list'] = """
type: command
short-summary: List lock information in the subscription.
examples:
- name: List out all locks on the subscription level
text: >
az account lock list
"""
helps['account lock show'] = """
type: command
short-summary: Show the details of a subscription lock
examples:
- name: Show a subscription level lock
text: >
az account lock show -n lockname
"""
helps['account lock update'] = """
type: command
short-summary: Update a subscription lock.
examples:
- name: Update a subscription lock with new notes and type
text: >
az account lock update --name lockName --notes newNotesHere --lock-type CanNotDelete
"""
helps['policy'] = """
type: group
short-summary: Manage resource policies.
Expand Down Expand Up @@ -483,6 +519,50 @@
type: group
short-summary: Manage deployment operations.
"""
helps['group lock'] = """
type: group
short-summary: Manage Azure resource group locks.
"""
helps['group lock create'] = """
type: command
short-summary: Create a resource group lock.
examples:
- name: Create a read-only resource group level lock.
text: >
az group lock create --lock-type ReadOnly -n lockName -g MyResourceGroup
"""
helps['group lock delete'] = """
type: command
short-summary: Delete a resource group lock.
examples:
- name: Delete a resource group lock
text: >
az group lock delete --name lockName -g MyResourceGroup
"""
helps['group lock list'] = """
type: command
short-summary: List lock information in the resource-group.
examples:
- name: List out all locks on the resource group level
text: >
az group lock list -g MyResourceGroup
"""
helps['group lock show'] = """
type: command
short-summary: Show the details of a resource group lock
examples:
- name: Show a resource group level lock
text: >
az group lock show -n lockname -g MyResourceGroup
"""
helps['group lock update'] = """
type: command
short-summary: Update a resource group lock.
examples:
- name: Update a resource group lock with new notes and type
text: >
az group lock update --name lockName -g MyResourceGroup --notes newNotesHere --lock-type CanNotDelete
"""
helps['provider'] = """
type: group
short-summary: Manage resource providers.
Expand Down Expand Up @@ -575,3 +655,47 @@
text: >
az resource link show --link-id <link-id>
"""
helps['resource lock'] = """
type: group
short-summary: Manage Azure resource level locks.
"""
helps['resource lock create'] = """
type: command
short-summary: Create a resource-level lock.
examples:
- name: Create a read-only resource level lock on a vnet.
text: >
az resource lock create --lock-type ReadOnly -n lockName -g MyResourceGroup --resource-name myvnet --resource-type Microsoft.Network/virtualNetworks
"""
helps['resource lock delete'] = """
type: command
short-summary: Delete a resource-level lock.
examples:
- name: Delete a resource level lock
text: >
az resource lock delete --name lockName -g MyResourceGroup --resource-name myvnet --resource-type Microsoft.Network/virtualNetworks
"""
helps['resource lock list'] = """
type: command
short-summary: List lock information in the resource-level.
examples:
- name: List out all locks on a vnet
text: >
az resource lock list -g MyResourceGroup --resource-name myvnet --resource-type Microsoft.Network/virtualNetworks
"""
helps['resource lock show'] = """
type: command
short-summary: Show the details of a resource-level lock
examples:
- name: Show a resource level lock
text: >
az resource lock show -n lockname -g MyResourceGroup --resource-name myvnet --resource-type Microsoft.Network/virtualNetworks
"""
helps['resource lock update'] = """
type: command
short-summary: Update a resource-level lock.
examples:
- name: Update a resource level lock with new notes and type
text: >
az resource lock update --name lockName -g MyResourceGroup --resource-name myvnet --resource-type Microsoft.Network/virtualNetworks --notes newNotesHere --lock-type CanNotDelete
"""
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
from .custom import (get_policy_completion_list, get_policy_set_completion_list,
get_policy_assignment_completion_list, get_resource_types_completion_list,
get_providers_completion_list)
from ._validators import process_deployment_create_namespace, validate_lock_parameters
from ._validators import (process_deployment_create_namespace, validate_lock_parameters, validate_subscription_lock,
validate_group_lock, validate_resource_lock)

# BASIC PARAMETER CONFIGURATION

Expand Down Expand Up @@ -134,15 +135,6 @@
register_cli_argument('tag', 'tag_name', options_list=('--name', '-n'))
register_cli_argument('tag', 'tag_value', options_list=('--value',))

register_cli_argument('lock', 'lock_name', options_list=('--name', '-n'), validator=validate_lock_parameters)
register_cli_argument('lock', 'level', options_list=('--lock-type', '-t'), **enum_choice_list(LockLevel))
register_cli_argument('lock', 'parent_resource_path', resource_parent_type)
register_cli_argument('lock', 'resource_provider_namespace', resource_namespace_type)
register_cli_argument('lock', 'resource_type', arg_type=resource_type_type,
completer=get_resource_types_completion_list,)
register_cli_argument('lock', 'resource_name', options_list=('--resource-name'))
register_cli_argument('lock', 'ids', nargs='+', options_list=('--ids'), help='One or more resource IDs (space delimited). If provided, no other "Resource Id" arguments should be specified.')

register_cli_argument('managedapp', 'resource_group_name', arg_type=resource_group_name_type, help='the resource group of the managed application', id_part='resource_group')
register_cli_argument('managedapp', 'application_name', options_list=('--name', '-n'), id_part='name')

Expand All @@ -159,3 +151,28 @@
register_cli_argument('managedapp definition create', 'authorizations', options_list=('--authorizations', '-a'), nargs='+', help="space separated authorization pairs in a format of <principalId>:<roleDefinitionId>")
register_cli_argument('managedapp definition create', 'createUiDefinition', options_list=('--create-ui-definition', '-c'), help='JSON formatted string or a path to a file with such content', type=file_type, completer=FilesCompleter())
register_cli_argument('managedapp definition create', 'mainTemplate', options_list=('--main-template', '-t'), help='JSON formatted string or a path to a file with such content', type=file_type, completer=FilesCompleter())

register_cli_argument('lock', 'parent_resource_path', resource_parent_type)
register_cli_argument('lock', 'resource_provider_namespace', resource_namespace_type)
register_cli_argument('lock', 'resource_type', arg_type=resource_type_type, completer=get_resource_types_completion_list)
register_cli_argument('lock', 'resource_name', options_list=('--resource-name'), help='Name of the resource being locked.')
register_cli_argument('lock', 'resource_group', resource_group_name_type, validator=validate_lock_parameters)

register_cli_argument('resource lock', 'resource_group', resource_group_name_type)
register_cli_argument('resource lock', 'resource_name', options_list=('--resource-name'), validator=validate_resource_lock)

register_cli_argument('group lock', 'resource_group', resource_group_name_type, validator=validate_group_lock)

register_cli_argument('account lock', 'resource_group', ignore_type, validator=validate_subscription_lock)

for scope in ['account', 'group']:
register_cli_argument('{} lock'.format(scope), 'resource_provider_namespace', ignore_type)
register_cli_argument('{} lock'.format(scope), 'parent_resource_path', ignore_type)
register_cli_argument('{} lock'.format(scope), 'resource_type', ignore_type)
register_cli_argument('{} lock'.format(scope), 'resource_name', ignore_type)

for command_name in ['lock', 'account lock', 'group lock', 'resource lock']:
register_cli_argument(command_name, 'lock_name', options_list=('--name', '-n'), help='Name of the lock')
register_cli_argument(command_name, 'level', options_list=('--lock-type', '-t'), **enum_choice_list([LockLevel.can_not_delete, LockLevel.read_only]))
register_cli_argument(command_name, 'ids', nargs='+', options_list=('--ids'), help='One or more resource IDs (space delimited). If provided, no other "Resource Id" arguments should be specified.')
register_cli_argument(command_name, 'notes', help='Notes about this lock.')
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


from azure.cli.core.util import CLIError
from .custom import _parse_lock_id


def _validate_deployment_name(namespace):
Expand All @@ -35,9 +36,9 @@ def process_deployment_create_namespace(namespace):
_validate_deployment_name(namespace)


def internal_validate_lock_parameters(resource_group_name, resource_provider_namespace,
def internal_validate_lock_parameters(resource_group, resource_provider_namespace,
parent_resource_path, resource_type, resource_name):
if resource_group_name is None:
if resource_group is None:
if resource_name is not None:
raise CLIError('--resource-name is ignored if --resource-group is not given.')
if resource_type is not None:
Expand Down Expand Up @@ -70,8 +71,46 @@ def internal_validate_lock_parameters(resource_group_name, resource_provider_nam


def validate_lock_parameters(namespace):
internal_validate_lock_parameters(getattr(namespace, 'resource_group_name', None),
internal_validate_lock_parameters(getattr(namespace, 'resource_group', None),
getattr(namespace, 'resource_provider_namespace', None),
getattr(namespace, 'parent_resource_path', None),
getattr(namespace, 'resource_type', None),
getattr(namespace, 'resource_name', None))


def validate_subscription_lock(namespace):
if getattr(namespace, 'ids', None):
for lock_id in getattr(namespace, 'ids'):
if _parse_lock_id(lock_id).get('resource_group'):
raise CLIError('{} is not a valid subscription-level lock id.'.format(lock_id))


def validate_group_lock(namespace):
if getattr(namespace, 'ids', None):
for lock_id in getattr(namespace, 'ids'):
lock_id_dict = _parse_lock_id(lock_id)
if not lock_id_dict.get('resource_group') or lock_id_dict.get('resource_name'):
raise CLIError('{} is not a valid group-level lock id.'.format(lock_id))
else:
if not getattr(namespace, 'resource_group', None):
raise CLIError('Missing required resource_group parameter.')


def validate_resource_lock(namespace):
if getattr(namespace, 'ids', None):
for lock_id in getattr(namespace, 'ids'):
lock_id_dict = _parse_lock_id(lock_id)
if not all((lock_id_dict.get(param)) for param in ['resource_group',
'resource_provider_namespace',
'resource_type',
'resource_name']):
raise CLIError('{} is not a valid resource-level lock id.'.format(lock_id))
else:
kwargs = {}
for param in ['resource_group', 'resource_type', 'resource_name']:
if not getattr(namespace, param, None):
raise CLIError('Missing required {} parameter.'.format(param))
kwargs[param] = getattr(namespace, param)
kwargs['resource_provider_namespace'] = getattr(namespace, 'resource_provider_namespace', None)
kwargs['parent_resource_path'] = getattr(namespace, 'parent_resource_path', None)
internal_validate_lock_parameters(**kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
cf_resource_managedappdefinitions)


# Subscription lock commands
cli_command(__name__, 'account lock create', 'azure.cli.command_modules.resource.custom#create_lock')
cli_command(__name__, 'account lock delete', 'azure.cli.command_modules.resource.custom#delete_lock')
cli_command(__name__, 'account lock list', 'azure.cli.command_modules.resource.custom#list_locks')
cli_command(__name__, 'account lock show', 'azure.cli.command_modules.resource.custom#get_lock',
exception_handler=empty_on_404)
cli_command(__name__, 'account lock update', 'azure.cli.command_modules.resource.custom#update_lock')


# Resource group commands
def transform_resource_group_list(result):
return [OrderedDict([('Name', r['name']), ('Location', r['location']), ('Status', r['properties']['provisioningState'])]) for r in result]
Expand All @@ -39,10 +48,15 @@ def transform_resource_group_list(result):
cli_command(__name__, 'group list', 'azure.cli.command_modules.resource.custom#list_resource_groups', table_transformer=transform_resource_group_list)
cli_command(__name__, 'group create', 'azure.cli.command_modules.resource.custom#create_resource_group')
cli_command(__name__, 'group export', 'azure.cli.command_modules.resource.custom#export_group_as_template')
cli_command(__name__, 'group lock create', 'azure.cli.command_modules.resource.custom#create_lock')
cli_command(__name__, 'group lock delete', 'azure.cli.command_modules.resource.custom#delete_lock')
cli_command(__name__, 'group lock list', 'azure.cli.command_modules.resource.custom#list_locks')
cli_command(__name__, 'group lock show', 'azure.cli.command_modules.resource.custom#get_lock',
exception_handler=empty_on_404)
cli_command(__name__, 'group lock update', 'azure.cli.command_modules.resource.custom#update_lock')


# Resource commands

def transform_resource_list(result):
transformed = []
for r in result:
Expand All @@ -62,6 +76,12 @@ def transform_resource_list(result):
cli_command(__name__, 'resource tag', 'azure.cli.command_modules.resource.custom#tag_resource')
cli_command(__name__, 'resource move', 'azure.cli.command_modules.resource.custom#move_resource')
cli_command(__name__, 'resource invoke-action', 'azure.cli.command_modules.resource.custom#invoke_resource_action')
cli_command(__name__, 'resource lock create', 'azure.cli.command_modules.resource.custom#create_lock')
cli_command(__name__, 'resource lock delete', 'azure.cli.command_modules.resource.custom#delete_lock')
cli_command(__name__, 'resource lock list', 'azure.cli.command_modules.resource.custom#list_locks')
cli_command(__name__, 'resource lock show', 'azure.cli.command_modules.resource.custom#get_lock',
exception_handler=empty_on_404)
cli_command(__name__, 'resource lock update', 'azure.cli.command_modules.resource.custom#update_lock')

# Resource provider commands
cli_command(__name__, 'provider list', 'azure.mgmt.resource.resources.operations.providers_operations#ProvidersOperations.list', cf_providers)
Expand Down
Loading

0 comments on commit bc50a23

Please sign in to comment.