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)
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
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
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
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