From 4a7cf9676694968fedace5100d72f880d3bad339 Mon Sep 17 00:00:00 2001 From: Andrey Kurilin Date: Fri, 8 May 2015 12:27:59 +0300 Subject: Sync latest code from oslo-incubator Hash of latest commit in oslo: f5646edc61b9653d7ff71ed0177ed77811bbdcd0 Change-Id: I2f3bf41434591fcfc811ae6dec40ccabd42db741 --- novaclient/openstack/common/_i18n.py | 49 ++++++++++++---------- novaclient/openstack/common/apiclient/auth.py | 13 ++++++ novaclient/openstack/common/apiclient/client.py | 27 ++++++++++-- .../openstack/common/apiclient/exceptions.py | 37 ++++++++++++---- .../openstack/common/apiclient/fake_client.py | 15 +++++++ novaclient/openstack/common/apiclient/utils.py | 17 +++++++- novaclient/openstack/common/cliutils.py | 15 +++++-- 7 files changed, 134 insertions(+), 39 deletions(-) diff --git a/novaclient/openstack/common/_i18n.py b/novaclient/openstack/common/_i18n.py index 6ae2ff23..c0749672 100644 --- a/novaclient/openstack/common/_i18n.py +++ b/novaclient/openstack/common/_i18n.py @@ -16,25 +16,30 @@ See http://docs.openstack.org/developer/oslo.i18n/usage.html """ -import oslo.i18n - - -# NOTE(dhellmann): This reference to o-s-l-o will be replaced by the -# application name when this module is synced into the separate -# repository. It is OK to have more than one translation function -# using the same domain, since there will still only be one message -# catalog. -_translators = oslo.i18n.TranslatorFactory(domain='novaclient') - -# The primary translation function using the well-known name "_" -_ = _translators.primary - -# Translators for log levels. -# -# The abbreviated names are meant to reflect the usual use of a short -# name like '_'. The "L" is for "log" and the other letter comes from -# the level. -_LI = _translators.log_info -_LW = _translators.log_warning -_LE = _translators.log_error -_LC = _translators.log_critical +try: + import oslo_i18n + + # NOTE(dhellmann): This reference to o-s-l-o will be replaced by the + # application name when this module is synced into the separate + # repository. It is OK to have more than one translation function + # using the same domain, since there will still only be one message + # catalog. + _translators = oslo_i18n.TranslatorFactory(domain='novaclient') + + # The primary translation function using the well-known name "_" + _ = _translators.primary + + # Translators for log levels. + # + # The abbreviated names are meant to reflect the usual use of a short + # name like '_'. The "L" is for "log" and the other letter comes from + # the level. + _LI = _translators.log_info + _LW = _translators.log_warning + _LE = _translators.log_error + _LC = _translators.log_critical +except ImportError: + # NOTE(dims): Support for cases where a project wants to use + # code from oslo-incubator, but is not ready to be internationalized + # (like tempest) + _ = _LI = _LW = _LE = _LC = lambda x: x diff --git a/novaclient/openstack/common/apiclient/auth.py b/novaclient/openstack/common/apiclient/auth.py index 67a1bf7d..68ed09fb 100644 --- a/novaclient/openstack/common/apiclient/auth.py +++ b/novaclient/openstack/common/apiclient/auth.py @@ -17,6 +17,19 @@ # E0202: An attribute inherited from %s hide this method # pylint: disable=E0202 +######################################################################## +# +# THIS MODULE IS DEPRECATED +# +# Please refer to +# https://etherpad.openstack.org/p/kilo-novaclient-library-proposals for +# the discussion leading to this deprecation. +# +# We recommend checking out the python-openstacksdk project +# (https://launchpad.net/python-openstacksdk) instead. +# +######################################################################## + import abc import argparse import os diff --git a/novaclient/openstack/common/apiclient/client.py b/novaclient/openstack/common/apiclient/client.py index c591850e..fa317c2d 100644 --- a/novaclient/openstack/common/apiclient/client.py +++ b/novaclient/openstack/common/apiclient/client.py @@ -25,6 +25,7 @@ OpenStack Client interface. Handles the REST calls and responses. # E0202: An attribute inherited from %s hide this method # pylint: disable=E0202 +import hashlib import logging import time @@ -33,14 +34,15 @@ try: except ImportError: import json -from oslo.utils import importutils +from oslo_utils import encodeutils +from oslo_utils import importutils import requests from novaclient.openstack.common._i18n import _ from novaclient.openstack.common.apiclient import exceptions - _logger = logging.getLogger(__name__) +SENSITIVE_HEADERS = ('X-Auth-Token', 'X-Subject-Token',) class HTTPClient(object): @@ -98,6 +100,18 @@ class HTTPClient(object): self.http = http or requests.Session() self.cached_token = None + self.last_request_id = None + + def _safe_header(self, name, value): + if name in SENSITIVE_HEADERS: + # because in python3 byte string handling is ... ug + v = value.encode('utf-8') + h = hashlib.sha1(v) + d = h.hexdigest() + return encodeutils.safe_decode(name), "{SHA1}%s" % d + else: + return (encodeutils.safe_decode(name), + encodeutils.safe_decode(value)) def _http_log_req(self, method, url, kwargs): if not self.debug: @@ -110,7 +124,8 @@ class HTTPClient(object): ] for element in kwargs['headers']: - header = "-H '%s: %s'" % (element, kwargs['headers'][element]) + header = ("-H '%s: %s'" % + self._safe_header(element, kwargs['headers'][element])) string_parts.append(header) _logger.debug("REQ: %s" % " ".join(string_parts)) @@ -177,6 +192,8 @@ class HTTPClient(object): start_time, time.time())) self._http_log_resp(resp) + self.last_request_id = resp.headers.get('x-openstack-request-id') + if resp.status_code >= 400: _logger.debug( "Request returned failure status: %s", @@ -327,6 +344,10 @@ class BaseClient(object): return self.http_client.client_request( self, method, url, **kwargs) + @property + def last_request_id(self): + return self.http_client.last_request_id + def head(self, url, **kwargs): return self.client_request("HEAD", url, **kwargs) diff --git a/novaclient/openstack/common/apiclient/exceptions.py b/novaclient/openstack/common/apiclient/exceptions.py index 15e885b9..540eefd3 100644 --- a/novaclient/openstack/common/apiclient/exceptions.py +++ b/novaclient/openstack/common/apiclient/exceptions.py @@ -20,6 +20,19 @@ Exception definitions. """ +######################################################################## +# +# THIS MODULE IS DEPRECATED +# +# Please refer to +# https://etherpad.openstack.org/p/kilo-novaclient-library-proposals for +# the discussion leading to this deprecation. +# +# We recommend checking out the python-openstacksdk project +# (https://launchpad.net/python-openstacksdk) instead. +# +######################################################################## + import inspect import sys @@ -54,11 +67,16 @@ class AuthorizationFailure(ClientException): pass -class ConnectionRefused(ClientException): +class ConnectionError(ClientException): """Cannot connect to API service.""" pass +class ConnectionRefused(ConnectionError): + """Connection refused while trying to connect to API service.""" + pass + + class AuthPluginOptionsMissing(AuthorizationFailure): """Auth plugin misses some options.""" def __init__(self, opt_names): @@ -72,7 +90,7 @@ class AuthSystemNotFound(AuthorizationFailure): """User has specified an AuthSystem that is not installed.""" def __init__(self, auth_system): super(AuthSystemNotFound, self).__init__( - _("AuthSystemNotFound: %s") % repr(auth_system)) + _("AuthSystemNotFound: %r") % auth_system) self.auth_system = auth_system @@ -95,7 +113,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: %r") % endpoints) self.endpoints = endpoints @@ -439,12 +457,15 @@ def from_response(response, method, url): except ValueError: pass else: - if isinstance(body, dict) and isinstance(body.get("error"), dict): - error = body["error"] - kwargs["message"] = error.get("message") - kwargs["details"] = error.get("details") + 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"] = response.text + kwargs["details"] = getattr(response, 'text', '') try: cls = _code_map[response.status_code] diff --git a/novaclient/openstack/common/apiclient/fake_client.py b/novaclient/openstack/common/apiclient/fake_client.py index eeb9b810..1a0324c8 100644 --- a/novaclient/openstack/common/apiclient/fake_client.py +++ b/novaclient/openstack/common/apiclient/fake_client.py @@ -21,6 +21,19 @@ wrong the tests might raise AssertionError. I've indicated in comments the places where actual behavior differs from the spec. """ +######################################################################## +# +# THIS MODULE IS DEPRECATED +# +# Please refer to +# https://etherpad.openstack.org/p/kilo-novaclient-library-proposals for +# the discussion leading to this deprecation. +# +# We recommend checking out the python-openstacksdk project +# (https://launchpad.net/python-openstacksdk) instead. +# +######################################################################## + # W0102: Dangerous default value %s as argument # pylint: disable=W0102 @@ -168,6 +181,8 @@ class FakeHTTPClient(client.HTTPClient): else: status, body = resp headers = {} + self.last_request_id = headers.get('x-openstack-request-id', + 'req-test') return TestResponse({ "status_code": status, "text": body, diff --git a/novaclient/openstack/common/apiclient/utils.py b/novaclient/openstack/common/apiclient/utils.py index 09ddae43..c8938ef5 100644 --- a/novaclient/openstack/common/apiclient/utils.py +++ b/novaclient/openstack/common/apiclient/utils.py @@ -11,12 +11,25 @@ # License for the specific language governing permissions and limitations # under the License. -from oslo.utils import encodeutils +######################################################################## +# +# THIS MODULE IS DEPRECATED +# +# Please refer to +# https://etherpad.openstack.org/p/kilo-novaclient-library-proposals for +# the discussion leading to this deprecation. +# +# We recommend checking out the python-openstacksdk project +# (https://launchpad.net/python-openstacksdk) instead. +# +######################################################################## + +from oslo_utils import encodeutils +from oslo_utils import uuidutils import six from novaclient.openstack.common._i18n import _ from novaclient.openstack.common.apiclient import exceptions -from novaclient.openstack.common import uuidutils def find_resource(manager, name_or_id, **find_args): diff --git a/novaclient/openstack/common/cliutils.py b/novaclient/openstack/common/cliutils.py index ac2cf757..080dd2d4 100644 --- a/novaclient/openstack/common/cliutils.py +++ b/novaclient/openstack/common/cliutils.py @@ -24,8 +24,8 @@ import os import sys import textwrap -from oslo.utils import encodeutils -from oslo.utils import strutils +from oslo_utils import encodeutils +from oslo_utils import strutils import prettytable import six from six import moves @@ -180,7 +180,10 @@ def print_list(objs, fields, formatters=None, sortby_index=0, row.append(data) pt.add_row(row) - print(encodeutils.safe_encode(pt.get_string(**kwargs))) + if six.PY3: + print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode()) + else: + print(encodeutils.safe_encode(pt.get_string(**kwargs))) def print_dict(dct, dict_property="Property", wrap=0): @@ -208,7 +211,11 @@ def print_dict(dct, dict_property="Property", wrap=0): col1 = '' else: pt.add_row([k, v]) - print(encodeutils.safe_encode(pt.get_string())) + + if six.PY3: + print(encodeutils.safe_encode(pt.get_string()).decode()) + else: + print(encodeutils.safe_encode(pt.get_string())) def get_password(max_password_prompts=3): -- cgit v1.2.1