Advertisement
shaifali

glanceclient- exceptions.py

Oct 2nd, 2014
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.71 KB | None | 0 0
  1. # Copyright 2010 Jacob Kaplan-Moss
  2. # Copyright 2011 Nebula, Inc.
  3. # Copyright 2013 Alessio Ababilov
  4. # Copyright 2013 OpenStack Foundation
  5. # All Rights Reserved.
  6. #
  7. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. # not use this file except in compliance with the License. You may obtain
  9. # a copy of the License at
  10. #
  11. # http://www.apache.org/licenses/LICENSE-2.0
  12. #
  13. # Unless required by applicable law or agreed to in writing, software
  14. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. # License for the specific language governing permissions and limitations
  17. # under the License.
  18.  
  19. """
  20. Exception definitions.
  21. """
  22.  
  23. import inspect
  24. import sys
  25.  
  26. import six
  27.  
  28. #for making exception messages in i18n
  29. from oslo import i18n
  30. #from oslo import *
  31. _translators = i18n.TranslatorFactory(domain='glanceclient')
  32.  
  33. # The primary translation function using the well-known name "_"
  34. _ = _translators.primary
  35.  
  36.  
  37.  
  38. class ClientException(Exception):
  39. """The base exception class for all exceptions this library raises.
  40. """
  41. pass
  42.  
  43.  
  44. class MissingArgs(ClientException):
  45. """Supplied arguments are not sufficient for calling a function."""
  46. def __init__(self, missing):
  47. self.missing = missing
  48. msg = _("Missing argument(s): %s") % ", ".join(missing)
  49. super(MissingArgs, self).__init__(msg)
  50.  
  51.  
  52. class ValidationError(ClientException):
  53. """Error in validation on API client side."""
  54. pass
  55.  
  56.  
  57. class UnsupportedVersion(ClientException):
  58. """User is trying to use an unsupported version of the API."""
  59. pass
  60.  
  61.  
  62. class CommandError(ClientException):
  63. """Error in CLI tool."""
  64. pass
  65.  
  66.  
  67. class AuthorizationFailure(ClientException):
  68. """Cannot authorize API client."""
  69. pass
  70.  
  71.  
  72. class ConnectionRefused(ClientException):
  73. """Cannot connect to API service."""
  74. pass
  75.  
  76.  
  77. class AuthPluginOptionsMissing(AuthorizationFailure):
  78. """Auth plugin misses some options."""
  79. def __init__(self, opt_names):
  80. super(AuthPluginOptionsMissing, self).__init__(
  81. "Authentication failed. Missing options: %s" %
  82. ", ".join(opt_names))
  83. self.opt_names = opt_names
  84.  
  85.  
  86. class AuthSystemNotFound(AuthorizationFailure):
  87. """User has specified a AuthSystem that is not installed."""
  88. def __init__(self, auth_system):
  89. super(AuthSystemNotFound, self).__init__(
  90. _("AuthSystemNotFound: %s") % repr(auth_system))
  91. self.auth_system = auth_system
  92.  
  93.  
  94. class NoUniqueMatch(ClientException):
  95. """Multiple entities found instead of one."""
  96. pass
  97.  
  98.  
  99. class EndpointException(ClientException):
  100. """Something is rotten in Service Catalog."""
  101. pass
  102.  
  103.  
  104. class EndpointNotFound(EndpointException):
  105. """Could not find requested endpoint in Service Catalog."""
  106. pass
  107.  
  108.  
  109. class AmbiguousEndpoints(EndpointException):
  110. """Found more than one matching endpoint in Service Catalog."""
  111. def __init__(self, endpoints=None):
  112. super(AmbiguousEndpoints, self).__init__(
  113. _("AmbiguousEndpoints: %s") % repr(endpoints))
  114. self.endpoints = endpoints
  115.  
  116.  
  117. class HttpError(ClientException):
  118. """The base exception class for all HTTP exceptions.
  119. """
  120. http_status = 0
  121. message = _("HTTP Error")
  122.  
  123. def __init__(self, message=None, details=None,
  124. response=None, request_id=None,
  125. url=None, method=None, http_status=None):
  126. self.http_status = http_status or self.http_status
  127. self.message = message or self.message
  128. self.details = details
  129. self.request_id = request_id
  130. self.response = response
  131. self.url = url
  132. self.method = method
  133. formatted_string = "%s (HTTP %s)" % (self.message, self.http_status)
  134. if request_id:
  135. formatted_string += " (Request-ID: %s)" % request_id
  136. super(HttpError, self).__init__(formatted_string)
  137.  
  138.  
  139. class HTTPRedirection(HttpError):
  140. """HTTP Redirection."""
  141. message = _("HTTP Redirection")
  142.  
  143.  
  144. class HTTPClientError(HttpError):
  145. """Client-side HTTP error.
  146.  
  147. Exception for cases in which the client seems to have erred.
  148. """
  149. message = _("HTTP Client Error")
  150.  
  151.  
  152. class HttpServerError(HttpError):
  153. """Server-side HTTP error.
  154.  
  155. Exception for cases in which the server is aware that it has
  156. erred or is incapable of performing the request.
  157. """
  158. message = _("HTTP Server Error")
  159.  
  160.  
  161. class MultipleChoices(HTTPRedirection):
  162. """HTTP 300 - Multiple Choices.
  163.  
  164. Indicates multiple options for the resource that the client may follow.
  165. """
  166.  
  167. http_status = 300
  168. message = _("Multiple Choices")
  169.  
  170.  
  171. class BadRequest(HTTPClientError):
  172. """HTTP 400 - Bad Request.
  173.  
  174. The request cannot be fulfilled due to bad syntax.
  175. """
  176. http_status = 400
  177. message = _("Bad Request")
  178.  
  179.  
  180. class Unauthorized(HTTPClientError):
  181. """HTTP 401 - Unauthorized.
  182.  
  183. Similar to 403 Forbidden, but specifically for use when authentication
  184. is required and has failed or has not yet been provided.
  185. """
  186. http_status = 401
  187. message = _("Unauthorized")
  188.  
  189.  
  190. class PaymentRequired(HTTPClientError):
  191. """HTTP 402 - Payment Required.
  192.  
  193. Reserved for future use.
  194. """
  195. http_status = 402
  196. message = _("Payment Required")
  197.  
  198.  
  199. class Forbidden(HTTPClientError):
  200. """HTTP 403 - Forbidden.
  201.  
  202. The request was a valid request, but the server is refusing to respond
  203. to it.
  204. """
  205. http_status = 403
  206. message = _("Forbidden")
  207.  
  208.  
  209. class NotFound(HTTPClientError):
  210. """HTTP 404 - Not Found.
  211.  
  212. The requested resource could not be found but may be available again
  213. in the future.
  214. """
  215. http_status = 404
  216. message = _("Not Found")
  217.  
  218.  
  219. class MethodNotAllowed(HTTPClientError):
  220. """HTTP 405 - Method Not Allowed.
  221.  
  222. A request was made of a resource using a request method not supported
  223. by that resource.
  224. """
  225. http_status = 405
  226. message = _("Method Not Allowed")
  227.  
  228.  
  229. class NotAcceptable(HTTPClientError):
  230. """HTTP 406 - Not Acceptable.
  231.  
  232. The requested resource is only capable of generating content not
  233. acceptable according to the Accept headers sent in the request.
  234. """
  235. http_status = 406
  236. message = _("Not Acceptable")
  237.  
  238.  
  239. class ProxyAuthenticationRequired(HTTPClientError):
  240. """HTTP 407 - Proxy Authentication Required.
  241.  
  242. The client must first authenticate itself with the proxy.
  243. """
  244. http_status = 407
  245. message = _("Proxy Authentication Required")
  246.  
  247.  
  248. class RequestTimeout(HTTPClientError):
  249. """HTTP 408 - Request Timeout.
  250.  
  251. The server timed out waiting for the request.
  252. """
  253. http_status = 408
  254. message = _("Request Timeout")
  255.  
  256.  
  257. class Conflict(HTTPClientError):
  258. """HTTP 409 - Conflict.
  259.  
  260. Indicates that the request could not be processed because of conflict
  261. in the request, such as an edit conflict.
  262. """
  263. http_status = 409
  264. message = _("Conflict")
  265.  
  266.  
  267. class Gone(HTTPClientError):
  268. """HTTP 410 - Gone.
  269.  
  270. Indicates that the resource requested is no longer available and will
  271. not be available again.
  272. """
  273. http_status = 410
  274. message = _("Gone")
  275.  
  276.  
  277. class LengthRequired(HTTPClientError):
  278. """HTTP 411 - Length Required.
  279.  
  280. The request did not specify the length of its content, which is
  281. required by the requested resource.
  282. """
  283. http_status = 411
  284. message = _("Length Required")
  285.  
  286.  
  287. class PreconditionFailed(HTTPClientError):
  288. """HTTP 412 - Precondition Failed.
  289.  
  290. The server does not meet one of the preconditions that the requester
  291. put on the request.
  292. """
  293. http_status = 412
  294. message = _("Precondition Failed")
  295.  
  296.  
  297. class RequestEntityTooLarge(HTTPClientError):
  298. """HTTP 413 - Request Entity Too Large.
  299.  
  300. The request is larger than the server is willing or able to process.
  301. """
  302. http_status = 413
  303. message = _("Request Entity Too Large")
  304.  
  305. def __init__(self, *args, **kwargs):
  306. try:
  307. self.retry_after = int(kwargs.pop('retry_after'))
  308. except (KeyError, ValueError):
  309. self.retry_after = 0
  310.  
  311. super(RequestEntityTooLarge, self).__init__(*args, **kwargs)
  312.  
  313.  
  314. class RequestUriTooLong(HTTPClientError):
  315. """HTTP 414 - Request-URI Too Long.
  316.  
  317. The URI provided was too long for the server to process.
  318. """
  319. http_status = 414
  320. message = _("Request-URI Too Long")
  321.  
  322.  
  323. class UnsupportedMediaType(HTTPClientError):
  324. """HTTP 415 - Unsupported Media Type.
  325.  
  326. The request entity has a media type which the server or resource does
  327. not support.
  328. """
  329. http_status = 415
  330. message = _("Unsupported Media Type")
  331.  
  332.  
  333. class RequestedRangeNotSatisfiable(HTTPClientError):
  334. """HTTP 416 - Requested Range Not Satisfiable.
  335.  
  336. The client has asked for a portion of the file, but the server cannot
  337. supply that portion.
  338. """
  339. http_status = 416
  340. message = _("Requested Range Not Satisfiable")
  341.  
  342.  
  343. class ExpectationFailed(HTTPClientError):
  344. """HTTP 417 - Expectation Failed.
  345.  
  346. The server cannot meet the requirements of the Expect request-header field.
  347. """
  348. http_status = 417
  349. message = _("Expectation Failed")
  350.  
  351.  
  352. class UnprocessableEntity(HTTPClientError):
  353. """HTTP 422 - Unprocessable Entity.
  354.  
  355. The request was well-formed but was unable to be followed due to semantic
  356. errors.
  357. """
  358. http_status = 422
  359. message = _("Unprocessable Entity")
  360.  
  361.  
  362. class InternalServerError(HttpServerError):
  363. """HTTP 500 - Internal Server Error.
  364.  
  365. A generic error message, given when no more specific message is suitable.
  366. """
  367. http_status = 500
  368. message = _("Internal Server Error")
  369.  
  370.  
  371. # NotImplemented is a python keyword.
  372. class HttpNotImplemented(HttpServerError):
  373. """HTTP 501 - Not Implemented.
  374.  
  375. The server either does not recognize the request method, or it lacks
  376. the ability to fulfill the request.
  377. """
  378. http_status = 501
  379. message = _("Not Implemented")
  380.  
  381.  
  382. class BadGateway(HttpServerError):
  383. """HTTP 502 - Bad Gateway.
  384.  
  385. The server was acting as a gateway or proxy and received an invalid
  386. response from the upstream server.
  387. """
  388. http_status = 502
  389. message = _("Bad Gateway")
  390.  
  391.  
  392. class ServiceUnavailable(HttpServerError):
  393. """HTTP 503 - Service Unavailable.
  394.  
  395. The server is currently unavailable.
  396. """
  397. http_status = 503
  398. message = _("Service Unavailable")
  399.  
  400.  
  401. class GatewayTimeout(HttpServerError):
  402. """HTTP 504 - Gateway Timeout.
  403.  
  404. The server was acting as a gateway or proxy and did not receive a timely
  405. response from the upstream server.
  406. """
  407. http_status = 504
  408. message = _("Gateway Timeout")
  409.  
  410.  
  411. class HttpVersionNotSupported(HttpServerError):
  412. """HTTP 505 - HttpVersion Not Supported.
  413.  
  414. The server does not support the HTTP protocol version used in the request.
  415. """
  416. http_status = 505
  417. message = _("HTTP Version Not Supported")
  418.  
  419.  
  420. # _code_map contains all the classes that have http_status attribute.
  421. _code_map = dict(
  422. (getattr(obj, 'http_status', None), obj)
  423. for name, obj in six.iteritems(vars(sys.modules[__name__]))
  424. if inspect.isclass(obj) and getattr(obj, 'http_status', False)
  425. )
  426.  
  427.  
  428. def from_response(response, method, url):
  429. """Returns an instance of :class:`HttpError` or subclass based on response.
  430.  
  431. :param response: instance of `requests.Response` class
  432. :param method: HTTP method used for request
  433. :param url: URL used for request
  434. """
  435. kwargs = {
  436. "http_status": response.status_code,
  437. "response": response,
  438. "method": method,
  439. "url": url,
  440. "request_id": response.headers.get("x-compute-request-id"),
  441. }
  442. if "retry-after" in response.headers:
  443. kwargs["retry_after"] = response.headers["retry-after"]
  444.  
  445. content_type = response.headers.get("Content-Type", "")
  446. if content_type.startswith("application/json"):
  447. try:
  448. body = response.json()
  449. except ValueError:
  450. pass
  451. else:
  452. if isinstance(body, dict):
  453. error = list(body.values())[0]
  454. kwargs["message"] = error.get("message")
  455. kwargs["details"] = error.get("details")
  456. elif content_type.startswith("text/"):
  457. kwargs["details"] = response.text
  458.  
  459. try:
  460. cls = _code_map[response.status_code]
  461. except KeyError:
  462. if 500 <= response.status_code < 600:
  463. cls = HttpServerError
  464. elif 400 <= response.status_code < 500:
  465. cls = HTTPClientError
  466. else:
  467. cls = HttpError
  468. return cls(**kwargs)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement