Add exception_handler kwarg support to generic_update and generic_wait command registration. (#2901)

This commit is contained in:
Travis Prescott 2017-04-19 10:37:32 -07:00 коммит произвёл GitHub
Родитель 3cfa85b71f
Коммит 6da8f26313
3 изменённых файлов: 114 добавлений и 62 удалений

Просмотреть файл

@ -43,7 +43,17 @@
<Compile Include="azure-cli-core\azure\cli\core\extensions\__init__.py" />
<Compile Include="azure-cli-core\azure\cli\core\help_files.py" />
<Compile Include="azure-cli-core\azure\cli\core\parser.py" />
<Compile Include="azure-cli-core\azure\cli\core\profiles\_shared.py" />
<Compile Include="azure-cli-core\azure\cli\core\profiles\_shared.py" />
<Compile Include="azure-cli-core\azure\cli\core\profiles\__init__.py" />
<Compile Include="azure-cli-core\azure\cli\core\profiles\__init__.py" />
<Compile Include="azure-cli-core\azure\cli\core\prompting.py" />
<Compile Include="azure-cli-core\azure\cli\core\sdk\util.py" />
<Compile Include="azure-cli-core\azure\cli\core\sdk\util.py" />
<Compile Include="azure-cli-core\azure\cli\core\sdk\validators.py" />
<Compile Include="azure-cli-core\azure\cli\core\sdk\validators.py" />
<Compile Include="azure-cli-core\azure\cli\core\sdk\__init__.py" />
<Compile Include="azure-cli-core\azure\cli\core\sdk\__init__.py" />
<Compile Include="azure-cli-core\azure\cli\core\telemetry_upload.py" />
<Compile Include="azure-cli-core\azure\cli\core\test_utils\vcr_test_base.py" />
<Compile Include="azure-cli-core\azure\cli\core\test_utils\__init__.py" />
@ -583,6 +593,8 @@
<Folder Include="azure-cli-core\azure\cli\core\" />
<Folder Include="azure-cli-core\azure\cli\core\commands\" />
<Folder Include="azure-cli-core\azure\cli\core\extensions\" />
<Folder Include="azure-cli-core\azure\cli\core\profiles\" />
<Folder Include="azure-cli-core\azure\cli\core\sdk\" />
<Folder Include="azure-cli-core\azure\cli\core\test_utils\" />
<Folder Include="azure-cli-core\tests\" />
<Folder Include="azure-cli-core\tests\__pycache__\" />

Просмотреть файл

@ -10,10 +10,13 @@ from six import string_types
from azure.cli.core.commands import (CliCommand,
get_op_handler,
command_table as main_command_table,
command_module_map as main_command_module_map)
command_module_map as main_command_module_map,
CONFIRM_PARAM_NAME)
from azure.cli.core.commands._introspection import extract_args_from_signature
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azure.cli.core.application import APPLICATION, IterateValue
from azure.cli.core.prompting import prompt_y_n, NoTTYException
from azure.cli.core._config import az_config
import azure.cli.core.azlogging as azlogging
from azure.cli.core.util import CLIError, todict, shell_safe_json_parse
from azure.cli.core.profiles import ResourceType
@ -207,12 +210,25 @@ def _get_child(parent, collection_name, item_name, collection_key):
return result
def _user_confirmed(confirmation, command_args):
if callable(confirmation):
return confirmation(command_args)
try:
if isinstance(confirmation, string_types):
return prompt_y_n(confirmation)
return prompt_y_n('Are you sure you want to perform this operation?')
except NoTTYException:
logger.warning('Unable to prompt for confirmation as no tty available. Use --yes.')
return False
# pylint: disable=too-many-arguments
def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=None,
setter_arg_name='parameters', table_transformer=None,
child_collection_prop_name=None, child_collection_key='name',
child_arg_name='item_name', custom_function_op=None,
no_wait_param=None, transform=None):
no_wait_param=None, transform=None, confirmation=None,
exception_handler=None, formatter_class=None):
if not isinstance(getter_op, string_types):
raise ValueError("Getter operation must be a string. Got '{}'".format(getter_op))
if not isinstance(setter_op, string_types):
@ -246,6 +262,12 @@ def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=
def handler(args): # pylint: disable=too-many-branches,too-many-statements
from msrestazure.azure_operation import AzureOperationPoller
if confirmation \
and not args.items().get(CONFIRM_PARAM_NAME) \
and not az_config.getboolean('core', 'disable_confirm_prompt', fallback=False) \
and not _user_confirmed(confirmation, args.items()):
raise CLIError('Operation cancelled.')
ordered_arguments = args.pop('ordered_arguments', [])
for item in ['properties_to_add', 'properties_to_set', 'properties_to_remove']:
if args[item]:
@ -259,66 +281,73 @@ def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=
getterargs = {key: val for key, val in args.items() if key in get_arguments_loader()}
getter = get_op_handler(getter_op)
if child_collection_prop_name:
parent = getter(client, **getterargs) if client else getter(**getterargs)
instance = _get_child(
parent,
child_collection_prop_name,
args.get(child_arg_name),
child_collection_key
)
else:
parent = None
instance = getter(client, **getterargs) if client else getter(**getterargs)
# pass instance to the custom_function, if provided
if custom_function_op:
custom_function = get_op_handler(custom_function_op)
custom_func_args = {k: v for k, v in args.items() if k in function_arguments_loader()}
try:
if child_collection_prop_name:
parent = custom_function(instance, parent, **custom_func_args)
parent = getter(client, **getterargs) if client else getter(**getterargs)
instance = _get_child(
parent,
child_collection_prop_name,
args.get(child_arg_name),
child_collection_key
)
else:
instance = custom_function(instance, **custom_func_args)
parent = None
instance = getter(client, **getterargs) if client else getter(**getterargs)
# apply generic updates after custom updates
setterargs = {key: val for key, val in args.items() if key in set_arguments_loader()}
# pass instance to the custom_function, if provided
if custom_function_op:
custom_function = get_op_handler(custom_function_op)
custom_func_args = \
{k: v for k, v in args.items() if k in function_arguments_loader()}
if child_collection_prop_name:
parent = custom_function(instance, parent, **custom_func_args)
else:
instance = custom_function(instance, **custom_func_args)
for arg in ordered_arguments:
arg_type, arg_values = arg
if arg_type == '--set':
try:
for expression in arg_values:
set_properties(instance, expression)
except ValueError:
raise CLIError('invalid syntax: {}'.format(set_usage))
elif arg_type == '--add':
try:
add_properties(instance, arg_values)
except ValueError:
raise CLIError('invalid syntax: {}'.format(add_usage))
elif arg_type == '--remove':
try:
remove_properties(instance, arg_values)
except ValueError:
raise CLIError('invalid syntax: {}'.format(remove_usage))
# apply generic updates after custom updates
setterargs = {key: val for key, val in args.items() if key in set_arguments_loader()}
# Done... update the instance!
setterargs[setter_arg_name] = parent if child_collection_prop_name else instance
setter = get_op_handler(setter_op)
for arg in ordered_arguments:
arg_type, arg_values = arg
if arg_type == '--set':
try:
for expression in arg_values:
set_properties(instance, expression)
except ValueError:
raise CLIError('invalid syntax: {}'.format(set_usage))
elif arg_type == '--add':
try:
add_properties(instance, arg_values)
except ValueError:
raise CLIError('invalid syntax: {}'.format(add_usage))
elif arg_type == '--remove':
try:
remove_properties(instance, arg_values)
except ValueError:
raise CLIError('invalid syntax: {}'.format(remove_usage))
opres = setter(client, **setterargs) if client else setter(**setterargs)
# Done... update the instance!
setterargs[setter_arg_name] = parent if child_collection_prop_name else instance
setter = get_op_handler(setter_op)
if setterargs.get(no_wait_param, None):
return None
opres = setter(client, **setterargs) if client else setter(**setterargs)
result = opres.result() if isinstance(opres, AzureOperationPoller) else opres
if child_collection_prop_name:
result = _get_child(
result,
child_collection_prop_name,
args.get(child_arg_name),
child_collection_key
)
if setterargs.get(no_wait_param, None):
return None
result = opres.result() if isinstance(opres, AzureOperationPoller) else opres
if child_collection_prop_name:
result = _get_child(
result,
child_collection_prop_name,
args.get(child_arg_name),
child_collection_key
)
except Exception as ex: # pylint: disable=broad-except
if exception_handler:
result = exception_handler(ex)
else:
raise ex
# apply results transform if specified
if transform:
@ -334,7 +363,7 @@ def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=
namespace.ordered_arguments.append((option_string, values))
cmd = CliCommand(name, handler, table_transformer=table_transformer,
arguments_loader=arguments_loader)
arguments_loader=arguments_loader, formatter_class=formatter_class)
group_name = 'Generic Update'
cmd.add_argument('properties_to_set', '--set', nargs='+', action=OrderedArgsAction, default=[],
help='Update an object by specifying a property path and value to set.'
@ -352,7 +381,7 @@ def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=
main_command_module_map[name] = module_name
def cli_generic_wait_command(module_name, name, getter_op, factory=None):
def cli_generic_wait_command(module_name, name, getter_op, factory=None, exception_handler=None):
if not isinstance(getter_op, string_types):
raise ValueError("Getter operation must be a string. Got '{}'".format(type(getter_op)))
@ -374,6 +403,12 @@ def cli_generic_wait_command(module_name, name, getter_op, factory=None):
provisioning_state = getattr(properties, 'provisioning_state', None)
return provisioning_state
def _handle_exception(ex):
if exception_handler:
return exception_handler(ex)
else:
raise ex
def handler(args):
from msrest.exceptions import ClientException
import time
@ -418,9 +453,11 @@ def cli_generic_wait_command(module_name, name, getter_op, factory=None):
if wait_for_deleted:
return
if not any([wait_for_created, wait_for_exists, custom_condition]):
raise
_handle_exception(ex)
else:
raise
_handle_exception(ex)
except Exception as ex: # pylint: disable=broad-except
_handle_exception(ex)
time.sleep(interval)

Просмотреть файл

@ -9,6 +9,8 @@ from azure.cli.core.commands import cli_command
from azure.cli.core.commands.arm import cli_generic_update_command
from azure.cli.command_modules.redis._client_factory import (cf_redis, cf_patch_schedules)
from azure.cli.command_modules.redis.custom import wrong_vmsize_argument_exception_handler
cli_command(__name__, 'redis create', 'azure.cli.command_modules.redis.custom#cli_redis_create', cf_redis)
cli_command(__name__, 'redis delete', 'azure.mgmt.redis.operations.redis_operations#RedisOperations.delete', cf_redis)
cli_command(__name__, 'redis export', 'azure.cli.command_modules.redis.custom#cli_redis_export', cf_redis)
@ -21,11 +23,12 @@ cli_command(__name__, 'redis regenerate-keys', 'azure.mgmt.redis.operations.redi
cli_command(__name__, 'redis show', 'azure.mgmt.redis.operations.redis_operations#RedisOperations.get', cf_redis)
cli_command(__name__, 'redis update-settings', 'azure.cli.command_modules.redis.custom#cli_redis_update_settings', cf_redis)
cli_generic_update_command(__name__, 'redis update', 'azure.mgmt.redis.operations.redis_operations#RedisOperations.get',
'azure.mgmt.redis.operations.redis_operations#RedisOperations.create_or_update',
cf_redis, custom_function_op='azure.cli.command_modules.redis.custom#cli_redis_update')
cli_generic_update_command(__name__, 'redis update',
'azure.mgmt.redis.operations.redis_operations#RedisOperations.get',
'azure.mgmt.redis.operations.redis_operations#RedisOperations.create_or_update', cf_redis,
custom_function_op='azure.cli.command_modules.redis.custom#cli_redis_update',
exception_handler=wrong_vmsize_argument_exception_handler)
cli_command(__name__, 'redis patch-schedule set', 'azure.mgmt.redis.operations.patch_schedules_operations#PatchSchedulesOperations.create_or_update', cf_patch_schedules)
cli_command(__name__, 'redis patch-schedule delete', 'azure.mgmt.redis.operations.patch_schedules_operations#PatchSchedulesOperations.delete', cf_patch_schedules)
cli_command(__name__, 'redis patch-schedule show', 'azure.mgmt.redis.operations.patch_schedules_operations#PatchSchedulesOperations.get', cf_patch_schedules)