diff --git a/novaclient/openstack/common/_i18n.py b/novaclient/openstack/common/_i18n.py
index 6ae2ff239..c07496727 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
+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')
 
-# 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
 
-# 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
+    # 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 67a1bf7dd..68ed09fb5 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 c591850e6..fa317c2da 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 15e885b9b..540eefd34 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 eeb9b810a..1a0324c8a 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 09ddae43b..c8938ef54 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 ac2cf7573..080dd2d44 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):