You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
8.8 KiB

# Copyright 2015 Huawei Technologies Co., Ltd.
# All Rights Reserved.
# 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
# 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.
Tricircle base exception handling.
import six
from oslo_log import log as logging
from tricircle.common.i18n import _
from tricircle.common.i18n import _LE
LOG = logging.getLogger(__name__)
class TricircleException(Exception):
"""Base Tricircle Exception.
To correctly use this class, inherit from it and define
a 'message' property. That message will get printf'd
with the keyword arguments provided to the constructor.
message = _("An unknown exception occurred.")
code = 500
headers = {}
safe = False
def __init__(self, message=None, **kwargs):
self.kwargs = kwargs
self.kwargs['message'] = message
if 'code' not in self.kwargs:
self.kwargs['code'] = self.code
for k, v in self.kwargs.items():
if isinstance(v, Exception):
self.kwargs[k] = six.text_type(v)
if self._should_format():
message = self.message % kwargs
except Exception:
# kwargs doesn't match a variable in the message
# log the issue and the kwargs
exc_info = _('Exception class %s in string '
'format operation') % type(self).__name__
format_str = _('%(exception_info)s ; %(format_key)s : '
for name, value in kwargs.items():
exc_info = format_str % {
'exception_info': exc_info,
'format_key': name,
'format_value': six.text_type(value)}
exc_info = _('%(message)s ; %(exception_info)s') % {
'message': self.message, 'exception_info': exc_info}
# no rerasie
# exc_info = sys.exc_info()
# if CONF.fatal_exception_format_errors:
# six.reraise(*exc_info)
# at least get the core message out if something happened
message = self.message
elif isinstance(message, Exception):
message = six.text_type(message)
self.msg = message
super(TricircleException, self).__init__(message)
def _should_format(self):
if self.kwargs['message'] is None and '%(message)' in self.message:
LOG.error(_LE('\%(message)s in message '
'but init parameter is None'))
return self.kwargs['message'] is None or '%(message)' in self.message
def __unicode__(self):
return six.text_type(self.msg)
class BadRequest(TricircleException):
message = _('Bad %(resource)s request: %(msg)s')
class NotFound(TricircleException):
message = _("Resource could not be found.")
code = 404
safe = True
class Conflict(TricircleException):
class NotAuthorized(TricircleException):
message = _("Not authorized.")
class ServiceUnavailable(TricircleException):
message = _("The service is unavailable")
class AdminRequired(NotAuthorized):
message = _("User does not have admin privileges")
class PolicyNotAuthorized(NotAuthorized):
message = _("Policy doesn't allow this operation to be performed.")
class InUse(TricircleException):
message = _("The resource is inuse")
class InvalidConfigurationOption(TricircleException):
message = _("An invalid value was provided for %(opt_name)s: "
class EndpointNotAvailable(TricircleException):
message = "Endpoint %(url)s for %(service)s is not available"
def __init__(self, service, url):
super(EndpointNotAvailable, self).__init__(service=service, url=url)
class EndpointNotUnique(TricircleException):
message = "Endpoint for %(service)s in %(pod)s not unique"
def __init__(self, pod, service):
super(EndpointNotUnique, self).__init__(pod=pod, service=service)
class EndpointNotFound(TricircleException):
message = "Endpoint for %(service)s in %(pod)s not found"
def __init__(self, pod, service):
super(EndpointNotFound, self).__init__(pod=pod, service=service)
class ResourceNotFound(TricircleException):
message = "Could not find %(resource_type)s: %(unique_key)s"
def __init__(self, model, unique_key):
resource_type = model.__name__.lower()
super(ResourceNotFound, self).__init__(resource_type=resource_type,
class ResourceNotSupported(TricircleException):
message = "%(method)s method not supported for %(resource)s"
def __init__(self, resource, method):
super(ResourceNotSupported, self).__init__(resource=resource,
class Invalid(TricircleException):
message = _("Unacceptable parameters.")
code = 400
class InvalidInput(Invalid):
message = _("Invalid input received: %(reason)s")
class InvalidMetadata(Invalid):
message = _("Invalid metadata: %(reason)s")
class InvalidMetadataSize(Invalid):
message = _("Invalid metadata size: %(reason)s")
class MetadataLimitExceeded(TricircleException):
message = _("Maximum number of metadata items exceeds %(allowed)d")
class InvalidReservationExpiration(Invalid):
message = _("Invalid reservation expiration %(expire)s.")
class InvalidQuotaValue(Invalid):
message = _("Change would make usage less than 0 for the following "
"resources: %(unders)s")
class QuotaNotFound(NotFound):
message = _("Quota could not be found")
class QuotaResourceUnknown(QuotaNotFound):
message = _("Unknown quota resources %(unknown)s.")
class ProjectQuotaNotFound(QuotaNotFound):
message = _("Quota for project %(project_id)s could not be found.")
class QuotaClassNotFound(QuotaNotFound):
message = _("Quota class %(class_name)s could not be found.")
class QuotaUsageNotFound(QuotaNotFound):
message = _("Quota usage for project %(project_id)s could not be found.")
class ReservationNotFound(QuotaNotFound):
message = _("Quota reservation %(uuid)s could not be found.")
class OverQuota(TricircleException):
message = _("Quota exceeded for resources: %(overs)s")
class TooManyInstances(TricircleException):
message = _("Quota exceeded for %(overs)s: Requested %(req)s,"
" but already used %(used)s of %(allowed)s %(overs)s")
class OnsetFileLimitExceeded(TricircleException):
message = _("Personality file limit exceeded")
class OnsetFilePathLimitExceeded(OnsetFileLimitExceeded):
message = _("Personality file path too long")
class OnsetFileContentLimitExceeded(OnsetFileLimitExceeded):
message = _("Personality file content too long")
class ExternalNetPodNotSpecify(TricircleException):
message = "Pod for external network not specified"
def __init__(self):
super(ExternalNetPodNotSpecify, self).__init__()
class PodNotFound(NotFound):
message = "Pod %(pod_name)s could not be found."
def __init__(self, pod_name):
super(PodNotFound, self).__init__(pod_name=pod_name)
class ChildQuotaNotZero(TricircleException):
message = _("Child projects having non-zero quota")
# parameter validation error
class ValidationError(TricircleException):
message = _("%(msg)s")
code = 400
# parameter validation error
class HTTPForbiddenError(TricircleException):
message = _("%(msg)s")
code = 403
class VolumeTypeNotFound(NotFound):
message = _("Volume type %(volume_type_id)s could not be found.")
class VolumeTypeNotFoundByName(VolumeTypeNotFound):
message = _("Volume type with name %(volume_type_name)s "
"could not be found.")
class VolumeTypeExtraSpecsNotFound(NotFound):
message = _("Volume Type %(volume_type_id)s has no extra specs with "
"key %(extra_specs_key)s.")
class Duplicate(TricircleException):
class VolumeTypeExists(Duplicate):
message = _("Volume Type %(id)s already exists.")
class VolumeTypeUpdateFailed(TricircleException):
message = _("Cannot update volume_type %(id)s")
class ServerMappingsNotFound(NotFound):
message = _('Instance %(server_id)s could not be found.')
class VolumeMappingsNotFound(NotFound):
message = _('Volume %(volume_id)s could not be found')