def _RaiseWrongResourceCollectionException(self, got, path):
     expected_collections = [
         'compute.instances',
         'compute.globalOperations',
         'compute.regionOperations',
         'compute.zoneOperations',
     ]
     raise resources.WrongResourceCollectionException(
         expected=','.join(expected_collections), got=got, path=path)
Exemple #2
0
def _SetLogsBucket(build_config, arg_gcs_log_dir):
  """Set a Google Cloud Storage directory to hold build logs."""
  if arg_gcs_log_dir:
    # Parse the logs directory as a folder object.
    try:
      gcs_log_dir = resources.REGISTRY.Parse(
          arg_gcs_log_dir, collection='storage.objects')
      build_config.logsBucket = ('gs://' + gcs_log_dir.bucket + '/' +
                                 gcs_log_dir.object)
      return build_config
    except resources.WrongResourceCollectionException:
      pass

    # Parse the logs directory as a bucket.
    try:
      gcs_log_dir = resources.REGISTRY.Parse(
          arg_gcs_log_dir, collection='storage.buckets')
      build_config.logsBucket = ('gs://' + gcs_log_dir.bucket)
    except resources.WrongResourceCollectionException as e:
      raise resources.WrongResourceCollectionException(
          expected='storage.buckets,storage.objects', got=e.got, path=e.path)

  return build_config
Exemple #3
0
    def ResolveResources(self,
                         names,
                         resource_scope,
                         scope_value,
                         api_resource_registry,
                         default_scope=None,
                         scope_lister=None,
                         with_project=True):
        """Resolve this resource against the arguments.

    Args:
      names: list of str, list of resource names
      resource_scope: ScopeEnum, kind of scope of resources; if this is not None
                   scope_value should be name of scope of type specified by this
                   argument. If this is None scope_value should be None, in that
                   case if prompting is possible user will be prompted to
                   select scope (if prompting is forbidden it will raise an
                   exception).
      scope_value: ScopeEnum, scope of resources; if this is not None
                   resource_scope should be type of scope specified by this
                   argument. If this is None resource_scope should be None, in
                   that case if prompting is possible user will be prompted to
                   select scope (if prompting is forbidden it will raise an
                   exception).
      api_resource_registry: instance of core.resources.Registry.
      default_scope: ScopeEnum, ZONE, REGION, GLOBAL, or None when resolving
          name and scope was not specified use this as default. If there is
          exactly one possible scope it will be used, there is no need to
          specify default_scope.
      scope_lister: func(scope, underspecified_names), a callback which returns
        list of items (with 'name' attribute) for given scope.
      with_project: indicates whether or not project is associated. It should be
        False for flexible resource APIs.
    Returns:
      Resource reference or list of references if plural.
    Raises:
      BadArgumentException: when names is not a list or default_scope is not one
          of the configured scopes.
      UnderSpecifiedResourceError: if it was not possible to resolve given names
          as resources references.
    """
        self._ValidateNames(names)
        self._ValidateDefaultScope(default_scope)
        if resource_scope is not None:
            resource_scope = self.scopes[resource_scope]
        if default_scope is not None:
            default_scope = self.scopes[default_scope]
        project = properties.VALUES.core.project.GetOrFail
        if with_project:
            params = {
                'project': project,
            }
        else:
            params = {}

        if scope_value is None:
            resource_scope = self.scopes.GetImplicitScope(default_scope)

        resource_scope_param = self._GetResourceScopeParam(
            resource_scope,
            scope_value,
            project,
            api_resource_registry,
            with_project=with_project)
        if resource_scope_param is not None:
            params[resource_scope.scope_enum.param_name] = resource_scope_param

        collection = resource_scope and resource_scope.collection

        # See if we can resolve names with so far deduced scope and its value.
        refs, underspecified_names = self._GetRefsAndUnderspecifiedNames(
            names, params, collection, scope_value is not None,
            api_resource_registry)

        # If we still have some resources which need to be resolve see if we can
        # prompt the user and try to resolve these again.
        self._ResolveUnderspecifiedNames(underspecified_names,
                                         default_scope,
                                         scope_lister,
                                         project,
                                         api_resource_registry,
                                         with_project=with_project)

        # Now unpack each element.
        refs = [ref[0] for ref in refs]

        # Make sure correct collection was given for each resource, for example
        # URLs have implicit collections.
        expected_collections = [scope.collection for scope in self.scopes]
        for ref in refs:
            if ref.Collection() not in expected_collections:
                raise resources.WrongResourceCollectionException(
                    expected=','.join(expected_collections),
                    got=ref.Collection(),
                    path=ref.SelfLink())
        return refs
Exemple #4
0
    def ResolveResources(self,
                         names,
                         resource_scope,
                         scope_value,
                         api_resource_registry,
                         default_scope=None,
                         scope_lister=None):
        """Resolve this resource against the arguments.

    Args:
      names: list of str, list of resource names
      resource_scope: ScopeEnum, kind of scope of resources; if this is not None
                   scope_value should be name of scope of type specified by this
                   argument. If this is None scope_value should be None, in that
                   case if prompting is possible user will be prompted to
                   select scope (if prompting is forbidden it will raise an
                   exception).
      scope_value: ScopeEnum, scope of resources; if this is not None
                   resource_scope should be type of scope specified by this
                   argument. If this is None resource_scope should be None, in
                   that case if prompting is possible user will be prompted to
                   select scope (if prompting is forbidden it will raise an
                   exception).
      api_resource_registry: instance of core.resources.Registry.
      default_scope: ScopeEnum, ZONE, REGION, GLOBAL, or None when resolving
          name and scope was not specified use this as default. If there is
          exactly one possible scope it will be used, there is no need to
          specify default_scope.
      scope_lister: func(scope, underspecified_names), a callback which returns
        list of items (with 'name' attribute) for given scope.
    Returns:
      Resource reference or list of references if plural.
    Raises:
      BadArgumentException: when names is not a list or default_scope is not one
          of the configured scopes.
      UnderSpecifiedResourceError: if it was not possible to resolve given names
          as resources references.
    """
        if not isinstance(names, list):
            raise BadArgumentException(
                'Expected names to be a list but it is {0!r}'.format(names))
        if resource_scope is not None:
            resource_scope = self.scopes[resource_scope]
        if default_scope is not None:
            if default_scope not in self.scopes:
                raise BadArgumentException(
                    'Unexpected value for default_scope {0}, expected None or {1}'
                    .format(
                        default_scope,
                        ' or '.join([s.scope_enum.name for s in self.scopes])))
            default_scope = self.scopes[default_scope]
        params = {}
        if scope_value is not None:
            if resource_scope.scope_enum == compute_scope.ScopeEnum.GLOBAL:
                stored_value = scope_value
            else:
                collection = compute_scope.ScopeEnum.CollectionForScope(
                    resource_scope.scope_enum)
                stored_value = api_resource_registry.Parse(
                    scope_value, collection=collection).Name()
            params[resource_scope.scope_enum.param_name] = stored_value
        else:
            resource_scope = self.scopes.GetImplicitScope(default_scope)

        collection = resource_scope and resource_scope.collection

        # See if we can resolve names with so far deduced scope and its value.
        refs = []
        underspecified_names = []
        for name in names:
            try:
                # Make each element an array so that we can do in place updates.
                ref = [
                    api_resource_registry.Parse(name,
                                                params=params,
                                                collection=collection,
                                                enforce_collection=False)
                ]
            except (resources.UnknownCollectionException,
                    resources.UnknownFieldException,
                    properties.RequiredPropertyError):
                if scope_value:
                    raise
                ref = [name]
                underspecified_names.append(ref)
            refs.append(ref)

        # If we still have some resources which need to be resolve see if we can
        # prompt the user and try to resolve these again.
        if underspecified_names:
            names = [n[0] for n in underspecified_names]
            if not console_io.CanPrompt():
                raise UnderSpecifiedResourceError(
                    names, [s.flag for s in self.scopes])
            resource_scope_enum, scope_value = scope_prompter.PromptForScope(
                self.resource_name, names, [s.scope_enum for s in self.scopes],
                default_scope.scope_enum
                if default_scope is not None else None, scope_lister)
            if resource_scope_enum is None:
                raise UnderSpecifiedResourceError(
                    names, [s.flag for s in self.scopes])
            resource_scope = self.scopes[resource_scope_enum]
            for name in underspecified_names:
                name[0] = api_resource_registry.Parse(
                    name[0],
                    params={resource_scope.scope_enum.param_name: scope_value},
                    collection=resource_scope.collection,
                    enforce_collection=True)
        # Now unpack each element.
        refs = [ref[0] for ref in refs]

        # Make sure correct collection was given for each resource, for example
        # URLs have implicit collections.
        expected_collections = [scope.collection for scope in self.scopes]
        for ref in refs:
            if ref.Collection() not in expected_collections:
                raise resources.WrongResourceCollectionException(
                    expected=','.join(expected_collections),
                    got=ref.Collection(),
                    path=ref.SelfLink())
        return refs
Exemple #5
0
  def ResolveAsResource(self, args,
                        api_resource_registry,
                        default_scope=None,
                        scope_lister=None):
    """Resolve this resource against the arguments.

    Args:
      args: Namespace, argparse.Namespace.
      api_resource_registry: instance of core.resources.Registry.
      default_scope: ScopeEnum, ZONE, REGION, GLOBAL, or None when resolving
          name and scope was not specified use this as default. If there is
          exactly one possible scope it will be used, there is no need to
          specify default_scope.
      scope_lister: func(scope, underspecified_names), a callback which returns
        list of items (with 'name' attribute) for given scope.
    Returns:
      Resource reference or list of references if plural.
    """
    if default_scope is not None:
      if default_scope not in self.scopes:
        raise exceptions.Error(
            'Unexpected value for default_scope {0}, expected None or {1}'
            .format(default_scope,
                    ' or '.join([s.scope_enum.name for s in self.scopes])))
      default_scope = self.scopes[default_scope]
    names = self._GetResourceNames(args)
    resource_scope, scope_value = self.scopes.SpecifiedByArgs(args)
    params = {}
    if scope_value is not None:
      # Complain if scope was specified without actual resource(s).
      if not self.required and not names:
        raise exceptions.Error('Can\'t specify --zone, --region or --global'
                               ' without specifying resource via {0}'
                               .format(self.name))
      if resource_scope.scope_enum == ScopeEnum.GLOBAL:
        stored_value = scope_value
      else:
        collection = ScopeEnum.CollectionForScope(resource_scope.scope_enum)
        stored_value = api_resource_registry.Parse(
            scope_value, collection=collection).Name()
      params[resource_scope.scope_enum.param_name] = stored_value
    else:
      resource_scope = self.scopes.GetImplicitScope(default_scope)

    collection = resource_scope and resource_scope.collection

    # See if we can resolve names with so far deduced scope and its value.
    refs = []
    underspecified_names = []
    for name in names:
      try:
        # Make each element an array so that we can do in place updates.
        ref = [api_resource_registry.Parse(name, params=params,
                                           collection=collection,
                                           enforce_collection=False)]
      except (resources.UnknownCollectionException,
              resources.UnknownFieldException):
        if scope_value:
          raise
        ref = [name]
        underspecified_names.append(ref)
      refs.append(ref)

    # If we still have some resources which need to be resolve see if we can
    # prompt the user and try to resolve these again.
    if underspecified_names:
      resource_scope, scope_value = self._PromptForScope(
          [n[0] for n in underspecified_names], default_scope, scope_lister)
      for name in underspecified_names:
        name[0] = api_resource_registry.Parse(
            name[0],
            params={resource_scope.scope_enum.param_name: scope_value},
            collection=resource_scope.collection,
            enforce_collection=True)
    # Now unpack each element.
    refs = [ref[0] for ref in refs]

    # Make sure correct collection was given for each resource, for example
    # URLs have implicit collections.
    expected_collections = [scope.collection for scope in self.scopes]
    for ref in refs:
      if ref.Collection() not in expected_collections:
        raise resources.WrongResourceCollectionException(
            expected=','.join(expected_collections),
            got=ref.Collection(),
            path=ref.SelfLink())

    if self.plural:
      return refs
    if refs:
      return refs[0]
    return None