Example #1
0
    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'),
        )
Example #2
0
    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,
        )
Example #4
0
 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')
Example #5
0
    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)))
Example #6
0
    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)))
Example #7
0
 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)
Example #8
0
    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)
Example #9
0
 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')
Example #10
0
 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', {}))
Example #11
0
 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', {}))
Example #12
0
    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)