def FromData(cls, data): """Gets the arg definition from the spec data. Args: data: The spec data. Returns: Argument, the parsed argument. Raises: InvalidSchemaError: if the YAML command is malformed. """ if data.get('params'): return ArgumentGroup.FromData(data) api_field = data.get('api_field') arg_name = data.get('arg_name', api_field) if not arg_name: raise util.InvalidSchemaError( 'An argument must have at least one of [api_field, arg_name].') is_positional = data.get('is_positional') action = data.get('action', None) if action and action not in cls.STATIC_ACTIONS: action = util.Hook.FromPath(action) if not action: deprecation = data.get('deprecated') if deprecation: flag_name = arg_name if is_positional else '--' + arg_name action = actions.DeprecationAction(flag_name, **deprecation) if data.get('default') and data.get('fallback'): raise util.InvalidSchemaError( 'An argument may have at most one of [default, fallback].') try: help_text = data['help_text'] except KeyError: raise util.InvalidSchemaError('An argument must have help_text.') return cls( api_field, arg_name, help_text, metavar=data.get('metavar'), completer=util.Hook.FromData(data, 'completer'), is_positional=is_positional, type=util.Hook.FromData(data, 'type'), choices=data.get('choices'), default=data.get('default'), fallback=util.Hook.FromData(data, 'fallback'), processor=util.Hook.FromData(data, 'processor'), required=data.get('required', False), hidden=data.get('hidden', False), action=action, repeated=data.get('repeated'), )
def GenerateResourceSpec(self, resource_collection=None): """Creates a concept spec for the resource argument. Args: resource_collection: registry.APICollection, The collection that the resource arg must be for. This simply does some extra validation to ensure that resource arg is for the correct collection and api_version. If not specified, the resource arg will just be loaded based on the collection it specifies. Returns: concepts.ResourceSpec, The generated specification that can be added to a parser. """ if self.is_parent_resource and resource_collection: parent_collection, _, _ = resource_collection.full_name.rpartition( '.') resource_collection = registry.GetAPICollection( parent_collection, api_version=self._api_version) if resource_collection and not self.override_resource_collection: # Validate that the expected collection matches what was registered for # the resource argument specification. if resource_collection.full_name != self._full_collection_name: raise util.InvalidSchemaError( 'Collection names do not match for resource argument specification ' '[{}]. Expected [{}], found [{}]'.format( self.name, resource_collection.full_name, self._full_collection_name)) if (self._api_version and self._api_version != resource_collection.api_version): raise util.InvalidSchemaError( 'API versions do not match for resource argument specification ' '[{}]. Expected [{}], found [{}]'.format( self.name, resource_collection.api_version, self._api_version)) else: # No required collection, just load whatever the resource arg declared # for itself. resource_collection = registry.GetAPICollection( self._full_collection_name, api_version=self._api_version) attributes = concepts.ParseAttributesFromData( self._attribute_data, resource_collection.detailed_params) return concepts.ResourceSpec( resource_collection.full_name, resource_name=self.name, api_version=resource_collection.api_version, disable_auto_completers=self._disable_auto_completers, plural_name=self._plural_name, **{ attribute.parameter_name: attribute for attribute in attributes })
def FromData(cls, data): """Gets the arg definition from the spec data. Args: data: The spec data. Returns: Argument, the parsed argument. Raises: InvalidSchemaError: if the YAML command is malformed. """ group = data.get('group') if group: return ArgumentGroup.FromData(group) api_field = data.get('api_field') disable_unused_arg_check = data.get('disable_unused_arg_check') arg_name = data.get('arg_name', api_field) if not arg_name: raise util.InvalidSchemaError( 'An argument must have at least one of [api_field, arg_name].') is_positional = data.get('is_positional') flag_name = arg_name if is_positional else '--' + arg_name if data.get('default') and data.get('fallback'): raise util.InvalidSchemaError( 'An argument may have at most one of [default, fallback].') try: help_text = data['help_text'] except KeyError: raise util.InvalidSchemaError('An argument must have help_text.') choices = data.get('choices') return cls( api_field=api_field, arg_name=arg_name, help_text=help_text, metavar=data.get('metavar'), completer=util.Hook.FromData(data, 'completer'), is_positional=is_positional, type=util.ParseType(data.get('type')), choices=[util.Choice(d) for d in choices] if choices else None, default=data.get('default', arg_utils.UNSPECIFIED), fallback=util.Hook.FromData(data, 'fallback'), processor=util.Hook.FromData(data, 'processor'), required=data.get('required', False), hidden=data.get('hidden', False), action=util.ParseAction(data.get('action'), flag_name), repeated=data.get('repeated'), disable_unused_arg_check=disable_unused_arg_check, )
def __init__(self, name, data): self.hidden = data.get('hidden', False) self.release_tracks = [ base.ReleaseTrack.FromId(i) for i in data.get('release_tracks', []) ] self.command_type = CommandType.ForName(data.get('command_type', name)) self.help_text = data['help_text'] request_data = data.get('request') self.request = Request(self.command_type, request_data) self.response = Response(data.get('response', {})) async_data = data.get('async') iam_data = data.get('iam') update_data = data.get('update') import_data = data.get('import') if self.command_type == CommandType.WAIT and not async_data: raise util.InvalidSchemaError( 'Wait commands must include an async section.') self.async_ = Async(async_data) if async_data else None self.iam = IamData(iam_data) if iam_data else None self.arguments = Arguments(data['arguments']) self.input = Input(self.command_type, data.get('input', {})) self.output = Output(data.get('output', {})) self.update = UpdateData(update_data) if update_data else None self.import_ = ImportData(import_data, request_data, async_data) if import_data else None self.deprecated_data = data.get('deprecate')
def __init__(self, data, group_help, is_positional=True, removed_flags=None, is_parent_resource=False, disable_auto_completers=True, arg_name=None, command_level_fallthroughs=None, display_name_hook=None): self.name = data['name'] if arg_name is None else arg_name self.name_override = arg_name self.request_id_field = data.get('request_id_field') self.group_help = group_help self.is_positional = is_positional self.is_parent_resource = is_parent_resource self.removed_flags = removed_flags or [] self.command_level_fallthroughs = _GenerateFallthroughsMap( command_level_fallthroughs) self._full_collection_name = data['collection'] self._api_version = data.get('api_version') self._attribute_data = data['attributes'] self._disable_auto_completers = disable_auto_completers self._plural_name = data.get('plural_name') self.display_name_hook = (util.Hook.FromPath(display_name_hook) if display_name_hook else None) for removed in self.removed_flags: if removed not in self.attribute_names: raise util.InvalidSchemaError( 'Removed flag [{}] for resource arg [{}] references an attribute ' 'that does not exist. Valid attributes are [{}]'.format( removed, self.name, ', '.join(self.attribute_names)))
def __init__(self, data, group_help, is_positional=True, removed_flags=None, is_parent_resource=False): self.name = data['name'] self.request_id_field = data.get('request_id_field') self.group_help = group_help self.is_positional = is_positional self.is_parent_resource = is_parent_resource self.removed_flags = removed_flags or [] self._full_collection_name = data['collection'] self._api_version = data.get('api_version') self._attribute_data = data['attributes'] attribute_names = [a['attribute_name'] for a in self._attribute_data] for removed in self.removed_flags: if removed not in attribute_names: raise util.InvalidSchemaError( 'Removed flag [{}] for resource arg [{}] references an attribute ' 'that does not exist. Valid attributes are [{}]'.format( removed, self.name, ', '.join(attribute_names)))
def __init__(self, command_type, data): self.collection = data['collection'] self.disable_resource_check = data.get('disable_resource_check') self.display_resource_type = data.get('display_resource_type') self.api_version = data.get('api_version') self.use_google_auth = data.get('use_google_auth', False) self.method = data.get('method', command_type.default_method) if not self.method: raise util.InvalidSchemaError( 'request.method was not specified and there is no default for this ' 'command type.') self.resource_method_params = data.get('resource_method_params', {}) self.parse_resource_into_request = data.get( 'parse_resource_into_request', True) self.static_fields = data.get('static_fields', {}) self.modify_request_hooks = [ util.Hook.FromPath(p) for p in data.get('modify_request_hooks', []) ] self.create_request_hook = util.Hook.FromData(data, 'create_request_hook') self.modify_method_hook = util.Hook.FromData(data, 'modify_method_hook') self.issue_request_hook = util.Hook.FromData(data, 'issue_request_hook') self.use_relative_name = data.get('use_relative_name', True)
def GenerateResourceSpec(self, resource_collection=None): """Creates a concept spec for the resource argument. Args: resource_collection: registry.APICollection, The collection that the resource arg must be for. This simply does some extra validation to ensure that resource arg is for the correct collection and api_version. If not specified, the resource arg will just be loaded based on the collection it specifies. Returns: concepts.ResourceSpec, The generated specification that can be added to a parser. """ if resource_collection: # Validate that the expected collection matches what was registered for # the resource argument specification. if resource_collection.full_name != self._full_collection_name: raise util.InvalidSchemaError( 'Collection names do not match for resource argument specification ' '[{}]. Expected [{}], found [{}]'.format( self.name, resource_collection.full_name, self._full_collection_name)) if (self._api_version and self._api_version != resource_collection.api_version): raise util.InvalidSchemaError( 'API versions do not match for resource argument specification ' '[{}]. Expected [{}], found [{}]'.format( self.name, resource_collection.api_version, self._api_version)) else: # No required collection, just load whatever the resource arg declared # for itself. resource_collection = registry.GetAPICollection( self._full_collection_name, api_version=self._api_version) return self._GenerateResourceSpec(resource_collection.full_name, resource_collection.api_version, resource_collection.detailed_params)
def __init__(self, command_type, data): self.collection = data['collection'] self.api_version = data.get('api_version') self.method = data.get('method', command_type.default_method) if not self.method: raise util.InvalidSchemaError( 'request.method was not specified and there is no default for this ' 'command type.') self.resource_method_params = data.get('resource_method_params', {}) self.static_fields = data.get('static_fields', {}) self.modify_request_hooks = [ util.Hook.FromPath(p) for p in data.get('modify_request_hooks', [])] self.create_request_hook = util.Hook.FromData(data, 'create_request_hook') self.issue_request_hook = util.Hook.FromData(data, 'issue_request_hook')
def __init__(self, name, data): self.is_hidden = data.get('is_hidden', False) self.release_tracks = [ base.ReleaseTrack.FromId(i) for i in data.get('release_tracks', [])] self.command_type = CommandType.ForName(data.get('command_type', name)) self.help_text = data['help_text'] self.request = Request(self.command_type, data['request']) self.response = Response(data.get('response', {})) async_data = data.get('async') if self.command_type == CommandType.WAIT and not async_data: raise util.InvalidSchemaError( 'Wait commands must include an async section.') self.async = Async(async_data) if async_data else None self.arguments = Arguments(data['arguments']) self.input = Input(self.command_type, data.get('input', {})) self.output = Output(data.get('output', {}))
def __init__(self, data): self.collection = data['collection'] self.api_version = data.get('api_version') self.method = data.get('method', 'get') self.response_name_field = data.get('response_name_field', 'name') self.extract_resource_result = data.get('extract_resource_result', True) resource_get_method = data.get('resource_get_method') if not self.extract_resource_result and resource_get_method: raise util.InvalidSchemaError( 'async.resource_get_method was specified but extract_resource_result ' 'is False') self.resource_get_method = resource_get_method or 'get' self.operation_get_method_params = data.get( 'operation_get_method_params', {}) self.result_attribute = data.get('result_attribute') self.state = AsyncStateField(data.get('state', {})) self.error = AsyncErrorField(data.get('error', {}))
def GenerateResourceSpec(self, resource_collection=None): """Creates a concept spec for the resource argument. Args: resource_collection: registry.APICollection, The collection that the resource arg must be for. This simply does some extra validation to ensure that resource arg is for the correct collection and api_version. If not specified, the resource arg will just be loaded based on the collection it specifies. Returns: multitype.MultitypeResourceSpec, The generated specification that can be added to a parser. """ name = self.name resource_specs = [] collections = [] # Need to find a matching collection for validation, if the collection # is specified. for sub_resource in self._resources: sub_resource_arg = YAMLResourceArgument.FromSpecData(sub_resource) sub_resource_spec = sub_resource_arg.GenerateResourceSpec() resource_specs.append(sub_resource_spec) # pylint: disable=protected-access collections.append((sub_resource_arg._full_collection_name, sub_resource_arg._api_version)) # pylint: enable=protected-access if resource_collection: resource_collection_tuple = (resource_collection.full_name, resource_collection.api_version) if (resource_collection_tuple not in collections and (resource_collection_tuple[0], None) not in collections): raise util.InvalidSchemaError( 'Collection names do not match for resource argument specification ' '[{}]. Expected [{} version {}], and no contained resources ' 'matched. Given collections: [{}]'.format( self.name, resource_collection.full_name, resource_collection.api_version, ', '.join( sorted([ '{} {}'.format(coll, vers) for (coll, vers) in collections ])))) return multitype.MultitypeResourceSpec(name, *resource_specs)