placement/placement/exception.py

212 lines
6.6 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Exceptions for use in the Placement API."""
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
class _BaseException(Exception):
"""Base Exception
To correctly use this class, inherit from it and define
a 'msg_fmt' property. That msg_fmt will get printf'd
with the keyword arguments provided to the constructor.
"""
msg_fmt = "An unknown exception occurred."
def __init__(self, message=None, **kwargs):
self.kwargs = kwargs
if not message:
try:
message = self.msg_fmt % kwargs
except Exception:
# NOTE(melwitt): This is done in a separate method so it can be
# monkey-patched during testing to make it a hard failure.
self._log_exception()
message = self.msg_fmt
self.message = message
super(_BaseException, self).__init__(message)
def _log_exception(self):
# kwargs doesn't match a variable in the message
# log the issue and the kwargs
LOG.exception('Exception in string format operation')
for name, value in self.kwargs.items():
LOG.error("%s: %s" % (name, value)) # noqa
def format_message(self):
# Use the first argument to the python Exception object which
# should be our full exception message, (see __init__).
return self.args[0]
class NotFound(_BaseException):
msg_fmt = "Resource could not be found."
class Exists(_BaseException):
msg_fmt = "Resource already exists."
class InvalidInventory(_BaseException):
msg_fmt = ("Inventory for '%(resource_class)s' on "
"resource provider '%(resource_provider)s' invalid.")
class CannotDeleteParentResourceProvider(_BaseException):
msg_fmt = ("Cannot delete resource provider that is a parent of "
"another. Delete child providers first.")
class ConcurrentUpdateDetected(_BaseException):
msg_fmt = ("Another thread concurrently updated the data. "
"Please retry your update")
class ResourceProviderConcurrentUpdateDetected(ConcurrentUpdateDetected):
msg_fmt = ("Another thread concurrently updated the resource provider "
"data. Please retry your update")
class ResourceProviderNotFound(NotFound):
# Marker exception indicating that we've filtered down to zero possible
# allocation candidates. Does not represent an API error; should only be
# used internally: no results is a 200 with empty allocation_requests.
msg_fmt = "No results are possible."
class InvalidAllocationCapacityExceeded(InvalidInventory):
msg_fmt = ("Unable to create allocation for '%(resource_class)s' on "
"resource provider '%(resource_provider)s'. The requested "
"amount would exceed the capacity.")
class InvalidAllocationConstraintsViolated(InvalidInventory):
msg_fmt = ("Unable to create allocation for '%(resource_class)s' on "
"resource provider '%(resource_provider)s'. The requested "
"amount would violate inventory constraints.")
class InvalidInventoryCapacity(InvalidInventory):
msg_fmt = ("Invalid inventory for '%(resource_class)s' on "
"resource provider '%(resource_provider)s'. "
"The reserved value is greater than or equal to total.")
class InvalidInventoryCapacityReservedCanBeTotal(InvalidInventoryCapacity):
msg_fmt = ("Invalid inventory for '%(resource_class)s' on "
"resource provider '%(resource_provider)s'. "
"The reserved value is greater than total.")
# An exception with this name is used on both sides of the placement/
# nova interaction.
class InventoryInUse(InvalidInventory):
msg_fmt = ("Inventory for '%(resource_classes)s' on "
"resource provider '%(resource_provider)s' in use.")
class InventoryWithResourceClassNotFound(NotFound):
msg_fmt = "No inventory of class %(resource_class)s found."
class MaxDBRetriesExceeded(_BaseException):
msg_fmt = ("Max retries of DB transaction exceeded attempting to "
"perform %(action)s.")
class ObjectActionError(_BaseException):
msg_fmt = 'Object action %(action)s failed because: %(reason)s'
class PolicyNotAuthorized(_BaseException):
msg_fmt = "Policy does not allow %(action)s to be performed."
class ResourceClassCannotDeleteStandard(_BaseException):
msg_fmt = "Cannot delete standard resource class %(resource_class)s."
class ResourceClassCannotUpdateStandard(_BaseException):
msg_fmt = "Cannot update standard resource class %(resource_class)s."
class ResourceClassExists(_BaseException):
msg_fmt = "Resource class %(resource_class)s already exists."
class ResourceClassInUse(_BaseException):
msg_fmt = ("Cannot delete resource class %(resource_class)s. "
"Class is in use in inventory.")
class ResourceClassNotFound(NotFound):
msg_fmt = "No such resource class %(name)s."
class ResourceProviderInUse(_BaseException):
msg_fmt = "Resource provider has allocations."
class TraitCannotDeleteStandard(_BaseException):
msg_fmt = "Cannot delete standard trait %(name)s."
class TraitExists(_BaseException):
msg_fmt = "The Trait %(name)s already exists"
class TraitInUse(_BaseException):
msg_fmt = "The trait %(name)s is in use by a resource provider."
class TraitNotFound(NotFound):
msg_fmt = "No such trait(s): %(name)s."
class ProjectNotFound(NotFound):
msg_fmt = "No such project(s): %(external_id)s."
class ProjectExists(Exists):
msg_fmt = "The project %(external_id)s already exists."
class UserNotFound(NotFound):
msg_fmt = "No such user(s): %(external_id)s."
class UserExists(Exists):
msg_fmt = "The user %(external_id)s already exists."
class ConsumerNotFound(NotFound):
msg_fmt = "No such consumer(s): %(uuid)s."
class ConsumerExists(Exists):
msg_fmt = "The consumer %(uuid)s already exists."
class ConsumerTypeNotFound(NotFound):
msg_fmt = "No such consumer type: %(name)s."
class ConsumerTypeExists(Exists):
msg_fmt = "The consumer type %(name)s already exists."