From a13fc6932ddef5e3e56ef76ca1167ff55254a200 Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Tue, 10 Jun 2014 13:30:39 +0200 Subject: [PATCH] Removed usage of the py3kcompat module Like mentioned in I8e0b49cdfbddcf2d44a601ad06be2e75897905fc the py3kcompat module is deprecated and should not be used. Updated module apiclient from oslo-incubator to use six instead of py3kcompat. Added six >= 1.6.0 as new requirement. Change-Id: I2253e5a2701ad046f76a8539405baac2eac739f6 --- requirements.txt | 1 + solumclient/common/base.py | 5 +- solumclient/openstack/common/__init__.py | 15 ++++ .../openstack/common/apiclient/auth.py | 4 +- .../openstack/common/apiclient/base.py | 15 +++- .../openstack/common/apiclient/client.py | 16 ++-- .../openstack/common/apiclient/exceptions.py | 77 ++++++++++--------- .../openstack/common/py3kcompat/__init__.py | 0 .../openstack/common/py3kcompat/urlutils.py | 65 ---------------- 9 files changed, 85 insertions(+), 113 deletions(-) delete mode 100644 solumclient/openstack/common/py3kcompat/__init__.py delete mode 100644 solumclient/openstack/common/py3kcompat/urlutils.py diff --git a/requirements.txt b/requirements.txt index 1e8fe66..53c6daa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ requests>=1.1 python-keystoneclient>=0.8.0 PyYAML>=3.1.0 stevedore>=0.14 +six>=1.6.0 diff --git a/solumclient/common/base.py b/solumclient/common/base.py index a40d8fa..3c0e2a1 100644 --- a/solumclient/common/base.py +++ b/solumclient/common/base.py @@ -12,9 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. +from six.moves.urllib import parse as urlparse + from solumclient.openstack.common.apiclient import base from solumclient.openstack.common.apiclient import exceptions -from solumclient.openstack.common.py3kcompat import urlutils class ManagerMixin(): @@ -148,7 +149,7 @@ class CrudManager(ManagerMixin, base.CrudManager): return self._list( '%(base_url)s%(query)s' % { 'base_url': self.build_url(base_url=base_url, **kwargs), - 'query': '?%s' % urlutils.urlencode(kwargs) if kwargs else '', + 'query': '?%s' % urlparse.urlencode(kwargs) if kwargs else '', }) def get(self, **kwargs): diff --git a/solumclient/openstack/common/__init__.py b/solumclient/openstack/common/__init__.py index 2a00f3b..d1223ea 100644 --- a/solumclient/openstack/common/__init__.py +++ b/solumclient/openstack/common/__init__.py @@ -1,2 +1,17 @@ +# +# 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. + import six + + six.add_move(six.MovedModule('mox', 'mox', 'mox3.mox')) diff --git a/solumclient/openstack/common/apiclient/auth.py b/solumclient/openstack/common/apiclient/auth.py index 2f6b498..d370cfa 100644 --- a/solumclient/openstack/common/apiclient/auth.py +++ b/solumclient/openstack/common/apiclient/auth.py @@ -213,8 +213,8 @@ class BaseAuthPlugin(object): :type service_type: string :param endpoint_type: Type of endpoint. Possible values: public or publicURL, - internal or internalURL, - admin or adminURL + internal or internalURL, + admin or adminURL :type endpoint_type: string :returns: tuple of token and endpoint strings :raises: EndpointException diff --git a/solumclient/openstack/common/apiclient/base.py b/solumclient/openstack/common/apiclient/base.py index b84bd21..401a470 100644 --- a/solumclient/openstack/common/apiclient/base.py +++ b/solumclient/openstack/common/apiclient/base.py @@ -30,6 +30,7 @@ import six from six.moves.urllib import parse from solumclient.openstack.common.apiclient import exceptions +from solumclient.openstack.common.gettextutils import _ from solumclient.openstack.common import strutils @@ -74,8 +75,8 @@ class HookableMixin(object): :param cls: class that registers hooks :param hook_type: hook type, e.g., '__pre_parse_args__' - :param **args: args to be passed to every hook function - :param **kwargs: kwargs to be passed to every hook function + :param args: args to be passed to every hook function + :param kwargs: kwargs to be passed to every hook function """ hook_funcs = cls._hooks_map.get(hook_type) or [] for hook_func in hook_funcs: @@ -219,7 +220,10 @@ class ManagerWithFind(BaseManager): matches = self.findall(**kwargs) num_matches = len(matches) if num_matches == 0: - msg = "No %s matching %s." % (self.resource_class.__name__, kwargs) + msg = _("No %(name)s matching %(args)s.") % { + 'name': self.resource_class.__name__, + 'args': kwargs + } raise exceptions.NotFound(msg) elif num_matches > 1: raise exceptions.NoUniqueMatch() @@ -373,7 +377,10 @@ class CrudManager(BaseManager): num = len(rl) if num == 0: - msg = "No %s matching %s." % (self.resource_class.__name__, kwargs) + msg = _("No %(name)s matching %(args)s.") % { + 'name': self.resource_class.__name__, + 'args': kwargs + } raise exceptions.NotFound(404, msg) elif num > 1: raise exceptions.NoUniqueMatch diff --git a/solumclient/openstack/common/apiclient/client.py b/solumclient/openstack/common/apiclient/client.py index f0347cd..26c1ffb 100644 --- a/solumclient/openstack/common/apiclient/client.py +++ b/solumclient/openstack/common/apiclient/client.py @@ -36,6 +36,7 @@ except ImportError: import requests from solumclient.openstack.common.apiclient import exceptions +from solumclient.openstack.common.gettextutils import _ from solumclient.openstack.common import importutils @@ -46,6 +47,7 @@ class HTTPClient(object): """This client handles sending HTTP requests to OpenStack servers. Features: + - share authentication information between several clients to different services (e.g., for compute and image clients); - reissue authentication request for expired tokens; @@ -151,7 +153,7 @@ class HTTPClient(object): :param method: method of HTTP request :param url: URL of HTTP request :param kwargs: any other parameter that can be passed to -' requests.Session.request (such as `headers`) or `json` + requests.Session.request (such as `headers`) or `json` that will be encoded as JSON and used as `data` argument """ kwargs.setdefault("headers", kwargs.get("headers", {})) @@ -206,7 +208,7 @@ class HTTPClient(object): :param method: method of HTTP request :param url: URL of HTTP request :param kwargs: any other parameter that can be passed to -' `HTTPClient.request` + `HTTPClient.request` """ filter_args = { @@ -228,7 +230,7 @@ class HTTPClient(object): **filter_args) if not (token and endpoint): raise exceptions.AuthorizationFailure( - "Cannot find endpoint or token for request") + _("Cannot find endpoint or token for request")) old_token_endpoint = (token, endpoint) kwargs.setdefault("headers", {})["X-Auth-Token"] = token @@ -351,8 +353,12 @@ class BaseClient(object): try: client_path = version_map[str(version)] except (KeyError, ValueError): - msg = "Invalid %s client version '%s'. must be one of: %s" % ( - (api_name, version, ', '.join(version_map.keys()))) + msg = _("Invalid %(api_name)s client version '%(version)s'. " + "Must be one of: %(version_map)s") % { + 'api_name': api_name, + 'version': version, + 'version_map': ', '.join(version_map.keys()) + } raise exceptions.UnsupportedVersion(msg) return importutils.import_class(client_path) diff --git a/solumclient/openstack/common/apiclient/exceptions.py b/solumclient/openstack/common/apiclient/exceptions.py index ada1344..0c2a3ba 100644 --- a/solumclient/openstack/common/apiclient/exceptions.py +++ b/solumclient/openstack/common/apiclient/exceptions.py @@ -25,6 +25,8 @@ import sys import six +from solumclient.openstack.common.gettextutils import _ + class ClientException(Exception): """The base exception class for all exceptions this library raises. @@ -36,7 +38,7 @@ class MissingArgs(ClientException): """Supplied arguments are not sufficient for calling a function.""" def __init__(self, missing): self.missing = missing - msg = "Missing argument(s): %s" % ", ".join(missing) + msg = _("Missing arguments: %s") % ", ".join(missing) super(MissingArgs, self).__init__(msg) @@ -69,7 +71,7 @@ class AuthPluginOptionsMissing(AuthorizationFailure): """Auth plugin misses some options.""" def __init__(self, opt_names): super(AuthPluginOptionsMissing, self).__init__( - "Authentication failed. Missing options: %s" % + _("Authentication failed. Missing options: %s") % ", ".join(opt_names)) self.opt_names = opt_names @@ -78,7 +80,7 @@ class AuthSystemNotFound(AuthorizationFailure): """User has specified a AuthSystem that is not installed.""" def __init__(self, auth_system): super(AuthSystemNotFound, self).__init__( - "AuthSystemNotFound: %s" % repr(auth_system)) + _("AuthSystemNotFound: %s") % repr(auth_system)) self.auth_system = auth_system @@ -101,7 +103,7 @@ class AmbiguousEndpoints(EndpointException): """Found more than one matching endpoint in Service Catalog.""" def __init__(self, endpoints=None): super(AmbiguousEndpoints, self).__init__( - "AmbiguousEndpoints: %s" % repr(endpoints)) + _("AmbiguousEndpoints: %s") % repr(endpoints)) self.endpoints = endpoints @@ -109,7 +111,7 @@ class HttpError(ClientException): """The base exception class for all HTTP exceptions. """ http_status = 0 - message = "HTTP Error" + message = _("HTTP Error") def __init__(self, message=None, details=None, response=None, request_id=None, @@ -129,7 +131,7 @@ class HttpError(ClientException): class HTTPRedirection(HttpError): """HTTP Redirection.""" - message = "HTTP Redirection" + message = _("HTTP Redirection") class HTTPClientError(HttpError): @@ -137,7 +139,7 @@ class HTTPClientError(HttpError): Exception for cases in which the client seems to have erred. """ - message = "HTTP Client Error" + message = _("HTTP Client Error") class HttpServerError(HttpError): @@ -146,7 +148,7 @@ class HttpServerError(HttpError): Exception for cases in which the server is aware that it has erred or is incapable of performing the request. """ - message = "HTTP Server Error" + message = _("HTTP Server Error") class MultipleChoices(HTTPRedirection): @@ -156,7 +158,7 @@ class MultipleChoices(HTTPRedirection): """ http_status = 300 - message = "Multiple Choices" + message = _("Multiple Choices") class BadRequest(HTTPClientError): @@ -165,7 +167,7 @@ class BadRequest(HTTPClientError): The request cannot be fulfilled due to bad syntax. """ http_status = 400 - message = "Bad Request" + message = _("Bad Request") class Unauthorized(HTTPClientError): @@ -175,7 +177,7 @@ class Unauthorized(HTTPClientError): is required and has failed or has not yet been provided. """ http_status = 401 - message = "Unauthorized" + message = _("Unauthorized") class PaymentRequired(HTTPClientError): @@ -184,7 +186,7 @@ class PaymentRequired(HTTPClientError): Reserved for future use. """ http_status = 402 - message = "Payment Required" + message = _("Payment Required") class Forbidden(HTTPClientError): @@ -194,7 +196,7 @@ class Forbidden(HTTPClientError): to it. """ http_status = 403 - message = "Forbidden" + message = _("Forbidden") class NotFound(HTTPClientError): @@ -204,7 +206,7 @@ class NotFound(HTTPClientError): in the future. """ http_status = 404 - message = "Not Found" + message = _("Not Found") class MethodNotAllowed(HTTPClientError): @@ -214,7 +216,7 @@ class MethodNotAllowed(HTTPClientError): by that resource. """ http_status = 405 - message = "Method Not Allowed" + message = _("Method Not Allowed") class NotAcceptable(HTTPClientError): @@ -224,7 +226,7 @@ class NotAcceptable(HTTPClientError): acceptable according to the Accept headers sent in the request. """ http_status = 406 - message = "Not Acceptable" + message = _("Not Acceptable") class ProxyAuthenticationRequired(HTTPClientError): @@ -233,7 +235,7 @@ class ProxyAuthenticationRequired(HTTPClientError): The client must first authenticate itself with the proxy. """ http_status = 407 - message = "Proxy Authentication Required" + message = _("Proxy Authentication Required") class RequestTimeout(HTTPClientError): @@ -242,7 +244,7 @@ class RequestTimeout(HTTPClientError): The server timed out waiting for the request. """ http_status = 408 - message = "Request Timeout" + message = _("Request Timeout") class Conflict(HTTPClientError): @@ -252,7 +254,7 @@ class Conflict(HTTPClientError): in the request, such as an edit conflict. """ http_status = 409 - message = "Conflict" + message = _("Conflict") class Gone(HTTPClientError): @@ -262,7 +264,7 @@ class Gone(HTTPClientError): not be available again. """ http_status = 410 - message = "Gone" + message = _("Gone") class LengthRequired(HTTPClientError): @@ -272,7 +274,7 @@ class LengthRequired(HTTPClientError): required by the requested resource. """ http_status = 411 - message = "Length Required" + message = _("Length Required") class PreconditionFailed(HTTPClientError): @@ -282,7 +284,7 @@ class PreconditionFailed(HTTPClientError): put on the request. """ http_status = 412 - message = "Precondition Failed" + message = _("Precondition Failed") class RequestEntityTooLarge(HTTPClientError): @@ -291,7 +293,7 @@ class RequestEntityTooLarge(HTTPClientError): The request is larger than the server is willing or able to process. """ http_status = 413 - message = "Request Entity Too Large" + message = _("Request Entity Too Large") def __init__(self, *args, **kwargs): try: @@ -308,7 +310,7 @@ class RequestUriTooLong(HTTPClientError): The URI provided was too long for the server to process. """ http_status = 414 - message = "Request-URI Too Long" + message = _("Request-URI Too Long") class UnsupportedMediaType(HTTPClientError): @@ -318,7 +320,7 @@ class UnsupportedMediaType(HTTPClientError): not support. """ http_status = 415 - message = "Unsupported Media Type" + message = _("Unsupported Media Type") class RequestedRangeNotSatisfiable(HTTPClientError): @@ -328,7 +330,7 @@ class RequestedRangeNotSatisfiable(HTTPClientError): supply that portion. """ http_status = 416 - message = "Requested Range Not Satisfiable" + message = _("Requested Range Not Satisfiable") class ExpectationFailed(HTTPClientError): @@ -337,7 +339,7 @@ class ExpectationFailed(HTTPClientError): The server cannot meet the requirements of the Expect request-header field. """ http_status = 417 - message = "Expectation Failed" + message = _("Expectation Failed") class UnprocessableEntity(HTTPClientError): @@ -347,7 +349,7 @@ class UnprocessableEntity(HTTPClientError): errors. """ http_status = 422 - message = "Unprocessable Entity" + message = _("Unprocessable Entity") class InternalServerError(HttpServerError): @@ -356,7 +358,7 @@ class InternalServerError(HttpServerError): A generic error message, given when no more specific message is suitable. """ http_status = 500 - message = "Internal Server Error" + message = _("Internal Server Error") # NotImplemented is a python keyword. @@ -367,7 +369,7 @@ class HttpNotImplemented(HttpServerError): the ability to fulfill the request. """ http_status = 501 - message = "Not Implemented" + message = _("Not Implemented") class BadGateway(HttpServerError): @@ -377,7 +379,7 @@ class BadGateway(HttpServerError): response from the upstream server. """ http_status = 502 - message = "Bad Gateway" + message = _("Bad Gateway") class ServiceUnavailable(HttpServerError): @@ -386,7 +388,7 @@ class ServiceUnavailable(HttpServerError): The server is currently unavailable. """ http_status = 503 - message = "Service Unavailable" + message = _("Service Unavailable") class GatewayTimeout(HttpServerError): @@ -396,7 +398,7 @@ class GatewayTimeout(HttpServerError): response from the upstream server. """ http_status = 504 - message = "Gateway Timeout" + message = _("Gateway Timeout") class HttpVersionNotSupported(HttpServerError): @@ -405,7 +407,7 @@ class HttpVersionNotSupported(HttpServerError): The server does not support the HTTP protocol version used in the request. """ http_status = 505 - message = "HTTP Version Not Supported" + message = _("HTTP Version Not Supported") # _code_map contains all the classes that have http_status attribute. @@ -423,12 +425,17 @@ def from_response(response, method, url): :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": response.headers.get("x-compute-request-id"), + "request_id": req_id, } if "retry-after" in response.headers: kwargs["retry_after"] = response.headers["retry-after"] diff --git a/solumclient/openstack/common/py3kcompat/__init__.py b/solumclient/openstack/common/py3kcompat/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/solumclient/openstack/common/py3kcompat/urlutils.py b/solumclient/openstack/common/py3kcompat/urlutils.py deleted file mode 100644 index 6200271..0000000 --- a/solumclient/openstack/common/py3kcompat/urlutils.py +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright 2013 Canonical 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 -# -# 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. -# - -""" -Python2/Python3 compatibility layer for OpenStack -""" - -import six - -if six.PY3: - # python3 - import urllib.error - import urllib.parse - import urllib.request - - urlencode = urllib.parse.urlencode - urljoin = urllib.parse.urljoin - quote = urllib.parse.quote - parse_qsl = urllib.parse.parse_qsl - unquote = urllib.parse.unquote - unquote_plus = urllib.parse.unquote_plus - urlparse = urllib.parse.urlparse - urlsplit = urllib.parse.urlsplit - urlunsplit = urllib.parse.urlunsplit - SplitResult = urllib.parse.SplitResult - - urlopen = urllib.request.urlopen - URLError = urllib.error.URLError - pathname2url = urllib.request.pathname2url -else: - # python2 - import urllib - import urllib2 - import urlparse - - urlencode = urllib.urlencode - quote = urllib.quote - unquote = urllib.unquote - unquote_plus = urllib.unquote_plus - - parse = urlparse - parse_qsl = parse.parse_qsl - urljoin = parse.urljoin - urlparse = parse.urlparse - urlsplit = parse.urlsplit - urlunsplit = parse.urlunsplit - SplitResult = parse.SplitResult - - urlopen = urllib2.urlopen - URLError = urllib2.URLError - pathname2url = urllib.pathname2url