summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/conf.py2
-rw-r--r--keystoneclient/exceptions.py571
2 files changed, 225 insertions, 348 deletions
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 593d7e2..9f05b9d 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -224,7 +224,9 @@ latex_documents = [
# If false, no module index is generated.
#latex_use_modindex = True
+keystoneauth_url = 'http://docs.openstack.org/developer/keystoneauth/'
intersphinx_mapping = {
'python': ('http://docs.python.org/', None),
'osloconfig': ('http://docs.openstack.org/developer/oslo.config/', None),
+ 'keystoneauth1': (keystoneauth_url, None),
}
diff --git a/keystoneclient/exceptions.py b/keystoneclient/exceptions.py
index 8756929..0bbd35a 100644
--- a/keystoneclient/exceptions.py
+++ b/keystoneclient/exceptions.py
@@ -14,47 +14,54 @@
# under the License.
"""Exception definitions."""
-import inspect
-import sys
-
-import six
+from keystoneauth1 import exceptions as _exc
from keystoneclient.i18n import _
-class ClientException(Exception):
- """The base exception class for all exceptions this library raises.
- """
- pass
+ClientException = _exc.ClientException
+"""The base exception class for all exceptions this library raises.
+An alias of :py:exc:`keystoneauth1.exceptions.base.ClientException`
+"""
-class ValidationError(ClientException):
- """Error in validation on API client side."""
- pass
+ConnectionError = _exc.ConnectionError
+"""Cannot connect to API service.
+An alias of :py:exc:`keystoneauth1.exceptions.connection.ConnectionError`
+"""
-class UnsupportedVersion(ClientException):
- """User is trying to use an unsupported version of the API."""
- pass
+ConnectionRefused = _exc.ConnectFailure
+"""Connection refused while trying to connect to API service.
+An alias of :py:exc:`keystoneauth1.exceptions.connection.ConnectFailure`
+"""
-class CommandError(ClientException):
- """Error in CLI tool."""
- pass
+SSLError = _exc.SSLError
+"""An SSL error occurred.
+
+An alias of :py:exc:`keystoneauth1.exceptions.connection.SSLError`
+"""
+AuthorizationFailure = _exc.AuthorizationFailure
+"""Cannot authorize API client.
-class AuthorizationFailure(ClientException):
- """Cannot authorize API client."""
+An alias of :py:exc:`keystoneauth1.exceptions.auth.AuthorizationFailure`
+"""
+
+
+class ValidationError(ClientException):
+ """Error in validation on API client side."""
pass
-class ConnectionError(ClientException):
- """Cannot connect to API service."""
+class UnsupportedVersion(ClientException):
+ """User is trying to use an unsupported version of the API."""
pass
-class ConnectionRefused(ConnectionError):
- """Connection refused while trying to connect to API service."""
+class CommandError(ClientException):
+ """Error in CLI tool."""
pass
@@ -80,14 +87,17 @@ class NoUniqueMatch(ClientException):
pass
-class EndpointException(ClientException):
- """Something is rotten in Service Catalog."""
- pass
+EndpointException = _exc.CatalogException
+"""Something is rotten in Service Catalog.
+An alias of :py:exc:`keystoneauth1.exceptions.catalog.CatalogException`
+"""
-class EndpointNotFound(EndpointException):
- """Could not find requested endpoint in Service Catalog."""
- pass
+EndpointNotFound = _exc.EndpointNotFound
+"""Could not find requested endpoint in Service Catalog.
+
+An alias of :py:exc:`keystoneauth1.exceptions.catalog.EndpointNotFound`
+"""
class AmbiguousEndpoints(EndpointException):
@@ -98,48 +108,31 @@ class AmbiguousEndpoints(EndpointException):
self.endpoints = endpoints
-class HttpError(ClientException):
- """The base exception class for all HTTP exceptions.
- """
- http_status = 0
- message = _("HTTP Error")
-
- def __init__(self, message=None, details=None,
- response=None, request_id=None,
- url=None, method=None, http_status=None):
- self.http_status = http_status or self.http_status
- self.message = message or self.message
- self.details = details
- self.request_id = request_id
- self.response = response
- self.url = url
- self.method = method
- formatted_string = "%s (HTTP %s)" % (self.message, self.http_status)
- if request_id:
- formatted_string += " (Request-ID: %s)" % request_id
- super(HttpError, self).__init__(formatted_string)
-
+HttpError = _exc.HttpError
+"""The base exception class for all HTTP exceptions.
-class HTTPRedirection(HttpError):
- """HTTP Redirection."""
- message = _("HTTP Redirection")
+An alias of :py:exc:`keystoneauth1.exceptions.http.HttpError`
+"""
+HTTPClientError = _exc.HTTPClientError
+"""Client-side HTTP error.
-class HTTPClientError(HttpError):
- """Client-side HTTP error.
+Exception for cases in which the client seems to have erred.
+An alias of :py:exc:`keystoneauth1.exceptions.http.HTTPClientError`
+"""
- Exception for cases in which the client seems to have erred.
- """
- message = _("HTTP Client Error")
+HttpServerError = _exc.HttpServerError
+"""Server-side HTTP error.
+Exception for cases in which the server is aware that it has
+erred or is incapable of performing the request.
+An alias of :py:exc:`keystoneauth1.exceptions.http.HttpServerError`
+"""
-class HttpServerError(HttpError):
- """Server-side HTTP error.
- Exception for cases in which the server is aware that it has
- erred or is incapable of performing the request.
- """
- message = _("HTTP Server Error")
+class HTTPRedirection(HttpError):
+ """HTTP Redirection."""
+ message = _("HTTP Redirection")
class MultipleChoices(HTTPRedirection):
@@ -152,318 +145,207 @@ class MultipleChoices(HTTPRedirection):
message = _("Multiple Choices")
-class BadRequest(HTTPClientError):
- """HTTP 400 - Bad Request.
+BadRequest = _exc.BadRequest
+"""HTTP 400 - Bad Request.
- The request cannot be fulfilled due to bad syntax.
- """
- http_status = 400
- message = _("Bad Request")
+The request cannot be fulfilled due to bad syntax.
+An alias of :py:exc:`keystoneauth1.exceptions.http.BadRequest`
+"""
+Unauthorized = _exc.Unauthorized
+"""HTTP 401 - Unauthorized.
-class Unauthorized(HTTPClientError):
- """HTTP 401 - Unauthorized.
+Similar to 403 Forbidden, but specifically for use when authentication
+is required and has failed or has not yet been provided.
+An alias of :py:exc:`keystoneauth1.exceptions.http.Unauthorized`
+"""
- Similar to 403 Forbidden, but specifically for use when authentication
- is required and has failed or has not yet been provided.
- """
- http_status = 401
- message = _("Unauthorized")
+PaymentRequired = _exc.PaymentRequired
+"""HTTP 402 - Payment Required.
+Reserved for future use.
+An alias of :py:exc:`keystoneauth1.exceptions.http.PaymentRequired`
+"""
-class PaymentRequired(HTTPClientError):
- """HTTP 402 - Payment Required.
+Forbidden = _exc.Forbidden
+"""HTTP 403 - Forbidden.
- Reserved for future use.
- """
- http_status = 402
- message = _("Payment Required")
+The request was a valid request, but the server is refusing to respond
+to it.
+An alias of :py:exc:`keystoneauth1.exceptions.http.Forbidden`
+"""
+NotFound = _exc.NotFound
+"""HTTP 404 - Not Found.
-class Forbidden(HTTPClientError):
- """HTTP 403 - Forbidden.
+The requested resource could not be found but may be available again
+in the future.
+An alias of :py:exc:`keystoneauth1.exceptions.http.NotFound`
+"""
- The request was a valid request, but the server is refusing to respond
- to it.
- """
- http_status = 403
- message = _("Forbidden")
+MethodNotAllowed = _exc.MethodNotAllowed
+"""HTTP 405 - Method Not Allowed.
+A request was made of a resource using a request method not supported
+by that resource.
+An alias of :py:exc:`keystoneauth1.exceptions.http.MethodNotAllowed`
+"""
-class NotFound(HTTPClientError):
- """HTTP 404 - Not Found.
+NotAcceptable = _exc.NotAcceptable
+"""HTTP 406 - Not Acceptable.
- The requested resource could not be found but may be available again
- in the future.
- """
- http_status = 404
- message = _("Not Found")
+The requested resource is only capable of generating content not
+acceptable according to the Accept headers sent in the request.
+An alias of :py:exc:`keystoneauth1.exceptions.http.NotAcceptable`
+"""
+ProxyAuthenticationRequired = _exc.ProxyAuthenticationRequired
+"""HTTP 407 - Proxy Authentication Required.
-class MethodNotAllowed(HTTPClientError):
- """HTTP 405 - Method Not Allowed.
+The client must first authenticate itself with the proxy.
+An alias of :py:exc:`keystoneauth1.exceptions.http.ProxyAuthenticationRequired`
+"""
- A request was made of a resource using a request method not supported
- by that resource.
- """
- http_status = 405
- message = _("Method Not Allowed")
+RequestTimeout = _exc.RequestTimeout
+"""HTTP 408 - Request Timeout.
+The server timed out waiting for the request.
+An alias of :py:exc:`keystoneauth1.exceptions.http.RequestTimeout`
+"""
-class NotAcceptable(HTTPClientError):
- """HTTP 406 - Not Acceptable.
+Conflict = _exc.Conflict
+"""HTTP 409 - Conflict.
- The requested resource is only capable of generating content not
- acceptable according to the Accept headers sent in the request.
- """
- http_status = 406
- message = _("Not Acceptable")
+Indicates that the request could not be processed because of conflict
+in the request, such as an edit conflict.
+An alias of :py:exc:`keystoneauth1.exceptions.http.Conflict`
+"""
+Gone = _exc.Gone
+"""HTTP 410 - Gone.
-class ProxyAuthenticationRequired(HTTPClientError):
- """HTTP 407 - Proxy Authentication Required.
+Indicates that the resource requested is no longer available and will
+not be available again.
+An alias of :py:exc:`keystoneauth1.exceptions.http.Gone`
+"""
- The client must first authenticate itself with the proxy.
- """
- http_status = 407
- message = _("Proxy Authentication Required")
+LengthRequired = _exc.LengthRequired
+"""HTTP 411 - Length Required.
+The request did not specify the length of its content, which is
+required by the requested resource.
+An alias of :py:exc:`keystoneauth1.exceptions.http.LengthRequired`
+"""
-class RequestTimeout(HTTPClientError):
- """HTTP 408 - Request Timeout.
+PreconditionFailed = _exc.PreconditionFailed
+"""HTTP 412 - Precondition Failed.
- The server timed out waiting for the request.
- """
- http_status = 408
- message = _("Request Timeout")
+The server does not meet one of the preconditions that the requester
+put on the request.
+An alias of :py:exc:`keystoneauth1.exceptions.http.PreconditionFailed`
+"""
+RequestEntityTooLarge = _exc.RequestEntityTooLarge
+"""HTTP 413 - Request Entity Too Large.
-class Conflict(HTTPClientError):
- """HTTP 409 - Conflict.
+The request is larger than the server is willing or able to process.
+An alias of :py:exc:`keystoneauth1.exceptions.http.RequestEntityTooLarge`
+"""
- Indicates that the request could not be processed because of conflict
- in the request, such as an edit conflict.
- """
- http_status = 409
- message = _("Conflict")
+RequestUriTooLong = _exc.RequestUriTooLong
+"""HTTP 414 - Request-URI Too Long.
+The URI provided was too long for the server to process.
+An alias of :py:exc:`keystoneauth1.exceptions.http.RequestUriTooLong`
+"""
-class Gone(HTTPClientError):
- """HTTP 410 - Gone.
+UnsupportedMediaType = _exc.UnsupportedMediaType
+"""HTTP 415 - Unsupported Media Type.
- Indicates that the resource requested is no longer available and will
- not be available again.
- """
- http_status = 410
- message = _("Gone")
+The request entity has a media type which the server or resource does
+not support.
+An alias of :py:exc:`keystoneauth1.exceptions.http.UnsupportedMediaType`
+"""
+RequestedRangeNotSatisfiable = _exc.RequestedRangeNotSatisfiable
+"""HTTP 416 - Requested Range Not Satisfiable.
-class LengthRequired(HTTPClientError):
- """HTTP 411 - Length Required.
+The client has asked for a portion of the file, but the server cannot
+supply that portion.
+An alias of
+:py:exc:`keystoneauth1.exceptions.http.RequestedRangeNotSatisfiable`
+"""
- The request did not specify the length of its content, which is
- required by the requested resource.
- """
- http_status = 411
- message = _("Length Required")
+ExpectationFailed = _exc.ExpectationFailed
+"""HTTP 417 - Expectation Failed.
+The server cannot meet the requirements of the Expect request-header field.
+An alias of :py:exc:`keystoneauth1.exceptions.http.ExpectationFailed`
+"""
-class PreconditionFailed(HTTPClientError):
- """HTTP 412 - Precondition Failed.
+UnprocessableEntity = _exc.UnprocessableEntity
+"""HTTP 422 - Unprocessable Entity.
- The server does not meet one of the preconditions that the requester
- put on the request.
- """
- http_status = 412
- message = _("Precondition Failed")
+The request was well-formed but was unable to be followed due to semantic
+errors.
+An alias of :py:exc:`keystoneauth1.exceptions.http.UnprocessableEntity`
+"""
+InternalServerError = _exc.InternalServerError
+"""HTTP 500 - Internal Server Error.
-class RequestEntityTooLarge(HTTPClientError):
- """HTTP 413 - Request Entity Too Large.
+A generic error message, given when no more specific message is suitable.
+An alias of :py:exc:`keystoneauth1.exceptions.http.InternalServerError`
+"""
- The request is larger than the server is willing or able to process.
- """
- http_status = 413
- message = _("Request Entity Too Large")
+HttpNotImplemented = _exc.HttpNotImplemented
+"""HTTP 501 - Not Implemented.
- def __init__(self, *args, **kwargs):
- try:
- self.retry_after = int(kwargs.pop('retry_after'))
- except (KeyError, ValueError):
- self.retry_after = 0
+The server either does not recognize the request method, or it lacks
+the ability to fulfill the request.
+An alias of :py:exc:`keystoneauth1.exceptions.http.HttpNotImplemented`
+"""
- super(RequestEntityTooLarge, self).__init__(*args, **kwargs)
+BadGateway = _exc.BadGateway
+"""HTTP 502 - Bad Gateway.
+The server was acting as a gateway or proxy and received an invalid
+response from the upstream server.
+An alias of :py:exc:`keystoneauth1.exceptions.http.BadGateway`
+"""
-class RequestUriTooLong(HTTPClientError):
- """HTTP 414 - Request-URI Too Long.
+ServiceUnavailable = _exc.ServiceUnavailable
+"""HTTP 503 - Service Unavailable.
- The URI provided was too long for the server to process.
- """
- http_status = 414
- message = _("Request-URI Too Long")
+The server is currently unavailable.
+An alias of :py:exc:`keystoneauth1.exceptions.http.ServiceUnavailable`
+"""
+GatewayTimeout = _exc.GatewayTimeout
+"""HTTP 504 - Gateway Timeout.
-class UnsupportedMediaType(HTTPClientError):
- """HTTP 415 - Unsupported Media Type.
-
- The request entity has a media type which the server or resource does
- not support.
- """
- http_status = 415
- message = _("Unsupported Media Type")
+The server was acting as a gateway or proxy and did not receive a timely
+response from the upstream server.
+An alias of :py:exc:`keystoneauth1.exceptions.http.GatewayTimeout`
+"""
+HttpVersionNotSupported = _exc.HttpVersionNotSupported
+"""HTTP 505 - HttpVersion Not Supported.
-class RequestedRangeNotSatisfiable(HTTPClientError):
- """HTTP 416 - Requested Range Not Satisfiable.
-
- The client has asked for a portion of the file, but the server cannot
- supply that portion.
- """
- http_status = 416
- message = _("Requested Range Not Satisfiable")
+The server does not support the HTTP protocol version used in the request.
+An alias of :py:exc:`keystoneauth1.exceptions.http.HttpVersionNotSupported`
+"""
+from_response = _exc.from_response
+"""Returns an instance of :class:`HttpError` or subclass based on response.
-class ExpectationFailed(HTTPClientError):
- """HTTP 417 - Expectation Failed.
-
- The server cannot meet the requirements of the Expect request-header field.
- """
- http_status = 417
- message = _("Expectation Failed")
-
-
-class UnprocessableEntity(HTTPClientError):
- """HTTP 422 - Unprocessable Entity.
-
- The request was well-formed but was unable to be followed due to semantic
- errors.
- """
- http_status = 422
- message = _("Unprocessable Entity")
-
-
-class InternalServerError(HttpServerError):
- """HTTP 500 - Internal Server Error.
-
- A generic error message, given when no more specific message is suitable.
- """
- http_status = 500
- message = _("Internal Server Error")
-
-
-# NotImplemented is a python keyword.
-class HttpNotImplemented(HttpServerError):
- """HTTP 501 - Not Implemented.
-
- The server either does not recognize the request method, or it lacks
- the ability to fulfill the request.
- """
- http_status = 501
- message = _("Not Implemented")
-
-
-class BadGateway(HttpServerError):
- """HTTP 502 - Bad Gateway.
-
- The server was acting as a gateway or proxy and received an invalid
- response from the upstream server.
- """
- http_status = 502
- message = _("Bad Gateway")
-
-
-class ServiceUnavailable(HttpServerError):
- """HTTP 503 - Service Unavailable.
-
- The server is currently unavailable.
- """
- http_status = 503
- message = _("Service Unavailable")
-
-
-class GatewayTimeout(HttpServerError):
- """HTTP 504 - Gateway Timeout.
-
- The server was acting as a gateway or proxy and did not receive a timely
- response from the upstream server.
- """
- http_status = 504
- message = _("Gateway Timeout")
-
-
-class HttpVersionNotSupported(HttpServerError):
- """HTTP 505 - HttpVersion Not Supported.
-
- The server does not support the HTTP protocol version used in the request.
- """
- http_status = 505
- message = _("HTTP Version Not Supported")
-
-
-# _code_map contains all the classes that have http_status attribute.
-_code_map = dict(
- (getattr(obj, 'http_status', None), obj)
- for name, obj in six.iteritems(vars(sys.modules[__name__]))
- if inspect.isclass(obj) and getattr(obj, 'http_status', False)
-)
-
-
-def from_response(response, method, url):
- """Returns an instance of :class:`HttpError` or subclass based on response.
-
- :param response: instance of `requests.Response` class
- :param method: HTTP method used for request
- :param url: URL used for request
- """
-
- req_id = response.headers.get("x-openstack-request-id")
- # NOTE(hdd) true for older versions of nova and cinder
- if not req_id:
- req_id = response.headers.get("x-compute-request-id")
- kwargs = {
- "http_status": response.status_code,
- "response": response,
- "method": method,
- "url": url,
- "request_id": req_id,
- }
- if "retry-after" in response.headers:
- kwargs["retry_after"] = response.headers["retry-after"]
-
- content_type = response.headers.get("Content-Type", "")
- if content_type.startswith("application/json"):
- try:
- body = response.json()
- except ValueError:
- pass
- else:
- if isinstance(body, dict):
- error = body.get(list(body)[0])
- if isinstance(error, dict):
- kwargs["message"] = (error.get("message") or
- error.get("faultstring"))
- kwargs["details"] = (error.get("details") or
- six.text_type(body))
- elif content_type.startswith("text/"):
- kwargs["details"] = getattr(response, 'text', '')
-
- try:
- cls = _code_map[response.status_code]
- except KeyError:
- if 500 <= response.status_code < 600:
- cls = HttpServerError
- elif 400 <= response.status_code < 500:
- cls = HTTPClientError
- else:
- cls = HttpError
- return cls(**kwargs)
+An alias of :py:func:`keystoneauth1.exceptions.http.from_response`
+"""
# NOTE(akurilin): This alias should be left here to support backwards
# compatibility until we are sure that usage of these exceptions in
# projects is correct.
-ConnectionError = ConnectionRefused
HTTPNotImplemented = HttpNotImplemented
Timeout = RequestTimeout
HTTPError = HttpError
@@ -484,47 +366,40 @@ class CMSError(Exception):
msg = _('Unable to sign or verify data.')
super(CMSError, self).__init__(msg)
+EmptyCatalog = _exc.EmptyCatalog
+"""The service catalog is empty.
-class EmptyCatalog(EndpointNotFound):
- """The service catalog is empty."""
- pass
-
-
-class SSLError(ConnectionRefused):
- """An SSL error occurred."""
+An alias of :py:exc:`keystoneauth1.exceptions.catalog.EmptyCatalog`
+"""
+DiscoveryFailure = _exc.DiscoveryFailure
+"""Discovery of client versions failed.
-class DiscoveryFailure(ClientException):
- """Discovery of client versions failed."""
+An alias of :py:exc:`keystoneauth1.exceptions.discovery.DiscoveryFailure`
+"""
+VersionNotAvailable = _exc.VersionNotAvailable
+"""Discovery failed as the version you requested is not available.
-class VersionNotAvailable(DiscoveryFailure):
- """Discovery failed as the version you requested is not available."""
+An alias of :py:exc:`keystoneauth1.exceptions.discovery.VersionNotAvailable`
+"""
class MethodNotImplemented(ClientException):
"""Method not implemented by the keystoneclient API."""
+MissingAuthPlugin = _exc.MissingAuthPlugin
+"""An authenticated request is required but no plugin available.
-class MissingAuthPlugin(ClientException):
- """An authenticated request is required but no plugin available."""
-
-
-class NoMatchingPlugin(ClientException):
- """There were no auth plugins that could be created from the parameters
- provided.
+An alias of :py:exc:`keystoneauth1.exceptions.auth_plugins.MissingAuthPlugin`
+"""
- :param str name: The name of the plugin that was attempted to load.
-
- .. py:attribute:: name
-
- The name of the plugin that was attempted to load.
- """
+NoMatchingPlugin = _exc.NoMatchingPlugin
+"""There were no auth plugins that could be created from the parameters
+provided.
- def __init__(self, name):
- self.name = name
- msg = _('The plugin %s could not be found') % name
- super(NoMatchingPlugin, self).__init__(msg)
+An alias of :py:exc:`keystoneauth1.exceptions.auth_plugins.NoMatchingPlugin`
+"""
class UnsupportedParameters(ClientException):