def self_destruct_add_parameters(cli_ctx, commands_loader): from knack.arguments import CLICommandArgument command_table = cli_ctx.invocation.commands_loader.command_table if not command_table: return create_commands = [v for k, v in command_table.items() if "create" in k] if create_commands: command = create_commands[0] command.arguments["self_destruct"] = CLICommandArgument( "self_destruct", options_list=["--self-destruct"], arg_group="Self Destruct (noelbundick)", help= "How long to wait until deletion. You can specify durations like 1d, 6h, 2h30m, 30m, etc", ) command.arguments["self_destruct_sp"] = CLICommandArgument( "self_destruct_sp", options_list=["--self-destruct-sp"], action="store_true", arg_group="Self Destruct (noelbundick)", help="Use legacy behavior that uses a predefined Service Principal", )
def test_get_not_none_validator(self): from azure.cli.core.azclierror import InvalidArgumentValueError from knack.arguments import CLICommandArgument, CLIArgumentType container_name_type = CLIArgumentType( options_list=['--container-name', '-c'], help='The container name.') arg_type = CLIArgumentType(help='whatever arg') cmd = MockCmd(self.cli) cmd.arguments = { 'container_name': CLICommandArgument(dest='container_name', argtype=container_name_type), 'arg': CLICommandArgument(dest='arg', argtype=arg_type) } validate_container_name = get_not_none_validator('container_name') with self.assertRaisesRegexp( InvalidArgumentValueError, 'Argument --container-name/-c should be specified'): validate_container_name(cmd, Namespace(container_name='')) validate_arg = get_not_none_validator('arg') with self.assertRaisesRegexp(InvalidArgumentValueError, 'Argument --arg should be specified'): validate_arg(cmd, Namespace(arg=None)) validate_arg(cmd, Namespace(arg=0)) validate_arg(cmd, Namespace(arg=False))
def generic_update_arguments_loader(): arguments = get_arguments_loader(context, getter_op) arguments.update(set_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) # Add the generic update parameters 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)) group_name = 'Generic Update' arguments['properties_to_set'] = CLICommandArgument( 'properties_to_set', options_list=['--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) arguments['properties_to_add'] = CLICommandArgument( 'properties_to_add', options_list=['--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) arguments['properties_to_remove'] = CLICommandArgument( 'properties_to_remove', options_list=['--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) arguments['force_string'] = CLICommandArgument( 'force_string', action='store_true', arg_group=group_name, help= "When using 'set' or 'add', preserve string literals instead of attempting to convert to JSON." ) return [(k, v) for k, v in arguments.items()]
def arguments_loader(self): """ Callback function of CLICommand arguments_loader """ from azure.cli.core.commands.arm import set_usage, add_usage, remove_usage arguments = self.load_getter_op_arguments(self.getter_op_path) arguments.update(self.load_setter_op_arguments()) arguments.update(self.load_custom_function_op_arguments()) arguments.pop('instance', None) # inherited from custom_function(instance, ...) arguments.pop('parent', None) arguments.pop('expand', None) # possibly inherited from the getter arguments.pop(self.setter_arg_name, None) # Add the generic update parameters group_name = 'Generic Update' arguments['properties_to_set'] = CLICommandArgument( 'properties_to_set', options_list=['--set'], nargs='+', action=self.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) arguments['properties_to_add'] = CLICommandArgument( 'properties_to_add', options_list=['--add'], nargs='+', action=self.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) arguments['properties_to_remove'] = CLICommandArgument( 'properties_to_remove', options_list=['--remove'], nargs='+', action=self.OrderedArgsAction, default=[], help='Remove a property or an element from a list. Example: {}'. format(remove_usage), metavar='LIST INDEX', arg_group=group_name) arguments['force_string'] = CLICommandArgument( 'force_string', action='store_true', arg_group=group_name, help= "When using 'set' or 'add', preserve string literals instead of attempting to convert to JSON." ) return list(arguments.items())
def get_arguments_loader(context, getter_op, cmd_args=None, operation_group=None): getter_args = dict(extract_args_from_signature(context.get_op_handler(getter_op, operation_group=operation_group), excluded_params=EXCLUDED_PARAMS)) cmd_args = cmd_args or {} cmd_args.update(getter_args) cmd_args['cmd'] = CLICommandArgument('cmd', arg_type=ignore_type) return cmd_args
def test_override_argtype_with_argtype(self): existing_options_list = ('--default', '-d') arg = CLIArgumentType(options_list=existing_options_list, validator=None, completer='base', help='base', required=True) overriding_argtype = CLIArgumentType(options_list=('--overridden', ), validator='overridden', completer=None, overrides=arg, help='overridden', required=CLIArgumentType.REMOVE) self.assertEqual(overriding_argtype.settings['validator'], 'overridden') self.assertEqual(overriding_argtype.settings['completer'], None) self.assertEqual(overriding_argtype.settings['options_list'], ('--overridden', )) self.assertEqual(overriding_argtype.settings['help'], 'overridden') self.assertEqual(overriding_argtype.settings['required'], CLIArgumentType.REMOVE) cmd_arg = CLICommandArgument(dest='whatever', argtype=overriding_argtype, help=CLIArgumentType.REMOVE) self.assertFalse('required' in cmd_arg.options) self.assertFalse('help' in cmd_arg.options)
def compile_args(self): """Generator to convert pending arguments into CLICommandArgument objects. """ for name, details in self._arg_tree.items(): if self._is_bool(name): if self._request_param['name'].endswith('patch_parameter'): self._help( name, "Specify either 'true' or 'false' to update the property." ) else: details['options']['action'] = 'store_true' self._help(name, "True if flag present.") elif self._is_list(name): details['options']['nargs'] = '+' elif self._is_datetime(name): details['options']['type'] = validators.datetime_format self._help(name, "Expected format is an ISO-8601 timestamp.") elif self._is_duration(name): details['options']['type'] = validators.duration_format self._help(name, "Expected format is an ISO-8601 duration.") elif self._is_silent(name): import argparse details['options']['nargs'] = '?' details['options']['help'] = argparse.SUPPRESS details['options']['required'] = False details['options']['action'] = IgnoreAction yield (name, CLICommandArgument(dest=name, **details['options']))
def extra(self, dest, arg_type=None, **kwargs): merged_kwargs = self._flatten_kwargs(kwargs, arg_type) resource_type = merged_kwargs.get('resource_type', None) min_api = merged_kwargs.get('min_api', None) max_api = merged_kwargs.get('max_api', None) operation_group = merged_kwargs.get('operation_group', None) if self.command_loader.supported_api_version( resource_type=resource_type, min_api=min_api, max_api=max_api, operation_group=operation_group): # Restore when knack #132 is fixed # merged_kwargs.pop('dest', None) # super(AzArgumentContext, self).extra(dest, **merged_kwargs) from knack.arguments import CLICommandArgument self._check_stale() if not self._applicable(): return if self.command_scope in self.command_loader.command_group_table: raise ValueError( "command authoring error: extra argument '{}' cannot be registered to a group-level " "scope '{}'. It must be registered to a specific command.". format(dest, self.command_scope)) deprecate_action = self._handle_deprecations(dest, **merged_kwargs) if deprecate_action: merged_kwargs['action'] = deprecate_action merged_kwargs.pop('dest', None) self.command_loader.extra_argument_registry[ self.command_scope][dest] = CLICommandArgument( dest, **merged_kwargs)
def generic_wait_arguments_loader(): cmd_args = get_arguments_loader(context, getter_op, operation_group=kwargs.get('operation_group')) group_name = 'Wait Condition' cmd_args['timeout'] = CLICommandArgument( 'timeout', options_list=['--timeout'], default=3600, arg_group=group_name, type=int, help='maximum wait in seconds' ) cmd_args['interval'] = CLICommandArgument( 'interval', options_list=['--interval'], default=30, arg_group=group_name, type=int, help='polling interval in seconds' ) cmd_args['deleted'] = CLICommandArgument( 'deleted', options_list=['--deleted'], action='store_true', arg_group=group_name, help='wait until deleted' ) cmd_args['created'] = CLICommandArgument( 'created', options_list=['--created'], action='store_true', arg_group=group_name, help="wait until created with 'provisioningState' at 'Succeeded'" ) cmd_args['updated'] = CLICommandArgument( 'updated', options_list=['--updated'], action='store_true', arg_group=group_name, help="wait until updated with provisioningState at 'Succeeded'" ) cmd_args['exists'] = CLICommandArgument( 'exists', options_list=['--exists'], action='store_true', arg_group=group_name, help="wait until the resource exists" ) cmd_args['custom'] = CLICommandArgument( 'custom', options_list=['--custom'], arg_group=group_name, help="Wait until the condition satisfies a custom JMESPath query. E.g. " "provisioningState!='InProgress', " "instanceView.statuses[?code=='PowerState/running']" ) return [(k, v) for k, v in cmd_args.items()]
def generic_wait_arguments_loader(): getter_args = dict( extract_args_from_signature(context.get_op_handler(getter_op), excluded_params=EXCLUDED_PARAMS)) cmd_args = getter_args.copy() group_name = 'Wait Condition' cmd_args['timeout'] = CLICommandArgument( 'timeout', options_list=['--timeout'], default=3600, arg_group=group_name, type=int, help='maximum wait in seconds') cmd_args['interval'] = CLICommandArgument( 'interval', options_list=['--interval'], default=30, arg_group=group_name, type=int, help='polling interval in seconds') cmd_args['deleted'] = CLICommandArgument('deleted', options_list=['--deleted'], action='store_true', arg_group=group_name, help='wait until deleted') cmd_args['created'] = CLICommandArgument( 'created', options_list=['--created'], action='store_true', arg_group=group_name, help="wait until created with 'provisioningState' at 'Succeeded'") cmd_args['updated'] = CLICommandArgument( 'updated', options_list=['--updated'], action='store_true', arg_group=group_name, help="wait until updated with provisioningState at 'Succeeded'") cmd_args['exists'] = CLICommandArgument( 'exists', options_list=['--exists'], action='store_true', arg_group=group_name, help="wait until the resource exists") cmd_args['custom'] = CLICommandArgument( 'custom', options_list=['--custom'], arg_group=group_name, help= "Wait until the condition satisfies a custom JMESPath query. E.g. " "provisioningState!='InProgress', " "instanceView.statuses[?code=='PowerState/running']") cmd_args['cmd'] = CLICommandArgument('cmd', arg_type=ignore_type) return [(k, v) for k, v in cmd_args.items()]
def load_arguments(self): super(AzCliCommand, self).load_arguments() if self.arguments_loader: cmd_args = self.arguments_loader() if self.no_wait_param: cmd_args.append( (self.no_wait_param, CLICommandArgument(self.no_wait_param, options_list=['--no-wait'], action='store_true', help='Do not wait for the long-running operation to finish.'))) self.arguments.update(cmd_args)
def load_getter_op_arguments(self, getter_op_path, cmd_args=None): """ Load arguments from function signature of getter command op """ op = self.get_op_handler(getter_op_path) getter_args = dict( extract_args_from_signature(op, excluded_params=EXCLUDED_PARAMS)) cmd_args = cmd_args or {} cmd_args.update(getter_args) # The cmd argument is required when calling self.handler function. cmd_args['cmd'] = CLICommandArgument('cmd', arg_type=ignore_type) return cmd_args
def _process_options(self): """Process the request options parameter to expose as arguments.""" for param in [o for o in self._options_attrs if o not in pformat.IGNORE_OPTIONS]: options = {} options['required'] = False options['arg_group'] = 'Pre-condition and Query' if param in ['if_modified_since', 'if_unmodified_since']: options['type'] = validators.datetime_format if param in pformat.FLATTEN_OPTIONS: for f_param, f_docstring in pformat.FLATTEN_OPTIONS[param].items(): options['default'] = None options['help'] = f_docstring options['options_list'] = [arg_name(f_param)] options['validator'] = validators.validate_options yield (f_param, CLICommandArgument(f_param, **options)) else: options['default'] = getattr(self._options_model, param) options['help'] = find_param_help(self._options_model, param) options['options_list'] = [arg_name(param)] yield (param, CLICommandArgument(param, **options))
def to_cmd_arg(self, name): """ convert AAZArg to CLICommandArgument """ arg = CLICommandArgument( dest=name, options_list=[*self._options] if self._options else None, required=self._required, help=self._help.get('short-summary', None), default=self._default, ) if self._arg_group: arg.arg_group = self._arg_group if self._blank != AAZUndefined: arg.nargs = '?' action = self._build_cmd_action( ) # call sub class's implementation to build CLICommandArgument action if action: arg.action = action return arg
def add_parameters(cli_ctx, **kwargs): from knack.arguments import CLICommandArgument command_table = cli_ctx.invocation.commands_loader.command_table if not command_table: return if 'ad sp credential list' in command_table: command = command_table['ad sp credential list'] command.arguments['keyvault'] = CLICommandArgument('keyvault', options_list=['--keyvault'], arg_group='Key Vault (noelbundick)', help='The name of the Key Vault to get the secret value from.')
def arguments_loader(self): """ Callback function of CLICommand arguments_loader """ cmd_args = self.load_getter_op_arguments(self.op_path) group_name = 'Wait Condition' cmd_args['timeout'] = CLICommandArgument( 'timeout', options_list=['--timeout'], default=3600, arg_group=group_name, type=int, help='maximum wait in seconds') cmd_args['interval'] = CLICommandArgument( 'interval', options_list=['--interval'], default=30, arg_group=group_name, type=int, help='polling interval in seconds') cmd_args['deleted'] = CLICommandArgument('deleted', options_list=['--deleted'], action='store_true', arg_group=group_name, help='wait until deleted') cmd_args['created'] = CLICommandArgument( 'created', options_list=['--created'], action='store_true', arg_group=group_name, help="wait until created with 'provisioningState' at 'Succeeded'") cmd_args['updated'] = CLICommandArgument( 'updated', options_list=['--updated'], action='store_true', arg_group=group_name, help="wait until updated with provisioningState at 'Succeeded'") cmd_args['exists'] = CLICommandArgument( 'exists', options_list=['--exists'], action='store_true', arg_group=group_name, help="wait until the resource exists") cmd_args['custom'] = CLICommandArgument( 'custom', options_list=['--custom'], arg_group=group_name, help= "Wait until the condition satisfies a custom JMESPath query. E.g. " "provisioningState!='InProgress', " "instanceView.statuses[?code=='PowerState/running']") return list(cmd_args.items())
def add_parameters(cli_ctx, commands_loader): from knack.arguments import CLICommandArgument command_table = cli_ctx.invocation.commands_loader.command_table if not command_table: return if "ad sp credential list" in command_table: command = command_table["ad sp credential list"] command.arguments["keyvault"] = CLICommandArgument( "keyvault", options_list=["--keyvault"], arg_group="Key Vault (noelbundick)", help="The name of the Key Vault to get the secret value from.", )
def self_destruct_add_parameters(cli_ctx, **kwargs): from knack.arguments import CLICommandArgument command_table = cli_ctx.invocation.commands_loader.command_table if not command_table: return create_commands = [v for k, v in command_table.items() if 'create' in k] if create_commands: command = create_commands[0] command.arguments['self_destruct'] = CLICommandArgument( 'self_destruct', options_list=['--self-destruct'], arg_group='Self Destruct (noelbundick)', help= 'How long to wait until deletion. You can specify durations like 1d, 6h, 2h30m, 30m, etc' )
def add_subscription_parameter(_, **kwargs): from azure.cli.command_modules.profile._completers import get_subscription_id_list commands_loader = kwargs['commands_loader'] cmd_tbl = kwargs['cmd_tbl'] for command_name, cmd in cmd_tbl.items(): if 'subscription' not in cmd.arguments: commands_loader.extra_argument_registry[command_name][ '_subscription'] = CLICommandArgument( '_subscription', options_list=['--subscription'], help= 'Name or ID of subscription. You can configure the default subscription ' 'using `az account set -s NAME_OR_ID`"', completer=get_subscription_id_list, arg_group='Global', configured_default='subscription') commands_loader._update_command_definitions() # pylint: disable=protected-access
def _load_transformed_arguments(self, handler): """Load all the command line arguments from the request parameters. :param func handler: The operation function. """ from azure.cli.core.commands.parameters import file_type from argcomplete.completers import FilesCompleter, DirectoriesCompleter self.parser = BatchArgumentTree(self.validator) self._load_options_model(handler) args = [] for arg in extract_args_from_signature( handler, excluded_params=EXCLUDED_PARAMS): arg_type = find_param_type(handler, arg[0]) if arg[0] == self._options_param: for option_arg in self._process_options(): args.append(option_arg) elif arg_type.startswith("str or"): docstring = find_param_help(handler, arg[0]) choices = [] values_index = docstring.find(' Possible values include') if values_index >= 0: choices = docstring[values_index + 25:].split(', ') choices = [ enum_value(c) for c in choices if enum_value(c) != "'unmapped'" ] docstring = docstring[0:values_index] args.append( ((arg[0], CLICommandArgument(arg[0], options_list=[arg_name(arg[0])], required=False, default=None, choices=choices, help=docstring)))) elif arg_type.startswith( "~"): # TODO: could add handling for enums param_type = class_name(arg_type) self.parser.set_request_param(arg[0], param_type) param_model = _load_model(param_type) self._flatten_object(arg[0], param_model) for flattened_arg in self.parser.compile_args(): args.append(flattened_arg) param = 'json_file' docstring = "A file containing the {} specification in JSON " \ "(formatted to match the respective REST API body). " \ "If this parameter is specified, all '{} Arguments'" \ " are ignored.".format(arg[0].replace('_', ' '), group_title(arg[0])) args.append((param, CLICommandArgument(param, options_list=[arg_name(param)], required=False, default=None, type=file_type, completer=FilesCompleter(), help=docstring))) elif arg[0] not in pformat.IGNORE_PARAMETERS: args.append(arg) return_type = find_return_type(handler) if return_type and return_type.startswith('Generator'): param = 'destination' docstring = "The path to the destination file or directory." args.append((param, CLICommandArgument( param, options_list=[arg_name(param)], required=True, default=None, completer=DirectoriesCompleter(), type=file_type, validator=validators.validate_file_destination, help=docstring))) if return_type == 'None' and handler.__name__.startswith('get'): self._head_cmd = True if self.confirmation: param = CONFIRM_PARAM_NAME docstring = 'Do not prompt for confirmation.' args.append((param, CLICommandArgument(param, options_list=['--yes', '-y'], required=False, action='store_true', help=docstring))) auth_group_name = 'Batch Account' args.append(('cmd', CLICommandArgument('cmd', action=IgnoreAction))) args.append(( 'account_name', CLICommandArgument( 'account_name', options_list=['--account-name'], required=False, default=None, validator=validators.validate_client_parameters, arg_group=auth_group_name, help= 'Batch account name. Alternatively, set by environment variable: AZURE_BATCH_ACCOUNT' ))) args.append(( 'account_key', CLICommandArgument( 'account_key', options_list=['--account-key'], required=False, default=None, arg_group=auth_group_name, help= 'Batch account key. Alternatively, set by environment variable: AZURE_BATCH_ACCESS_KEY' ))) args.append(( 'account_endpoint', CLICommandArgument( 'account_endpoint', options_list=['--account-endpoint'], required=False, default=None, arg_group=auth_group_name, help= 'Batch service endpoint. Alternatively, set by environment variable: AZURE_BATCH_ENDPOINT' ))) return args