def handler(args): from msrest.exceptions import ClientException import time try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None getterargs = { key: val for key, val in args.items() if key in get_arguments_loader() } getter = get_op_handler(getter_op) timeout = args.pop('timeout') interval = args.pop('interval') wait_for_created = args.pop('created') wait_for_deleted = args.pop('deleted') wait_for_updated = args.pop('updated') wait_for_exists = args.pop('exists') custom_condition = args.pop('custom') if not any([ wait_for_created, wait_for_updated, wait_for_deleted, wait_for_exists, custom_condition ]): raise CLIError( "incorrect usage: --created | --updated | --deleted | --exists | --custom JMESPATH") # pylint: disable=line-too-long for _ in range(0, timeout, interval): try: instance = getter(client, **getterargs) if client else getter( **getterargs) if wait_for_exists: return provisioning_state = get_provisioning_state(instance) # until we have any needs to wait for 'Failed', let us bail out on this if provisioning_state == 'Failed': raise CLIError('The operation failed') if wait_for_created or wait_for_updated: if provisioning_state == 'Succeeded': return if custom_condition and bool( verify_property(instance, custom_condition)): return except ClientException as ex: if getattr(ex, 'status_code', None) == 404: if wait_for_deleted: return if not any( [wait_for_created, wait_for_exists, custom_condition]): raise else: raise time.sleep(interval) return CLIError( 'Wait operation timed-out after {} seconds'.format(timeout))
def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from msrestazure.azure_operation import AzureOperationPoller from azure.cli.core._profile import Profile from azure.cli.command_modules.keyvault.keyvaultclient import \ (KeyVaultClient, KeyVaultAuthentication) from azure.cli.command_modules.keyvault.keyvaultclient.generated import \ (KeyVaultClient as BaseKeyVaultClient) from azure.cli.command_modules.keyvault.keyvaultclient.generated.models import \ (KeyVaultErrorException) try: def get_token(server, resource, scope): # pylint: disable=unused-argument return Profile().get_login_credentials( resource)[0]._token_retriever() # pylint: disable=protected-access op = get_op_handler(operation) # since the convenience client can be inconvenient, we have to check and create the # correct client version if 'generated' in op.__module__: client = BaseKeyVaultClient(KeyVaultAuthentication(get_token)) else: client = KeyVaultClient(KeyVaultAuthentication(get_token)) # pylint: disable=redefined-variable-type result = op(client, **kwargs) # apply results transform if specified if transform_result: return _encode_hex(transform_result(result)) # otherwise handle based on return type of results if isinstance(result, AzureOperationPoller): return _encode_hex( LongRunningOperation('Starting {}'.format(name))(result)) elif isinstance(result, Paged): try: return _encode_hex(list(result)) except TypeError: # TODO: Workaround for an issue in either KeyVault server-side or msrest # See https://github.com/Azure/autorest/issues/1309 return [] else: return _encode_hex(result) except (ValidationError, KeyVaultErrorException) as ex: try: raise CLIError(ex.inner_exception.error.message) except AttributeError: raise CLIError(ex) except ClientRequestError as ex: if 'Failed to establish a new connection' in str( ex.inner_exception): raise CLIError( 'Max retries exceeded attempting to connect to vault. ' 'The vault may not exist or you may need to flush your DNS cache ' 'and try again later.') raise CLIError(ex)
def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from msrestazure.azure_operation import AzureOperationPoller from azure.cli.core._profile import Profile from azure.keyvault import KeyVaultClient, KeyVaultAuthentication from azure.keyvault.models import KeyVaultErrorException try: def get_token(server, resource, scope): # pylint: disable=unused-argument import adal try: return Profile().get_login_credentials(resource)[0]._token_retriever() # pylint: disable=protected-access except adal.AdalError as err: # pylint: disable=no-member if (hasattr(err, 'error_response') and ('error_description' in err.error_response) and ('AADSTS70008:' in err.error_response['error_description'])): raise CLIError( "Credentials have expired due to inactivity. Please run 'az login'") raise CLIError(err) op = get_op_handler(operation) # since the convenience client can be inconvenient, we have to check and create the # correct client version client = KeyVaultClient(KeyVaultAuthentication(get_token)) result = op(client, **kwargs) # apply results transform if specified if transform_result: return _encode_hex(transform_result(result)) # otherwise handle based on return type of results if isinstance(result, AzureOperationPoller): return _encode_hex(LongRunningOperation('Starting {}'.format(name))(result)) elif isinstance(result, Paged): try: return _encode_hex(list(result)) except TypeError: # TODO: Workaround for an issue in either KeyVault server-side or msrest # See https://github.com/Azure/autorest/issues/1309 return [] else: return _encode_hex(result) except (ValidationError, KeyVaultErrorException) as ex: try: raise CLIError(ex.inner_exception.error.message) except AttributeError: raise CLIError(ex) except ClientRequestError as ex: if 'Failed to establish a new connection' in str(ex.inner_exception): raise CLIError('Max retries exceeded attempting to connect to vault. ' 'The vault may not exist or you may need to flush your DNS cache ' 'and try again later.') raise CLIError(ex)
def handler(args): from msrest.exceptions import ClientException import time try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None getterargs = {key: val for key, val in args.items() if key in get_arguments_loader()} getter = get_op_handler(getter_op) timeout = args.pop('timeout') interval = args.pop('interval') wait_for_created = args.pop('created') wait_for_deleted = args.pop('deleted') wait_for_updated = args.pop('updated') wait_for_exists = args.pop('exists') custom_condition = args.pop('custom') if not any([wait_for_created, wait_for_updated, wait_for_deleted, wait_for_exists, custom_condition]): raise CLIError( "incorrect usage: --created | --updated | --deleted | --exists | --custom JMESPATH") for _ in range(0, timeout, interval): try: instance = getter(client, **getterargs) if client else getter(**getterargs) if wait_for_exists: return provisioning_state = get_provisioning_state(instance) # until we have any needs to wait for 'Failed', let us bail out on this if provisioning_state == 'Failed': raise CLIError('The operation failed') if wait_for_created or wait_for_updated: if provisioning_state == 'Succeeded': return if custom_condition and bool(verify_property(instance, custom_condition)): return except ClientException as ex: if getattr(ex, 'status_code', None) == 404: if wait_for_deleted: return if not any([wait_for_created, wait_for_exists, custom_condition]): _handle_exception(ex) else: _handle_exception(ex) except Exception as ex: # pylint: disable=broad-except _handle_exception(ex) time.sleep(interval) return CLIError('Wait operation timed-out after {} seconds'.format(timeout))
def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from msrestazure.azure_operation import AzureOperationPoller from azure.cli.core._profile import Profile from azure.cli.command_modules.keyvault.keyvaultclient import \ (KeyVaultClient, KeyVaultAuthentication) from azure.cli.command_modules.keyvault.keyvaultclient.generated import \ (KeyVaultClient as BaseKeyVaultClient) from azure.cli.command_modules.keyvault.keyvaultclient.generated.models import \ (KeyVaultErrorException) try: def get_token(server, resource, scope): # pylint: disable=unused-argument return Profile().get_login_credentials(resource)[0]._token_retriever() # pylint: disable=protected-access op = get_op_handler(operation) # since the convenience client can be inconvenient, we have to check and create the # correct client version if 'generated' in op.__module__: client = BaseKeyVaultClient(KeyVaultAuthentication(get_token)) else: client = KeyVaultClient(KeyVaultAuthentication(get_token)) # pylint: disable=redefined-variable-type result = op(client, **kwargs) # apply results transform if specified if transform_result: return _encode_hex(transform_result(result)) # otherwise handle based on return type of results if isinstance(result, AzureOperationPoller): return _encode_hex(LongRunningOperation('Starting {}'.format(name))(result)) elif isinstance(result, Paged): try: return _encode_hex(list(result)) except TypeError: # TODO: Workaround for an issue in either KeyVault server-side or msrest # See https://github.com/Azure/autorest/issues/1309 return [] else: return _encode_hex(result) except (ValidationError, KeyVaultErrorException) as ex: try: raise CLIError(ex.inner_exception.error.message) except AttributeError: raise CLIError(ex) except ClientRequestError as ex: if 'Failed to establish a new connection' in str(ex.inner_exception): raise CLIError('Max retries exceeded attempting to connect to vault. ' 'The vault may not exist or you may need to flush your DNS cache ' 'and try again later.') raise CLIError(ex)
def set_arguments_loader(): return dict( extract_args_from_signature(get_op_handler(setter_op), no_wait_param=no_wait_param))
def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from azure.batch.models import BatchErrorException from azure.cli.core._util import CLIError from azure.cli.core._config import az_config from azure.cli.core.commands import _user_confirmed if self._cancel_operation(kwargs, az_config, _user_confirmed): raise CLIError('Operation cancelled.') try: client = factory(kwargs) self._build_options(kwargs) stream_output = kwargs.pop('destination', None) json_file = kwargs.pop('json_file', None) # Build the request parameters from command line arguments if json_file: self.parser.deserialize_json(client, kwargs, json_file) for arg, _ in self.parser: del kwargs[arg] else: for arg, details in self.parser: try: param_value = kwargs.pop(arg) if param_value is None: continue else: self._build_parameters( details['path'], kwargs, details['root'], param_value) except KeyError: continue # Make request op = get_op_handler(operation) result = op(client, **kwargs) # File download if stream_output: with open(stream_output, "wb") as file_handle: for data in result: file_handle.write(data) return # Apply results transform if specified elif transform_result: return transform_result(result) # Otherwise handle based on return type of results elif isinstance(result, Paged): return list(result) else: return result except BatchErrorException as ex: try: message = ex.error.message.value if ex.error.values: for detail in ex.error.values: message += "\n{}: {}".format(detail.key, detail.value) raise CLIError(message) except AttributeError: raise CLIError(ex) except (ValidationError, ClientRequestError) as ex: raise CLIError(ex)
def __init__( self, module_name, name, # pylint:disable=too-many-statements operation, factory, transform_result, flatten, ignore, validator, silent): if not isinstance(operation, string_types): raise ValueError( "Operation must be a string. Got '{}'".format(operation)) self.flatten = flatten # Number of object levels to flatten self.silent = silent if silent else [] self.ignore = list(IGNORE_PARAMETERS) # Parameters to ignore if ignore: self.ignore.extend(ignore) self.parser = None self.validator = validator self.confirmation = 'delete' in operation self.head_cmd = False # The name of the request options parameter self._options_param = format_options_name(operation) # Arguments used for request options self._options_attrs = [] # The loaded options model to populate for the request self._options_model = None def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from azure.batch.models import BatchErrorException from azure.cli.core.util import CLIError from azure.cli.core._config import az_config from azure.cli.core.commands import _user_confirmed if self._cancel_operation(kwargs, az_config, _user_confirmed): raise CLIError('Operation cancelled.') try: client = factory(kwargs) self._build_options(kwargs) stream_output = kwargs.pop('destination', None) json_file = kwargs.pop('json_file', None) # Build the request parameters from command line arguments if json_file: self.parser.deserialize_json(client, kwargs, json_file) for arg, _ in self.parser: del kwargs[arg] else: for arg, details in self.parser: try: param_value = kwargs.pop(arg) if param_value is None: continue else: self._build_parameters(details['path'], kwargs, details['root'], param_value) except KeyError: continue # Make request op = get_op_handler(operation) if self.head_cmd: kwargs['raw'] = True result = op(client, **kwargs) # Head output if self.head_cmd: return transformers.transform_response_headers(result) # File download if stream_output: with open(stream_output, "wb") as file_handle: for data in result: file_handle.write(data) return # Apply results transform if specified elif transform_result: return transform_result(result) # Otherwise handle based on return type of results elif isinstance(result, Paged): return list(result) return result except BatchErrorException as ex: try: message = ex.error.message.value if ex.error.values: for detail in ex.error.values: message += "\n{}: {}".format( detail.key, detail.value) raise CLIError(message) except AttributeError: raise CLIError(ex) except (ValidationError, ClientRequestError) as ex: raise CLIError(ex) table_transformer = None try: transform_func = '_'.join(name.split()[1:]).replace('-', '_') table_transformer = getattr(transformers, transform_func + "_table_format") except AttributeError: pass command_module_map[name] = module_name self.cmd = CliCommand( ' '.join(name.split()), _execute_command, table_transformer=table_transformer, arguments_loader=lambda: self._load_transformed_arguments( get_op_handler(operation)), description_loader=lambda: extract_full_summary_from_signature( get_op_handler(operation)))
def handler(args): # pylint: disable=too-many-branches,too-many-statements from msrestazure.azure_operation import AzureOperationPoller ordered_arguments = args.pop('ordered_arguments', []) for item in ['properties_to_add', 'properties_to_set', 'properties_to_remove']: if args[item]: raise CLIError("Unexpected '{}' was not empty.".format(item)) del args[item] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates setterargs = {key: val for key, val in args.items() if key in set_arguments_loader()} 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)) # Done... update the instance! setterargs[setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) opres = setter(client, **setterargs) if client else setter(**setterargs) 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 ) # apply results transform if specified if transform: return transform(result) return result
def set_arguments_loader(): return dict(extract_args_from_signature(get_op_handler(setter_op), no_wait_param=no_wait_param))
def _create_key_vault_command(module_name, name, operation, transform_result, table_transformer): if not isinstance(operation, string_types): raise ValueError("Operation must be a string. Got '{}'".format(operation)) def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from msrestazure.azure_operation import AzureOperationPoller from azure.cli.core._profile import Profile from azure.keyvault import \ (KeyVaultClient, KeyVaultAuthentication) from azure.keyvault.generated import \ (KeyVaultClient as BaseKeyVaultClient) from azure.keyvault.generated.models import \ (KeyVaultErrorException) try: def get_token(server, resource, scope): # pylint: disable=unused-argument import adal try: return Profile().get_login_credentials(resource)[0]._token_retriever() # pylint: disable=protected-access except adal.AdalError as err: #pylint: disable=no-member if (hasattr(err, 'error_response') and ('error_description' in err.error_response) and ('AADSTS70008:' in err.error_response['error_description'])): raise CLIError( "Credentials have expired due to inactivity. Please run 'az login'") raise CLIError(err) op = get_op_handler(operation) # since the convenience client can be inconvenient, we have to check and create the # correct client version if 'generated' in op.__module__: client = BaseKeyVaultClient(KeyVaultAuthentication(get_token)) else: client = KeyVaultClient(KeyVaultAuthentication(get_token)) # pylint: disable=redefined-variable-type result = op(client, **kwargs) # apply results transform if specified if transform_result: return _encode_hex(transform_result(result)) # otherwise handle based on return type of results if isinstance(result, AzureOperationPoller): return _encode_hex(LongRunningOperation('Starting {}'.format(name))(result)) elif isinstance(result, Paged): try: return _encode_hex(list(result)) except TypeError: # TODO: Workaround for an issue in either KeyVault server-side or msrest # See https://github.com/Azure/autorest/issues/1309 return [] else: return _encode_hex(result) except (ValidationError, KeyVaultErrorException) as ex: try: raise CLIError(ex.inner_exception.error.message) except AttributeError: raise CLIError(ex) except ClientRequestError as ex: if 'Failed to establish a new connection' in str(ex.inner_exception): raise CLIError('Max retries exceeded attempting to connect to vault. ' 'The vault may not exist or you may need to flush your DNS cache ' 'and try again later.') raise CLIError(ex) command_module_map[name] = module_name name = ' '.join(name.split()) arguments_loader = lambda: extract_args_from_signature(get_op_handler(operation)) description_loader = lambda: extract_full_summary_from_signature(get_op_handler(operation)) cmd = CliCommand(name, _execute_command, table_transformer=table_transformer, arguments_loader=arguments_loader, description_loader=description_loader) return cmd
def get_arguments_loader(): return dict(extract_args_from_signature(get_op_handler(getter_op)))
def description_loader(): return extract_full_summary_from_signature(get_op_handler(operation))
def arguments_loader(): return extract_args_from_signature(get_op_handler(operation))
def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=None, setter_arg_name='parameters', # pylint: disable=too-many-arguments, line-too-long table_transformer=None, child_collection_prop_name=None, child_collection_key='name', child_arg_name='item_name', custom_function_op=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): raise ValueError("Setter operation must be a string. Got '{}'".format(setter_op)) if custom_function_op and not isinstance(custom_function_op, string_types): raise ValueError("Custom function operation must be a string. Got '{}'".format(custom_function_op)) #pylint: disable=line-too-long get_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(getter_op))) set_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(setter_op))) function_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(custom_function_op))) if custom_function_op else {} #pylint: disable=line-too-long def arguments_loader(): arguments = {} arguments.update(set_arguments_loader()) arguments.update(get_arguments_loader()) arguments.update(function_arguments_loader()) arguments.pop('instance', None) # inherited from custom_function(instance, ...) arguments.pop('parent', None) arguments.pop('expand', None) # possibly inherited from the getter arguments.pop(setter_arg_name, None) return arguments def handler(args): from msrestazure.azure_operation import AzureOperationPoller ordered_arguments = args.pop('ordered_arguments') if 'ordered_arguments' in args else [] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates for k in args.copy().keys(): if k in get_arguments_loader() or k in set_arguments_loader() \ or k in ('properties_to_add', 'properties_to_remove', 'properties_to_set'): args.pop(k) for key, val in args.items(): ordered_arguments.append((key, val)) 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)) # Done... update the instance! getterargs[setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) opres = setter(client, **getterargs) if client else setter(**getterargs) result = opres.result() if isinstance(opres, AzureOperationPoller) else opres if child_collection_prop_name: return _get_child( result, child_collection_prop_name, args.get(child_arg_name), child_collection_key ) else: return result class OrderedArgsAction(argparse.Action): #pylint:disable=too-few-public-methods def __call__(self, parser, namespace, values, option_string=None): if not getattr(namespace, 'ordered_arguments', None): setattr(namespace, 'ordered_arguments', []) namespace.ordered_arguments.append((option_string, values)) cmd = CliCommand(name, handler, table_transformer=table_transformer, arguments_loader=arguments_loader) 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.' ' Example: {}'.format(set_usage), metavar='KEY=VALUE', arg_group=group_name) cmd.add_argument('properties_to_add', '--add', nargs='+', action=OrderedArgsAction, default=[], help='Add an object to a list of objects by specifying a path and key' ' value pairs. Example: {}'.format(add_usage), metavar='LIST KEY=VALUE', arg_group=group_name) cmd.add_argument('properties_to_remove', '--remove', nargs='+', action=OrderedArgsAction, default=[], help='Remove a property or an element from a list. Example: ' '{}'.format(remove_usage), metavar='LIST INDEX', arg_group=group_name) main_command_table[name] = cmd main_command_module_map[name] = module_name
def _create_key_vault_command(module_name, name, operation, transform_result, table_transformer): if not isinstance(operation, string_types): raise ValueError("Operation must be a string. Got '{}'".format(operation)) def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from msrestazure.azure_operation import AzureOperationPoller from azure.cli.core._profile import Profile from azure.keyvault import KeyVaultClient, KeyVaultAuthentication from azure.keyvault.generated import KeyVaultClient as BaseKeyVaultClient from azure.keyvault.generated.models import KeyVaultErrorException try: def get_token(server, resource, scope): # pylint: disable=unused-argument try: return ( Profile().get_login_credentials(resource)[0]._token_retriever() ) # pylint: disable=protected-access except adal.AdalError as err: # pylint: disable=no-member if ( hasattr(err, "error_response") and ("error_description" in err.error_response) and ("AADSTS70008:" in err.error_response["error_description"]) ): raise CLIError("Credentials have expired due to inactivity. Please run 'az login'") raise CLIError(err) op = get_op_handler(operation) # since the convenience client can be inconvenient, we have to check and create the # correct client version if "generated" in op.__module__: client = BaseKeyVaultClient(KeyVaultAuthentication(get_token)) else: client = KeyVaultClient(KeyVaultAuthentication(get_token)) # pylint: disable=redefined-variable-type result = op(client, **kwargs) # apply results transform if specified if transform_result: return _encode_hex(transform_result(result)) # otherwise handle based on return type of results if isinstance(result, AzureOperationPoller): return _encode_hex(LongRunningOperation("Starting {}".format(name))(result)) elif isinstance(result, Paged): try: return _encode_hex(list(result)) except TypeError: # TODO: Workaround for an issue in either KeyVault server-side or msrest # See https://github.com/Azure/autorest/issues/1309 return [] else: return _encode_hex(result) except (ValidationError, KeyVaultErrorException) as ex: try: raise CLIError(ex.inner_exception.error.message) except AttributeError: raise CLIError(ex) except ClientRequestError as ex: if "Failed to establish a new connection" in str(ex.inner_exception): raise CLIError( "Max retries exceeded attempting to connect to vault. " "The vault may not exist or you may need to flush your DNS cache " "and try again later." ) raise CLIError(ex) command_module_map[name] = module_name name = " ".join(name.split()) arguments_loader = lambda: extract_args_from_signature(get_op_handler(operation)) description_loader = lambda: extract_full_summary_from_signature(get_op_handler(operation)) cmd = CliCommand( name, _execute_command, table_transformer=table_transformer, arguments_loader=arguments_loader, description_loader=description_loader, ) return cmd
def function_arguments_loader(): return dict(extract_args_from_signature(get_op_handler(custom_function_op))) \ if custom_function_op else {}
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]: raise CLIError("Unexpected '{}' was not empty.".format(item)) del args[item] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None getterargs = { key: val for key, val in args.items() if key in get_arguments_loader() } getter = get_op_handler(getter_op) try: 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates setterargs = { key: val for key, val in args.items() if key in set_arguments_loader() } 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)) # Done... update the instance! setterargs[ setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) opres = setter(client, **setterargs) if client else setter( **setterargs) 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: return transform(result) return result
def handler(args): from msrestazure.azure_operation import AzureOperationPoller ordered_arguments = args.pop('ordered_arguments') if 'ordered_arguments' in args else [] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates for k in args.copy().keys(): if k in get_arguments_loader() or k in set_arguments_loader() \ or k in ('properties_to_add', 'properties_to_remove', 'properties_to_set'): args.pop(k) for key, val in args.items(): ordered_arguments.append((key, val)) 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)) # Done... update the instance! getterargs[setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) opres = setter(client, **getterargs) if client else setter(**getterargs) result = opres.result() if isinstance(opres, AzureOperationPoller) else opres if child_collection_prop_name: return _get_child( result, child_collection_prop_name, args.get(child_arg_name), child_collection_key ) else: return result
def cli_generic_update_command(module_name, name, getter_op, setter_op, factory=None, setter_arg_name='parameters', # pylint: disable=too-many-arguments, line-too-long 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): 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): raise ValueError("Setter operation must be a string. Got '{}'".format(setter_op)) if custom_function_op and not isinstance(custom_function_op, string_types): raise ValueError("Custom function operation must be a string. Got '{}'".format(custom_function_op)) #pylint: disable=line-too-long get_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(getter_op))) set_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(setter_op), no_wait_param=no_wait_param)) #pylint: disable=line-too-long function_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(custom_function_op))) if custom_function_op else {} #pylint: disable=line-too-long def arguments_loader(): arguments = {} arguments.update(set_arguments_loader()) arguments.update(get_arguments_loader()) arguments.update(function_arguments_loader()) arguments.pop('instance', None) # inherited from custom_function(instance, ...) arguments.pop('parent', None) arguments.pop('expand', None) # possibly inherited from the getter arguments.pop(setter_arg_name, None) return arguments def handler(args):#pylint: disable=too-many-branches,too-many-statements from msrestazure.azure_operation import AzureOperationPoller ordered_arguments = args.pop('ordered_arguments') if 'ordered_arguments' in args else [] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates setterargs = set_arguments_loader() for k in args.copy().keys(): if k in get_arguments_loader() or k in setterargs \ or k in ('properties_to_add', 'properties_to_remove', 'properties_to_set'): args.pop(k) for key, val in args.items(): ordered_arguments.append((key, val)) 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)) # Done... update the instance! getterargs[setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) no_wait = no_wait_param and setterargs.get(no_wait_param, None) if no_wait: getterargs[no_wait_param] = True opres = setter(client, **getterargs) if client else setter(**getterargs) if no_wait: 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 ) # apply results transform if specified if transform: return transform(result) return result class OrderedArgsAction(argparse.Action): #pylint:disable=too-few-public-methods def __call__(self, parser, namespace, values, option_string=None): if not getattr(namespace, 'ordered_arguments', None): setattr(namespace, 'ordered_arguments', []) namespace.ordered_arguments.append((option_string, values)) cmd = CliCommand(name, handler, table_transformer=table_transformer, arguments_loader=arguments_loader) 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.' ' Example: {}'.format(set_usage), metavar='KEY=VALUE', arg_group=group_name) cmd.add_argument('properties_to_add', '--add', nargs='+', action=OrderedArgsAction, default=[], help='Add an object to a list of objects by specifying a path and key' ' value pairs. Example: {}'.format(add_usage), metavar='LIST KEY=VALUE', arg_group=group_name) cmd.add_argument('properties_to_remove', '--remove', nargs='+', action=OrderedArgsAction, default=[], help='Remove a property or an element from a list. Example: ' '{}'.format(remove_usage), metavar='LIST INDEX', arg_group=group_name) main_command_table[name] = cmd main_command_module_map[name] = module_name
def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from msrestazure.azure_operation import AzureOperationPoller from azure.cli.core._profile import Profile from azure.keyvault import KeyVaultClient, KeyVaultAuthentication from azure.keyvault.models import KeyVaultErrorException try: def get_token(server, resource, scope): # pylint: disable=unused-argument import adal try: return Profile().get_login_credentials( resource)[0]._token_retriever() # pylint: disable=protected-access except adal.AdalError as err: # pylint: disable=no-member if (hasattr(err, 'error_response') and ('error_description' in err.error_response) and ('AADSTS70008:' in err.error_response['error_description'])): raise CLIError( "Credentials have expired due to inactivity. Please run 'az login'" ) raise CLIError(err) op = get_op_handler(operation) # since the convenience client can be inconvenient, we have to check and create the # correct client version client = KeyVaultClient(KeyVaultAuthentication(get_token)) result = op(client, **kwargs) # apply results transform if specified if transform_result: return _encode_hex(transform_result(result)) # otherwise handle based on return type of results if isinstance(result, AzureOperationPoller): return _encode_hex( LongRunningOperation('Starting {}'.format(name))(result)) elif isinstance(result, Paged): try: return _encode_hex(list(result)) except TypeError: # TODO: Workaround for an issue in either KeyVault server-side or msrest # See https://github.com/Azure/autorest/issues/1309 return [] else: return _encode_hex(result) except (ValidationError, KeyVaultErrorException) as ex: try: raise CLIError(ex.inner_exception.error.message) except AttributeError: raise CLIError(ex) except ClientRequestError as ex: if 'Failed to establish a new connection' in str( ex.inner_exception): raise CLIError( 'Max retries exceeded attempting to connect to vault. ' 'The vault may not exist or you may need to flush your DNS cache ' 'and try again later.') raise CLIError(ex)
def handler(args):#pylint: disable=too-many-branches,too-many-statements from msrestazure.azure_operation import AzureOperationPoller ordered_arguments = args.pop('ordered_arguments') if 'ordered_arguments' in args else [] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates setterargs = set_arguments_loader() for k in args.copy().keys(): if k in get_arguments_loader() or k in setterargs \ or k in ('properties_to_add', 'properties_to_remove', 'properties_to_set'): args.pop(k) for key, val in args.items(): ordered_arguments.append((key, val)) 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)) # Done... update the instance! getterargs[setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) no_wait = no_wait_param and setterargs.get(no_wait_param, None) if no_wait: getterargs[no_wait_param] = True opres = setter(client, **getterargs) if client else setter(**getterargs) if no_wait: 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 ) # apply results transform if specified if transform: return transform(result) return result
def cli_generic_wait_command(module_name, name, getter_op, factory=None): if not isinstance(getter_op, string_types): raise ValueError("Getter operation must be a string. Got '{}'".format(type(getter_op))) get_arguments_loader = lambda: dict(extract_args_from_signature(get_op_handler(getter_op))) def arguments_loader(): arguments = {} arguments.update(get_arguments_loader()) return arguments def get_provisioning_state(instance): provisioning_state = getattr(instance, 'provisioning_state', None) if not provisioning_state: #some SDK, like resource-group, has 'provisioning_state' under 'properties' properties = getattr(instance, 'properties', None) if properties: provisioning_state = getattr(properties, 'provisioning_state', None) return provisioning_state def handler(args): from msrest.exceptions import ClientException import time try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None getterargs = {key: val for key, val in args.items() if key in get_arguments_loader()} getter = get_op_handler(getter_op) timeout = args.pop('timeout') interval = args.pop('interval') wait_for_created = args.pop('created') wait_for_deleted = args.pop('deleted') wait_for_updated = args.pop('updated') wait_for_exists = args.pop('exists') custom_condition = args.pop('custom') if not any([wait_for_created, wait_for_updated, wait_for_deleted, wait_for_exists, custom_condition]): raise CLIError("incorrect usage: --created | --updated | --deleted | --exists | --custom JMESPATH")#pylint: disable=line-too-long for _ in range(0, timeout, interval): try: instance = getter(client, **getterargs) if client else getter(**getterargs) if wait_for_exists: return provisioning_state = get_provisioning_state(instance) #until we have any needs to wait for 'Failed', let us bail out on this if provisioning_state == 'Failed': raise CLIError('The operation failed') if wait_for_created or wait_for_updated: if provisioning_state == 'Succeeded': return if custom_condition and bool(verify_property(instance, custom_condition)): return except ClientException as ex: if getattr(ex, 'status_code', None) == 404: if wait_for_deleted: return if not any([wait_for_created, wait_for_exists, custom_condition]): raise else: raise time.sleep(interval) return CLIError('Wait operation timed-out after {} seconds'.format(timeout)) cmd = CliCommand(name, handler, arguments_loader=arguments_loader) group_name = 'Wait Condition' cmd.add_argument('timeout', '--timeout', default=3600, arg_group=group_name, type=int, help='maximum wait in seconds') cmd.add_argument('interval', '--interval', default=30, arg_group=group_name, type=int, help='polling interval in seconds') cmd.add_argument('deleted', '--deleted', action='store_true', arg_group=group_name, help='wait till deleted') cmd.add_argument('created', '--created', action='store_true', arg_group=group_name, help="wait till created with 'provisioningState' at 'Succeeded'") cmd.add_argument('updated', '--updated', action='store_true', arg_group=group_name, help="wait till updated with provisioningState at 'Succeeded'") cmd.add_argument('exists', '--exists', action='store_true', arg_group=group_name, help="wait till the resource exists") cmd.add_argument('custom', '--custom', arg_group=group_name, help=("Wait until the condition satisfies a custom JMESPath query. E.g. " "provisioningState!='InProgress', " "instanceView.statuses[?code=='PowerState/running']")) main_command_table[name] = cmd main_command_module_map[name] = module_name
def __init__(self, module_name, name, operation, factory, transform_result, # pylint:disable=too-many-arguments table_transformer, flatten, ignore, validator, silent): if not isinstance(operation, string_types): raise ValueError("Operation must be a string. Got '{}'".format(operation)) self.flatten = flatten # Number of object levels to flatten self.silent = silent if silent else [] self.ignore = list(IGNORE_PARAMETERS) # Parameters to ignore if ignore: self.ignore.extend(ignore) self.parser = None self.validator = validator self.confirmation = 'delete' in operation # The name of the request options parameter self._options_param = format_options_name(operation) # Arguments used for request options self._options_attrs = [] # The loaded options model to populate for the request self._options_model = None def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from azure.batch.models import BatchErrorException from azure.cli.core._util import CLIError from azure.cli.core._config import az_config from azure.cli.core.commands import _user_confirmed if self._cancel_operation(kwargs, az_config, _user_confirmed): raise CLIError('Operation cancelled.') try: client = factory(kwargs) self._build_options(kwargs) stream_output = kwargs.pop('destination', None) json_file = kwargs.pop('json_file', None) # Build the request parameters from command line arguments if json_file: self.parser.deserialize_json(client, kwargs, json_file) for arg, _ in self.parser: del kwargs[arg] else: for arg, details in self.parser: try: param_value = kwargs.pop(arg) if param_value is None: continue else: self._build_parameters( details['path'], kwargs, details['root'], param_value) except KeyError: continue # Make request op = get_op_handler(operation) result = op(client, **kwargs) # File download if stream_output: with open(stream_output, "wb") as file_handle: for data in result: file_handle.write(data) return # Apply results transform if specified elif transform_result: return transform_result(result) # Otherwise handle based on return type of results elif isinstance(result, Paged): return list(result) else: return result except BatchErrorException as ex: try: message = ex.error.message.value if ex.error.values: for detail in ex.error.values: message += "\n{}: {}".format(detail.key, detail.value) raise CLIError(message) except AttributeError: raise CLIError(ex) except (ValidationError, ClientRequestError) as ex: raise CLIError(ex) command_module_map[name] = module_name self.cmd = CliCommand( ' '.join(name.split()), _execute_command, table_transformer=table_transformer, arguments_loader=lambda: self._load_transformed_arguments( get_op_handler(operation)), description_loader=lambda: extract_full_summary_from_signature( get_op_handler(operation)) )
def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from azure.batch.models import BatchErrorException from azure.cli.core.util import CLIError from azure.cli.core._config import az_config from azure.cli.core.commands import _user_confirmed if self._cancel_operation(kwargs, az_config, _user_confirmed): raise CLIError('Operation cancelled.') try: client = factory(kwargs) self._build_options(kwargs) stream_output = kwargs.pop('destination', None) json_file = kwargs.pop('json_file', None) # Build the request parameters from command line arguments if json_file: self.parser.deserialize_json(client, kwargs, json_file) for arg, _ in self.parser: del kwargs[arg] else: for arg, details in self.parser: try: param_value = kwargs.pop(arg) if param_value is None: continue else: self._build_parameters(details['path'], kwargs, details['root'], param_value) except KeyError: continue # Make request op = get_op_handler(operation) if self.head_cmd: kwargs['raw'] = True result = op(client, **kwargs) # Head output if self.head_cmd: return transformers.transform_response_headers(result) # File download if stream_output: with open(stream_output, "wb") as file_handle: for data in result: file_handle.write(data) return # Apply results transform if specified elif transform_result: return transform_result(result) # Otherwise handle based on return type of results elif isinstance(result, Paged): return list(result) return result except BatchErrorException as ex: try: message = ex.error.message.value if ex.error.values: for detail in ex.error.values: message += "\n{}: {}".format( detail.key, detail.value) raise CLIError(message) except AttributeError: raise CLIError(ex) except (ValidationError, ClientRequestError) as ex: raise CLIError(ex)
def handler(args): # pylint: disable=too-many-branches,too-many-statements from msrestazure.azure_operation import AzureOperationPoller ordered_arguments = args.pop("ordered_arguments") if "ordered_arguments" in args else [] try: client = factory() if factory else None except TypeError: client = factory(None) if factory else None 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()} if child_collection_prop_name: parent = custom_function(instance, parent, **custom_func_args) else: instance = custom_function(instance, **custom_func_args) # apply generic updates after custom updates setterargs = set_arguments_loader() for k in args.copy().keys(): if ( k in get_arguments_loader() or k in setterargs or k in ("properties_to_add", "properties_to_remove", "properties_to_set") ): args.pop(k) for key, val in args.items(): ordered_arguments.append((key, val)) 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)) # Done... update the instance! getterargs[setter_arg_name] = parent if child_collection_prop_name else instance setter = get_op_handler(setter_op) no_wait = no_wait_param and setterargs.get(no_wait_param, None) if no_wait: getterargs[no_wait_param] = True opres = setter(client, **getterargs) if client else setter(**getterargs) if no_wait: 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) # apply results transform if specified if transform: return transform(result) return result