From bf62bc73a0726f0c095a167bb9eca883916d8a00 Mon Sep 17 00:00:00 2001
From: adrian-turjak <adriant@catalyst.net.nz>
Date: Thu, 25 May 2017 20:55:07 +1200
Subject: [PATCH] Renamed to Adjutant and cull legacy code

* Renaming from StackTask to Adjutant.
* Cull unused or old elements of code originally
  from heatclient.
* Remove old cli as deprecation is redundant with the
  rename as well. Rename is now a blank slate for the cli
  and the cli is entirely OSC based.

Change-Id: Ic548bdd0f5dadfe537ffe5e1eed7725358c13fce
---
 .gitignore                                    |   3 +-
 .testr.conf                                   |   4 -
 AUTHORS~                                      |   2 -
 MANIFEST.in                                   |   2 +-
 README.md                                     |   0
 README.rst                                    |  14 +-
 .../__init__.py                               |   2 +-
 adjutantclient/_i18n.py                       |  37 ++
 {stacktaskclient => adjutantclient}/client.py |   5 +-
 .../common/__init__.py                        |   0
 .../common}/base.py                           |  55 +-
 .../common/http.py                            |  88 +--
 {stacktaskclient => adjutantclient}/exc.py    |   6 +-
 .../osc}/__init__.py                          |   0
 .../osc/plugin.py                             |  10 +-
 .../osc/v1}/__init__.py                       |   0
 .../osc/v1/notifications.py                   |   2 +-
 .../osc/v1/signup.py                          |   4 +-
 .../osc/v1/status.py                          |   2 +-
 .../osc/v1/tasks.py                           |   2 +-
 .../osc/v1/tokens.py                          |   6 +-
 .../osc/v1/users.py                           |   4 +-
 .../v1/__init__.py                            |   2 +-
 .../v1/client.py                              |  22 +-
 .../v1/notifications.py                       |   2 +-
 .../v1/roles.py                               |   6 +-
 .../v1/signup.py                              |   2 +-
 .../v1/status.py                              |   2 +-
 .../v1/tasks.py                               |   2 +-
 .../v1/tokens.py                              |   2 +-
 .../v1/users.py                               |   2 +-
 requirements.txt                              |  25 +-
 setup.cfg                                     |  67 +-
 stacktaskclient/common/utils.py               | 345 ----------
 stacktaskclient/openstack/common/_i18n.py     |  45 --
 .../openstack/common/apiclient/__init__.py    |   0
 .../openstack/common/apiclient/auth.py        | 234 -------
 .../openstack/common/apiclient/client.py      | 388 ------------
 .../openstack/common/apiclient/exceptions.py  | 479 --------------
 .../openstack/common/apiclient/fake_client.py | 190 ------
 .../openstack/common/apiclient/utils.py       | 100 ---
 stacktaskclient/openstack/common/cliutils.py  | 271 --------
 stacktaskclient/osc/__init__.py               |   0
 stacktaskclient/osc/v1/__init__.py            |   0
 stacktaskclient/shell.py                      | 593 ------------------
 stacktaskclient/v1/build_info.py              |  34 -
 stacktaskclient/v1/shell.py                   | 525 ----------------
 47 files changed, 198 insertions(+), 3388 deletions(-)
 delete mode 100644 .testr.conf
 delete mode 100644 AUTHORS~
 delete mode 100644 README.md
 rename {stacktaskclient => adjutantclient}/__init__.py (87%)
 create mode 100644 adjutantclient/_i18n.py
 rename {stacktaskclient => adjutantclient}/client.py (84%)
 rename {stacktaskclient => adjutantclient}/common/__init__.py (100%)
 rename {stacktaskclient/openstack/common/apiclient => adjutantclient/common}/base.py (94%)
 rename {stacktaskclient => adjutantclient}/common/http.py (83%)
 rename {stacktaskclient => adjutantclient}/exc.py (96%)
 rename {stacktaskclient/openstack => adjutantclient/osc}/__init__.py (100%)
 rename {stacktaskclient => adjutantclient}/osc/plugin.py (89%)
 rename {stacktaskclient/openstack/common => adjutantclient/osc/v1}/__init__.py (100%)
 rename {stacktaskclient => adjutantclient}/osc/v1/notifications.py (98%)
 rename {stacktaskclient => adjutantclient}/osc/v1/signup.py (95%)
 rename {stacktaskclient => adjutantclient}/osc/v1/status.py (96%)
 rename {stacktaskclient => adjutantclient}/osc/v1/tasks.py (99%)
 rename {stacktaskclient => adjutantclient}/osc/v1/tokens.py (95%)
 rename {stacktaskclient => adjutantclient}/osc/v1/users.py (98%)
 rename {stacktaskclient => adjutantclient}/v1/__init__.py (92%)
 rename {stacktaskclient => adjutantclient}/v1/client.py (78%)
 rename {stacktaskclient => adjutantclient}/v1/notifications.py (96%)
 rename {stacktaskclient => adjutantclient}/v1/roles.py (96%)
 rename {stacktaskclient => adjutantclient}/v1/signup.py (94%)
 rename {stacktaskclient => adjutantclient}/v1/status.py (92%)
 rename {stacktaskclient => adjutantclient}/v1/tasks.py (96%)
 rename {stacktaskclient => adjutantclient}/v1/tokens.py (96%)
 rename {stacktaskclient => adjutantclient}/v1/users.py (98%)
 delete mode 100644 stacktaskclient/common/utils.py
 delete mode 100644 stacktaskclient/openstack/common/_i18n.py
 delete mode 100644 stacktaskclient/openstack/common/apiclient/__init__.py
 delete mode 100644 stacktaskclient/openstack/common/apiclient/auth.py
 delete mode 100644 stacktaskclient/openstack/common/apiclient/client.py
 delete mode 100644 stacktaskclient/openstack/common/apiclient/exceptions.py
 delete mode 100644 stacktaskclient/openstack/common/apiclient/fake_client.py
 delete mode 100644 stacktaskclient/openstack/common/apiclient/utils.py
 delete mode 100644 stacktaskclient/openstack/common/cliutils.py
 delete mode 100644 stacktaskclient/osc/__init__.py
 delete mode 100644 stacktaskclient/osc/v1/__init__.py
 delete mode 100644 stacktaskclient/shell.py
 delete mode 100644 stacktaskclient/v1/build_info.py
 delete mode 100644 stacktaskclient/v1/shell.py

diff --git a/.gitignore b/.gitignore
index 95c071f..589ed55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,9 +13,10 @@ doc/source/api
 doc/build
 *.egg
 .eggs/*
-stacktaskclient/versioninfo
+adjutantclient/versioninfo
 *.egg-info
 *.log
 .testrepository
 .pypirc
 env/
+*~
diff --git a/.testr.conf b/.testr.conf
deleted file mode 100644
index c8af2c3..0000000
--- a/.testr.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-[DEFAULT]
-test_command=${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./stacktaskclient/tests/unit} $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff --git a/AUTHORS~ b/AUTHORS~
deleted file mode 100644
index c2a7e17..0000000
--- a/AUTHORS~
+++ /dev/null
@@ -1,2 +0,0 @@
-Dale Smith <dale@catalyst-eu.net>
-adriant <adriant@catalyst.net.nz>
diff --git a/MANIFEST.in b/MANIFEST.in
index 16438ae..1eec6d9 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
 include AUTHORS
 include LICENSE
-include README.md
+include README.rst
 include ChangeLog
diff --git a/README.md b/README.md
deleted file mode 100644
index e69de29..0000000
diff --git a/README.rst b/README.rst
index b674aca..755eb9f 100644
--- a/README.rst
+++ b/README.rst
@@ -1,17 +1,17 @@
-StackTaskClient is a command-line and python client for StackTask.
+AdjutantClient is a command-line and python client for Adjutant.
 
 Getting Started
 ===============
 
-StackTask Client can be installed from PyPI using pip:
+Adjutant Client can be installed from PyPI using pip:
 
 ::
 
-    pip install python-openstackclient python-stacktaskclient
+    pip install python-openstackclient python-adjutantclient
 
 
 The command line client is installed as a plugin for the OpenStack client, and
-an older deprecated version is available under the entry point 'stacktask'.
+an older deprecated version is available under the entry point 'adjutant'.
 
 Python API
 ==========
@@ -19,13 +19,13 @@ Python API
 In order to use the python api directly, you must first obtain an auth
 token and identify which endpoint you wish to speak to::
 
-  >>> stacktask_url = 'http://stacktask.example.org:8004/v1/'
+  >>> adjutant_url = 'http://adjutant.example.org:8004/v1/'
   >>> auth_token = '3bcc3d3a03f44e3d8377f9247b0ad155'
 
 Once you have done so, you can use the API like so::
 
-  >>> from stacktaskclient.client import Client
-  >>> stacktask = Client('1', endpoint=stacktask_url, token=auth_token)
+  >>> from adjutantclient.client import Client
+  >>> adjutant = Client('1', endpoint=adjutant_url, token=auth_token)
 
 An auth token isn't needed for accessing signup, user.password_forgot(),
 token.submit() or token.get().
diff --git a/stacktaskclient/__init__.py b/adjutantclient/__init__.py
similarity index 87%
rename from stacktaskclient/__init__.py
rename to adjutantclient/__init__.py
index b126fc8..f641663 100644
--- a/stacktaskclient/__init__.py
+++ b/adjutantclient/__init__.py
@@ -13,4 +13,4 @@
 import pbr.version
 
 
-__version__ = pbr.version.VersionInfo('python-stacktaskclient').version_string()
+__version__ = pbr.version.VersionInfo('python-adjutantclient').version_string()
diff --git a/adjutantclient/_i18n.py b/adjutantclient/_i18n.py
new file mode 100644
index 0000000..d05e2a4
--- /dev/null
+++ b/adjutantclient/_i18n.py
@@ -0,0 +1,37 @@
+#    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.
+
+"""oslo.i18n integration module.
+
+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='adjutantclient')
+
+# The primary translation function using the well-known name "_"
+_ = _translators.primary
+
+
+def get_available_languages():
+    return oslo_i18n.get_available_languages('adjutantclient')
+
+
+def enable_lazy():
+    return oslo_i18n.enable_lazy()
diff --git a/stacktaskclient/client.py b/adjutantclient/client.py
similarity index 84%
rename from stacktaskclient/client.py
rename to adjutantclient/client.py
index 417813b..2b1cf85 100644
--- a/stacktaskclient/client.py
+++ b/adjutantclient/client.py
@@ -10,10 +10,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from stacktaskclient.common import utils
+from oslo_utils import importutils
 
 
 def Client(version, *args, **kwargs):
-    module = utils.import_versioned_module(version, 'client')
+    module = importutils.import_versioned_module(
+        'adjutantclient', version, 'client')
     client_class = getattr(module, 'Client')
     return client_class(*args, **kwargs)
diff --git a/stacktaskclient/common/__init__.py b/adjutantclient/common/__init__.py
similarity index 100%
rename from stacktaskclient/common/__init__.py
rename to adjutantclient/common/__init__.py
diff --git a/stacktaskclient/openstack/common/apiclient/base.py b/adjutantclient/common/base.py
similarity index 94%
rename from stacktaskclient/openstack/common/apiclient/base.py
rename to adjutantclient/common/base.py
index 84a38e3..b91ecaa 100644
--- a/stacktaskclient/openstack/common/apiclient/base.py
+++ b/adjutantclient/common/base.py
@@ -19,33 +19,16 @@
 """
 Base utilities to build API operation managers and objects on top of.
 """
-
-########################################################################
-#
-# THIS MODULE IS DEPRECATED
-#
-# Please refer to
-# https://etherpad.openstack.org/p/kilo-oslo-library-proposals for
-# the discussion leading to this deprecation.
-#
-# We recommend checking out the python-openstacksdk project
-# (https://launchpad.net/python-openstacksdk) instead.
-#
-########################################################################
-
-
-# E1102: %s is not callable
-# pylint: disable=E1102
-
 import abc
 import copy
 
+from oslo_utils import reflection
 from oslo_utils import strutils
 import six
 from six.moves.urllib import parse
 
-from stacktaskclient.openstack.common._i18n import _
-from stacktaskclient.openstack.common.apiclient import exceptions
+from adjutantclient._i18n import _
+from adjutantclient import exc as exceptions
 
 
 def getid(obj):
@@ -216,14 +199,12 @@ class BaseManager(HookableMixin):
         else:
             return self.resource_class(self, body)
 
-    def _delete(self, url, json=None, response_key=None):
+    def _delete(self, url):
         """Delete an object.
 
         :param url: a partial URL, e.g., '/servers/my-server'
-        :param json: data that will be encoded as JSON and passed in DELETE
-            request
         """
-        return self.client.delete(url, json=json)
+        return self.client.delete(url)
 
 
 @six.add_metaclass(abc.ABCMeta)
@@ -277,14 +258,12 @@ class CrudManager(BaseManager):
     """Base manager class for manipulating entities.
 
     Children of this class are expected to define a `collection_key` and `key`.
-
     - `collection_key`: Usually a plural noun by convention (e.g. `entities`);
       used to refer collections in both URL's (e.g.  `/v3/entities`) and JSON
       objects containing a list of member resources (e.g. `{'entities': [{},
       {}, {}]}`).
     - `key`: Usually a singular noun by convention (e.g. `entity`); used to
       refer to an individual member of the collection.
-
     """
     collection_key = None
     key = None
@@ -294,16 +273,11 @@ class CrudManager(BaseManager):
 
         Given an example collection where `collection_key = 'entities'` and
         `key = 'entity'`, the following URL's could be generated.
-
         By default, the URL will represent a collection of entities, e.g.::
-
             /entities
-
         If kwargs contains an `entity_id`, then the URL will represent a
         specific member, e.g.::
-
             /entities/{entity_id}
-
         :param base_url: if provided, the generated URL will be appended to it
         """
         url = base_url if base_url is not None else ''
@@ -444,7 +418,6 @@ class Resource(object):
 
     This is pretty much just a bag for attributes.
     """
-
     HUMAN_ID = False
     NAME_ATTR = 'name'
 
@@ -465,12 +438,12 @@ class Resource(object):
                           for k in self.__dict__.keys()
                           if k[0] != '_' and k != 'manager')
         info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
-        return "<%s %s>" % (self.__class__.__name__, info)
+        class_name = reflection.get_class_name(self, fully_qualified=False)
+        return "<%s %s>" % (class_name, info)
 
     @property
     def human_id(self):
-        """Human-readable ID which can be used for bash completion.
-        """
+        """Human-readable ID which can be used for bash completion. """
         if self.HUMAN_ID:
             name = getattr(self, self.NAME_ATTR, None)
             if name is not None:
@@ -520,10 +493,18 @@ class Resource(object):
         # two resources of different types are not equal
         if not isinstance(other, self.__class__):
             return False
-        if hasattr(self, 'id') and hasattr(other, 'id'):
-            return self.id == other.id
         return self._info == other._info
 
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def is_same_obj(self, other):
+        """Identify the two objects are same one with same id."""
+        if isinstance(other, self.__class__):
+            if hasattr(self, 'id') and hasattr(other, 'id'):
+                return self.id == other.id
+        return False
+
     def is_loaded(self):
         return self._loaded
 
diff --git a/stacktaskclient/common/http.py b/adjutantclient/common/http.py
similarity index 83%
rename from stacktaskclient/common/http.py
rename to adjutantclient/common/http.py
index 7f74e5b..488d7d0 100644
--- a/stacktaskclient/common/http.py
+++ b/adjutantclient/common/http.py
@@ -19,6 +19,7 @@ import logging
 import os
 import socket
 
+from keystoneauth1 import adapter
 from oslo_serialization import jsonutils
 from oslo_utils import encodeutils
 from oslo_utils import importutils
@@ -26,19 +27,28 @@ import requests
 import six
 from six.moves.urllib import parse
 
-from stacktaskclient.common import utils
-from stacktaskclient import exc
-from stacktaskclient.openstack.common._i18n import _
-from stacktaskclient.openstack.common._i18n import _LW
-from keystoneauth1 import adapter
+from adjutantclient._i18n import _
+from adjutantclient import exc
 
 LOG = logging.getLogger(__name__)
-USER_AGENT = 'python-stacktaskclient'
+USER_AGENT = 'python-adjutantclient'
 CHUNKSIZE = 1024 * 64  # 64kB
 SENSITIVE_HEADERS = ('X-Auth-Token',)
 osprofiler_web = importutils.try_import("osprofiler.web")
 
 
+def get_response_body(resp):
+    body = resp.content
+    if 'application/json' in resp.headers.get('content-type', ''):
+        try:
+            body = resp.json()
+        except ValueError:
+            LOG.error('Could not decode response body as JSON')
+    else:
+        body = None
+    return body
+
+
 def get_system_ca_file():
     """Return path to system default CA file."""
     # Standard CA file locations for Debian/Ubuntu, RedHat/Fedora,
@@ -54,7 +64,7 @@ def get_system_ca_file():
         if os.path.exists(ca):
             LOG.debug("Using ca file %s", ca)
             return ca
-    LOG.warn(_LW("System ca file could not be found."))
+    LOG.warning("System ca file could not be found.")
 
 
 class HTTPClient(object):
@@ -158,7 +168,7 @@ class HTTPClient(object):
             kwargs['headers'].setdefault('X-Auth-Url', self.auth_url)
         if self.region_name:
             kwargs['headers'].setdefault('X-Region-Name', self.region_name)
-        if self.include_pass and not 'X-Auth-Key' in kwargs['headers']:
+        if self.include_pass and 'X-Auth-Key' not in kwargs['headers']:
             kwargs['headers'].update(self.credentials_headers())
         if osprofiler_web:
             kwargs['headers'].update(osprofiler_web.get_trace_id_headers())
@@ -188,10 +198,14 @@ class HTTPClient(object):
         # See issue: https://github.com/kennethreitz/requests/issues/1704
         allow_redirects = False
 
+        # Use fully qualified URL from response header for redirects
+        if not parse.urlparse(url).netloc:
+            url = self.endpoint_url + url
+
         try:
             resp = requests.request(
                 method,
-                self.endpoint_url + url,
+                url,
                 allow_redirects=allow_redirects,
                 **kwargs)
         except socket.gaierror as e:
@@ -206,17 +220,11 @@ class HTTPClient(object):
 
         self.log_http_response(resp)
 
-        if not 'X-Auth-Key' in kwargs['headers'] and \
-                (resp.status_code == 401 or
-                 (resp.status_code == 500 and "(HTTP 401)" in resp.content)):
-            raise exc.HTTPUnauthorized(_("Authentication failed. Please try"
-                                         " again with option %(option)s or "
-                                         "export %(var)s\n%(content)s") %
-                                       {
-                                           'option': '--include-password',
-                                           'var': 'HEAT_INCLUDE_PASSWORD=1',
-                                           'content': resp.content
-                                       })
+        if not ('X-Auth-Key' in kwargs['headers']) and (
+                resp.status_code == 401 or
+                (resp.status_code == 500 and "(HTTP 401)" in resp.content)):
+            raise exc.HTTPUnauthorized(_("Authentication failed: %s")
+                                       % resp.content)
         elif 400 <= resp.status_code < 600:
             raise exc.from_response(resp)
         elif resp.status_code in (301, 302, 305):
@@ -224,31 +232,17 @@ class HTTPClient(object):
             # unless caller specified redirect=False
             if redirect:
                 location = resp.headers.get('location')
-                path = self.strip_endpoint(location)
-                resp = self._http_request(path, method, **kwargs)
+                if not location:
+                    message = _("Location not returned with redirect")
+                    raise exc.InvalidEndpoint(message=message)
+                resp = self._http_request(location, method, **kwargs)
         elif resp.status_code == 300:
             raise exc.from_response(resp)
 
         return resp
 
-    def strip_endpoint(self, location):
-        if location is None:
-            message = _("Location not returned with 302")
-            raise exc.InvalidEndpoint(message=message)
-        elif location.lower().startswith(self.endpoint.lower()):
-            return location[len(self.endpoint):]
-        else:
-            message = _("Prohibited endpoint redirect %s") % location
-            raise exc.InvalidEndpoint(message=message)
-
     def credentials_headers(self):
         creds = {}
-        # NOTE(dhu): (shardy) When deferred_auth_method=password, Heat
-        # encrypts and stores username/password.  For Keystone v3, the
-        # intent is to use trusts since SHARDY is working towards
-        # deferred_auth_method=trusts as the default.
-        # TODO(dhu): Make Keystone v3 work in Heat standalone mode.  Maye
-        # require X-Auth-User-Domain.
         if self.username:
             creds['X-Auth-User'] = self.username
         if self.password:
@@ -264,7 +258,7 @@ class HTTPClient(object):
             kwargs['data'] = jsonutils.dumps(kwargs['data'])
 
         resp = self._http_request(url, method, **kwargs)
-        body = utils.get_response_body(resp)
+        body = get_response_body(resp)
         return resp, body
 
     def raw_request(self, method, url, **kwargs):
@@ -303,10 +297,8 @@ class SessionClient(adapter.LegacyJsonAdapter):
         redirect = kwargs.get('redirect')
         kwargs.setdefault('user_agent', USER_AGENT)
 
-        try:
-            kwargs.setdefault('json', kwargs.pop('data'))
-        except KeyError:
-            pass
+        if 'data' in kwargs:
+            kwargs['data'] = jsonutils.dumps(kwargs['data'])
 
         resp, body = super(SessionClient, self).request(
             url, method,
@@ -346,7 +338,15 @@ def _construct_http_client(endpoint=None, username=None, password=None,
     auth = kwargs.pop('auth', None)
 
     if session:
-        kwargs['endpoint_override'] = endpoint
+        if 'endpoint_override' not in kwargs and endpoint:
+            kwargs['endpoint_override'] = endpoint
+
+        if 'service_type' not in kwargs:
+            kwargs['service_type'] = 'registration'
+
+        if 'interface' not in kwargs and endpoint_type:
+            kwargs['interface'] = endpoint_type
+
         return SessionClient(session, auth=auth, **kwargs)
     else:
         return HTTPClient(endpoint=endpoint, username=username,
diff --git a/stacktaskclient/exc.py b/adjutantclient/exc.py
similarity index 96%
rename from stacktaskclient/exc.py
rename to adjutantclient/exc.py
index 9717019..d46b9fc 100644
--- a/stacktaskclient/exc.py
+++ b/adjutantclient/exc.py
@@ -14,7 +14,7 @@ import sys
 
 from oslo_serialization import jsonutils
 
-from stacktaskclient.openstack.common._i18n import _
+from adjutantclient._i18n import _
 
 verbose = 0
 
@@ -48,7 +48,7 @@ class HTTPException(BaseException):
         super(HTTPException, self).__init__(message)
         try:
             self.error = jsonutils.loads(message)
-            # Stacktask client: mangle the 'errors' return list into
+            # Adjutant client: mangle the 'errors' return list into
             # standard 'error' format
             if 'errors' in self.error:
                 self.error['error'] = {
@@ -81,7 +81,7 @@ class HTTPMultipleChoices(HTTPException):
     code = 300
 
     def __str__(self):
-        self.details = _("Requested version of Stacktask API is not"
+        self.details = _("Requested version of Adjutant API is not"
                          "available.")
         return (_("%(name)s (HTTP %(code)s) %(details)s") %
                 {
diff --git a/stacktaskclient/openstack/__init__.py b/adjutantclient/osc/__init__.py
similarity index 100%
rename from stacktaskclient/openstack/__init__.py
rename to adjutantclient/osc/__init__.py
diff --git a/stacktaskclient/osc/plugin.py b/adjutantclient/osc/plugin.py
similarity index 89%
rename from stacktaskclient/osc/plugin.py
rename to adjutantclient/osc/plugin.py
index ded490a..00f16ad 100644
--- a/stacktaskclient/osc/plugin.py
+++ b/adjutantclient/osc/plugin.py
@@ -23,12 +23,12 @@ DEFAULT_API_VERSION = '1'
 API_VERSION_OPTION = 'os_registration_version'
 API_NAME = "registration"
 API_VERSIONS = {
-    "1": "stacktaskclient.v1.client.Client",
+    "1": "adjutantclient.v1.client.Client",
 }
 
 
 def make_client(instance):
-    """Returns an stacktask service client."""
+    """Returns an adjutant service client."""
     version = instance._api_version[API_NAME]
     try:
         version = int(version)
@@ -37,12 +37,12 @@ def make_client(instance):
 
     version = 1
 
-    stacktask_client = utils.get_client_class(
+    adjutant_client = utils.get_client_class(
         API_NAME,
         version,
         API_VERSIONS)
 
-    LOG.debug('Instantiating stacktask client: %s', stacktask_client)
+    LOG.debug('Instantiating adjutant client: %s', adjutant_client)
 
     kwargs = {'region_name': instance.region_name}
 
@@ -61,7 +61,7 @@ def make_client(instance):
                        'username': instance.auth_ref.username,
                        'token': instance.auth_ref.auth_token})
 
-    client = stacktask_client(**kwargs)
+    client = adjutant_client(**kwargs)
 
     return client
 
diff --git a/stacktaskclient/openstack/common/__init__.py b/adjutantclient/osc/v1/__init__.py
similarity index 100%
rename from stacktaskclient/openstack/common/__init__.py
rename to adjutantclient/osc/v1/__init__.py
diff --git a/stacktaskclient/osc/v1/notifications.py b/adjutantclient/osc/v1/notifications.py
similarity index 98%
rename from stacktaskclient/osc/v1/notifications.py
rename to adjutantclient/osc/v1/notifications.py
index df2c9da..cc74703 100644
--- a/stacktaskclient/osc/v1/notifications.py
+++ b/adjutantclient/osc/v1/notifications.py
@@ -32,7 +32,7 @@ def _show_notification(notification_id, client, formatter):
 
 
 class NotificationList(command.Lister):
-    """Lists stacktask notifications. """
+    """Lists adjutant notifications. """
 
     def get_parser(self, prog_name):
         parser = super(NotificationList, self).get_parser(prog_name)
diff --git a/stacktaskclient/osc/v1/signup.py b/adjutantclient/osc/v1/signup.py
similarity index 95%
rename from stacktaskclient/osc/v1/signup.py
rename to adjutantclient/osc/v1/signup.py
index 1372736..707d72f 100644
--- a/stacktaskclient/osc/v1/signup.py
+++ b/adjutantclient/osc/v1/signup.py
@@ -18,7 +18,7 @@ import json
 from osc_lib.command import command
 from osc_lib.i18n import _
 
-from stacktaskclient import client as stacktask_client
+from adjutantclient import client as adjutant_client
 
 
 LOG = logging.getLogger(__name__)
@@ -60,7 +60,7 @@ class Signup(command.Command):
             self.app.client_manager.setup_auth()
             client = self.app.client_manager.registration
         else:
-            client = stacktask_client.Client(1, parsed_args.bypass_url)
+            client = adjutant_client.Client(1, parsed_args.bypass_url)
 
         signup = client.signup.post(parsed_args.user, parsed_args.email,
                                     parsed_args.project_name,
diff --git a/stacktaskclient/osc/v1/status.py b/adjutantclient/osc/v1/status.py
similarity index 96%
rename from stacktaskclient/osc/v1/status.py
rename to adjutantclient/osc/v1/status.py
index 646ef8b..41a92d3 100644
--- a/stacktaskclient/osc/v1/status.py
+++ b/adjutantclient/osc/v1/status.py
@@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__)
 
 
 class Status(command.Command):
-    """Lists stacktask tasks. """
+    """Lists adjutant tasks. """
 
     def take_action(self, parsed_args):
         client = self.app.client_manager.registration
diff --git a/stacktaskclient/osc/v1/tasks.py b/adjutantclient/osc/v1/tasks.py
similarity index 99%
rename from stacktaskclient/osc/v1/tasks.py
rename to adjutantclient/osc/v1/tasks.py
index 74b1dbc..e23e550 100644
--- a/stacktaskclient/osc/v1/tasks.py
+++ b/adjutantclient/osc/v1/tasks.py
@@ -37,7 +37,7 @@ def _show_task(task_id, client, formatter):
 
 
 class TaskList(command.Lister):
-    """Lists stacktask tasks. """
+    """Lists adjutant tasks. """
 
     def get_parser(self, prog_name):
         parser = super(TaskList, self).get_parser(prog_name)
diff --git a/stacktaskclient/osc/v1/tokens.py b/adjutantclient/osc/v1/tokens.py
similarity index 95%
rename from stacktaskclient/osc/v1/tokens.py
rename to adjutantclient/osc/v1/tokens.py
index ebe5e53..38d6d83 100644
--- a/stacktaskclient/osc/v1/tokens.py
+++ b/adjutantclient/osc/v1/tokens.py
@@ -19,7 +19,7 @@ import six
 from osc_lib.command import command
 from osc_lib.i18n import _
 
-from stacktaskclient import client as stacktask_client
+from adjutantclient import client as adjutant_client
 
 LOG = logging.getLogger(__name__)
 
@@ -35,7 +35,7 @@ def _list_tokens(client, filters={}):
 
 
 class TokenList(command.Lister):
-    """Lists stacktask tokens. """
+    """Lists adjutant tokens. """
 
     def get_parser(self, prog_name):
         parser = super(TokenList, self).get_parser(prog_name)
@@ -73,7 +73,7 @@ class TokenShow(command.ShowOne):
             self.app.client_manager.setup_auth()
             client = self.app.client_manager.registration
         else:
-            client = stacktask_client.Client("1", parsed_args.bypass_url)
+            client = adjutant_client.Client("1", parsed_args.bypass_url)
         token = client.tokens.get(parsed_args.token)
         return zip(*six.iteritems(token.to_dict()))
 
diff --git a/stacktaskclient/osc/v1/users.py b/adjutantclient/osc/v1/users.py
similarity index 98%
rename from stacktaskclient/osc/v1/users.py
rename to adjutantclient/osc/v1/users.py
index 24b5bce..15e8cf7 100644
--- a/stacktaskclient/osc/v1/users.py
+++ b/adjutantclient/osc/v1/users.py
@@ -19,7 +19,7 @@ from osc_lib import utils
 from osc_lib.command import command
 from osc_lib.i18n import _
 
-from stacktaskclient import client as stacktask_client
+from adjutantclient import client as adjutant_client
 
 LOG = logging.getLogger(__name__)
 
@@ -238,7 +238,7 @@ class PasswordForgot(command.Command):
             self.app.client_manager.setup_auth()
             client = self.app.client_manager.registration
         else:
-            client = stacktask_client.Client(1, parsed_args.bypass_url)
+            client = adjutant_client.Client(1, parsed_args.bypass_url)
 
         client.users.password_forgot(parsed_args.email, parsed_args.username)
         print("Task has been sucessfully submitted.")
diff --git a/stacktaskclient/v1/__init__.py b/adjutantclient/v1/__init__.py
similarity index 92%
rename from stacktaskclient/v1/__init__.py
rename to adjutantclient/v1/__init__.py
index 507adf6..817886e 100644
--- a/stacktaskclient/v1/__init__.py
+++ b/adjutantclient/v1/__init__.py
@@ -15,4 +15,4 @@
 
 __all__ = ['Client']
 
-from stacktaskclient.v1.client import Client  # noqa
+from adjutantclient.v1.client import Client  # noqa
diff --git a/stacktaskclient/v1/client.py b/adjutantclient/v1/client.py
similarity index 78%
rename from stacktaskclient/v1/client.py
rename to adjutantclient/v1/client.py
index c409c64..c0d848d 100644
--- a/stacktaskclient/v1/client.py
+++ b/adjutantclient/v1/client.py
@@ -12,20 +12,20 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from stacktaskclient.common import http
-from stacktaskclient.v1 import notifications
-from stacktaskclient.v1 import roles
-from stacktaskclient.v1 import signup
-from stacktaskclient.v1 import status
-from stacktaskclient.v1 import tasks
-from stacktaskclient.v1 import tokens
-from stacktaskclient.v1 import users
+from adjutantclient.common import http
+from adjutantclient.v1 import notifications
+from adjutantclient.v1 import roles
+from adjutantclient.v1 import signup
+from adjutantclient.v1 import status
+from adjutantclient.v1 import tasks
+from adjutantclient.v1 import tokens
+from adjutantclient.v1 import users
 
 
 class Client(object):
-    """Client for the Stacktask v1 API.
+    """Client for the Adjutant v1 API.
 
-    :param string endpoint: A user-supplied endpoint URL for the stacktask
+    :param string endpoint: A user-supplied endpoint URL for the adjutant
                             service.
     :param string token: Token for authentication.
     :param integer timeout: Allows customization of the timeout for client
@@ -33,7 +33,7 @@ class Client(object):
     """
 
     def __init__(self, *args, **kwargs):
-        """Initialize a new client for the Stacktask v1 API."""
+        """Initialize a new client for the Adjutant v1 API."""
         self.http_client = http._construct_http_client(*args, **kwargs)
 
         self.users = users.UserManager(self.http_client)
diff --git a/stacktaskclient/v1/notifications.py b/adjutantclient/v1/notifications.py
similarity index 96%
rename from stacktaskclient/v1/notifications.py
rename to adjutantclient/v1/notifications.py
index b055f93..3419cd6 100644
--- a/stacktaskclient/v1/notifications.py
+++ b/adjutantclient/v1/notifications.py
@@ -14,7 +14,7 @@
 
 from six.moves.urllib import parse
 
-from stacktaskclient.openstack.common.apiclient import base
+from adjutantclient.common import base
 
 
 class Notification(base.Resource):
diff --git a/stacktaskclient/v1/roles.py b/adjutantclient/v1/roles.py
similarity index 96%
rename from stacktaskclient/v1/roles.py
rename to adjutantclient/v1/roles.py
index 9eeba7b..0dacf39 100644
--- a/stacktaskclient/v1/roles.py
+++ b/adjutantclient/v1/roles.py
@@ -14,8 +14,8 @@
 
 from six.moves.urllib import parse
 
-from stacktaskclient.openstack.common.apiclient import base
-from stacktaskclient import exc
+from adjutantclient.common import base
+from adjutantclient import exc
 
 
 class Role(base.Resource):
@@ -50,7 +50,7 @@ class ManagedRoleManager(base.ManagerWithFind):
         for role in roles:
             if role.id == role_id:
                 return role
-        raise exc.NotFound()
+        raise exc.HTTPNotFound()
 
 
 class UserRoleManager(base.BaseManager):
diff --git a/stacktaskclient/v1/signup.py b/adjutantclient/v1/signup.py
similarity index 94%
rename from stacktaskclient/v1/signup.py
rename to adjutantclient/v1/signup.py
index e0eddcc..510ae45 100644
--- a/stacktaskclient/v1/signup.py
+++ b/adjutantclient/v1/signup.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from stacktaskclient.openstack.common.apiclient import base
+from adjutantclient.common import base
 
 
 class SignupManager(base.BaseManager):
diff --git a/stacktaskclient/v1/status.py b/adjutantclient/v1/status.py
similarity index 92%
rename from stacktaskclient/v1/status.py
rename to adjutantclient/v1/status.py
index 3f11120..c41c757 100644
--- a/stacktaskclient/v1/status.py
+++ b/adjutantclient/v1/status.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from stacktaskclient.openstack.common.apiclient import base
+from adjutantclient.common import base
 
 
 class StatusManager(base.BaseManager):
diff --git a/stacktaskclient/v1/tasks.py b/adjutantclient/v1/tasks.py
similarity index 96%
rename from stacktaskclient/v1/tasks.py
rename to adjutantclient/v1/tasks.py
index 9990616..351ae64 100644
--- a/stacktaskclient/v1/tasks.py
+++ b/adjutantclient/v1/tasks.py
@@ -14,7 +14,7 @@
 
 from six.moves.urllib import parse
 
-from stacktaskclient.openstack.common.apiclient import base
+from adjutantclient.common import base
 
 
 class Task(base.Resource):
diff --git a/stacktaskclient/v1/tokens.py b/adjutantclient/v1/tokens.py
similarity index 96%
rename from stacktaskclient/v1/tokens.py
rename to adjutantclient/v1/tokens.py
index 7c1d9ef..d79270b 100644
--- a/stacktaskclient/v1/tokens.py
+++ b/adjutantclient/v1/tokens.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from stacktaskclient.openstack.common.apiclient import base
+from adjutantclient.common import base
 
 from six.moves.urllib import parse
 
diff --git a/stacktaskclient/v1/users.py b/adjutantclient/v1/users.py
similarity index 98%
rename from stacktaskclient/v1/users.py
rename to adjutantclient/v1/users.py
index c58f4cb..f8dfc0f 100644
--- a/stacktaskclient/v1/users.py
+++ b/adjutantclient/v1/users.py
@@ -15,7 +15,7 @@
 import six
 from six.moves.urllib import parse
 
-from stacktaskclient.openstack.common.apiclient import base
+from adjutantclient.common import base
 
 
 class User(base.Resource):
diff --git a/requirements.txt b/requirements.txt
index 484f39f..e85e7cf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,14 +2,17 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 
-Babel>=1.3
-pbr>=3.0.0
-iso8601>=0.1.9
-PrettyTable<0.8,>=0.7
-oslo.i18n>=2.1.0
-oslo.serialization>=1.10.0
-oslo.utils>=3.16.0
-keystoneauth1>=2.11.0
-PyYAML>=3.10.0
-requests>=2.10.0
-six>=1.9.0
+Babel!=2.4.0,>=2.3.4 # BSD
+pbr>=3.0.0 # Apache-2.0
+cliff>=2.6.0 # Apache-2.0
+iso8601>=0.1.11 # MIT
+osc-lib>=1.5.1 # Apache-2.0
+PrettyTable<0.8,>=0.7.1 # BSD
+python-openstackclient>=3.11.0
+oslo.i18n>=2.1.0 # Apache-2.0
+oslo.serialization>=1.10.0 # Apache-2.0
+oslo.utils>=3.20.0 # Apache-2.0
+keystoneauth1>=2.20.0 # Apache-2.0
+PyYAML>=3.10.0 # MIT
+requests!=2.12.2,!=2.13.0,>=2.10.0 # Apache-2.0
+six>=1.9.0 # MIT
diff --git a/setup.cfg b/setup.cfg
index 3a23920..b61735a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,11 +1,11 @@
 [metadata]
-name = python-stacktaskclient
-summary = StackTask API Client Library
+name = python-adjutantclient
+summary = Adjutant API Client Library
 description-file =
     README.rst
-author = Dale Smith
-author-email = dale@catalyst-eu.net
-home-page = https://github.com/catalyst/stacktask-client
+author = Adrian Turjak
+author-email = adriant@catalyst.net.nz
+home-page = https://github.com/catalyst/python-adjutantclient
 classifier =
     Environment :: OpenStack
     Intended Audience :: Information Technology
@@ -19,41 +19,38 @@ classifier =
 
 [files]
 packages =
-    stacktaskclient
+    adjutantclient
 
 [entry_points]
-console_scripts =
-    stacktask = stacktaskclient.shell:main
-
 openstack.cli.extension =
-    registration = stacktaskclient.osc.plugin
+    registration = adjutantclient.osc.plugin
 
 openstack.registration.v1 =
-    admin_task_list = stacktaskclient.osc.v1.tasks:TaskList
-    admin_task_show = stacktaskclient.osc.v1.tasks:TaskShow
-    admin_task_approve = stacktaskclient.osc.v1.tasks:TaskApprove
-    admin_task_cancel = stacktaskclient.osc.v1.tasks:TaskCancel
-    admin_task_update = stacktaskclient.osc.v1.tasks:TaskUpdate
-    admin_task_token_reissue = stacktaskclient.osc.v1.tasks:TaskTokenReissue
-    admin_task_token_list = stacktaskclient.osc.v1.tokens:TokenList
-    admin_task_token_show = stacktaskclient.osc.v1.tokens:TokenShow
-    admin_task_token_submit = stacktaskclient.osc.v1.tokens:TokenSubmit
-    admin_task_tokens_clear = stacktaskclient.osc.v1.tokens:TokenClear
-    admin_task_notification_list = stacktaskclient.osc.v1.notifications:NotificationList
-    admin_task_notification_show = stacktaskclient.osc.v1.notifications:NotificationShow
-    admin_task_notification_acknowledge = stacktaskclient.osc.v1.notifications:NotificationAcknowledge
-    project_user_list = stacktaskclient.osc.v1.users:UserList
-    project_user_show = stacktaskclient.osc.v1.users:UserShow
-    project_user_invite = stacktaskclient.osc.v1.users:UserInvite
-    project_user_invite_cancel = stacktaskclient.osc.v1.users:UserInviteCancel
-    project_user_role_list = stacktaskclient.osc.v1.users:UserRoleList
-    project_user_role_add = stacktaskclient.osc.v1.users:UserRoleAdd
-    project_user_role_remove = stacktaskclient.osc.v1.users:UserRoleRemove
-    project_manageable_roles = stacktaskclient.osc.v1.users:ManageableRolesList
-    password_forgot = stacktaskclient.osc.v1.users:PasswordForgot
-    password_reset = stacktaskclient.osc.v1.users:PasswordReset
-    signup = stacktaskclient.osc.v1.signup:Signup
-    stacktask_status = stacktaskclient.osc.v1.status:Status
+    admin_task_list = adjutantclient.osc.v1.tasks:TaskList
+    admin_task_show = adjutantclient.osc.v1.tasks:TaskShow
+    admin_task_approve = adjutantclient.osc.v1.tasks:TaskApprove
+    admin_task_cancel = adjutantclient.osc.v1.tasks:TaskCancel
+    admin_task_update = adjutantclient.osc.v1.tasks:TaskUpdate
+    admin_task_token_reissue = adjutantclient.osc.v1.tasks:TaskTokenReissue
+    admin_task_token_list = adjutantclient.osc.v1.tokens:TokenList
+    admin_task_token_show = adjutantclient.osc.v1.tokens:TokenShow
+    admin_task_token_submit = adjutantclient.osc.v1.tokens:TokenSubmit
+    admin_task_tokens_clear = adjutantclient.osc.v1.tokens:TokenClear
+    admin_task_notification_list = adjutantclient.osc.v1.notifications:NotificationList
+    admin_task_notification_show = adjutantclient.osc.v1.notifications:NotificationShow
+    admin_task_notification_acknowledge = adjutantclient.osc.v1.notifications:NotificationAcknowledge
+    project_user_list = adjutantclient.osc.v1.users:UserList
+    project_user_show = adjutantclient.osc.v1.users:UserShow
+    project_user_invite = adjutantclient.osc.v1.users:UserInvite
+    project_user_invite_cancel = adjutantclient.osc.v1.users:UserInviteCancel
+    project_user_role_list = adjutantclient.osc.v1.users:UserRoleList
+    project_user_role_add = adjutantclient.osc.v1.users:UserRoleAdd
+    project_user_role_remove = adjutantclient.osc.v1.users:UserRoleRemove
+    project_manageable_roles = adjutantclient.osc.v1.users:ManageableRolesList
+    password_forgot = adjutantclient.osc.v1.users:PasswordForgot
+    password_reset = adjutantclient.osc.v1.users:PasswordReset
+    signup = adjutantclient.osc.v1.signup:Signup
+    adjutant_status = adjutantclient.osc.v1.status:Status
 
 [global]
 setup-hooks =
diff --git a/stacktaskclient/common/utils.py b/stacktaskclient/common/utils.py
deleted file mode 100644
index 810fa2f..0000000
--- a/stacktaskclient/common/utils.py
+++ /dev/null
@@ -1,345 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# 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.
-
-import base64
-from fcntl import ioctl
-import logging
-import os
-import textwrap
-import uuid
-import six
-import struct
-import sys
-import termios
-
-from oslo_serialization import jsonutils
-from oslo_utils import importutils
-import prettytable
-from six.moves.urllib import error
-from six.moves.urllib import parse
-from six.moves.urllib import request
-import yaml
-
-from stacktaskclient import exc
-from stacktaskclient.openstack.common._i18n import _
-from stacktaskclient.openstack.common._i18n import _LE
-from stacktaskclient.openstack.common import cliutils
-
-LOG = logging.getLogger(__name__)
-
-
-supported_formats = {
-    "json": lambda x: jsonutils.dumps(x, indent=2),
-    "yaml": yaml.safe_dump
-}
-
-# Using common methods from oslo cliutils
-arg = cliutils.arg
-env = cliutils.env
-print_list = cliutils.print_list
-
-
-def link_formatter(links):
-    def format_link(l):
-        if 'rel' in l:
-            return "%s (%s)" % (l.get('href', ''), l.get('rel', ''))
-        else:
-            return "%s" % (l.get('href', ''))
-    return '\n'.join(format_link(l) for l in links or [])
-
-
-def resource_nested_identifier(rsrc):
-    nested_link = [l for l in rsrc.links or []
-                   if l.get('rel') == 'nested']
-    if nested_link:
-        nested_href = nested_link[0].get('href')
-        nested_identifier = nested_href.split("/")[-2:]
-        return "/".join(nested_identifier)
-
-
-def json_formatter(js, wrap=None):
-    value = jsonutils.dumps(js, indent=2, ensure_ascii=False,
-                            separators=(', ', ': '))
-    # as json sort of does it's own line splitting, we have to check
-    # if each line is over the wrap limit, and split ourselves.
-    if wrap:
-        lines = []
-        for line in value.split('\n'):
-            if len(line) > wrap:
-                lines.append(line[0:wrap-1])
-                line = line[wrap:]
-                while line:
-                    lines.append(line[0:wrap-1])
-                    line = line[wrap:]
-            else:
-                lines.append(line)
-        value = ""
-        for line in lines:
-            value += "%s\n" % line
-    return value
-
-
-def text_wrap_formatter(d):
-    return '\n'.join(textwrap.wrap(d or '', 55))
-
-
-def newline_list_formatter(r):
-    return '\n'.join(r or [])
-
-
-def print_dict(d, formatters=None, wrap=None):
-    if not wrap:
-        # 2 columns padded by 1 on each side = 4
-        # 3 x '|' as border and separator = 3
-        # total non-content padding = 7
-        padding = 7
-        # Now we need to find what the longest key is
-        longest_key = 0
-        for key in d.keys():
-            if len(key) > longest_key:
-                longest_key = len(key)
-        # the wrap for the value column is based on
-        # what is left after we account for the padding
-        # and longest key
-        wrap = terminal_width() - padding - longest_key
-
-    formatters = formatters or {}
-    pt = prettytable.PrettyTable(['Property', 'Value'],
-                                 caching=False, print_empty=False)
-    pt.align = 'l'
-
-    for field in d.keys():
-        if field in formatters:
-            value = formatters[field](d[field], wrap)
-            pt.add_row([field, value])
-        else:
-            value = textwrap.fill(six.text_type(d[field]), wrap)
-            pt.add_row([field, value])
-    print(pt.get_string(sortby='Property'))
-
-
-def event_log_formatter(events):
-    """Return the events in log format."""
-    event_log = []
-    log_format = _("%(event_date)s  %(event_time)s  %(event_id)s "
-                   "[%(rsrc_name)s]: %(rsrc_status)s  %(rsrc_status_reason)s")
-    for event in events:
-        event_time = getattr(event, 'event_time', '')
-        time_date = event_time.split('T')
-        try:
-            event_time = time_date[0]
-            event_date = time_date[1][:-1]
-        except IndexError:
-            event_time = event_date = ''
-
-        log = log_format % {
-            'event_date': event_date, 'event_time': event_time,
-            'event_id': getattr(event, 'id', ''),
-            'rsrc_name': getattr(event, 'resource_name', ''),
-            'rsrc_status': getattr(event, 'resource_status', ''),
-            'rsrc_status_reason': getattr(event, 'resource_status_reason', '')
-        }
-        event_log.append(log)
-
-    return "\n".join(event_log)
-
-
-def find_resource(manager, name_or_id):
-    """Helper for the _find_* methods."""
-    # first try to get entity as integer id
-    try:
-        if isinstance(name_or_id, int) or name_or_id.isdigit():
-            return manager.get(int(name_or_id))
-    except exc.NotFound:
-        pass
-
-    # now try to get entity as uuid
-    try:
-        uuid.UUID(str(name_or_id))
-        return manager.get(name_or_id)
-    except (ValueError, exc.NotFound):
-        pass
-
-    # finally try to find entity by name
-    try:
-        return manager.find(name=name_or_id)
-    except exc.NotFound:
-        msg = _("No %(name)s with a name or ID of "
-                "'%(name_or_id)s' exists.") % \
-            {
-                'name': manager.resource_class.__name__.lower(),
-                'name_or_id': name_or_id
-            }
-        raise exc.CommandError(msg)
-
-
-def import_versioned_module(version, submodule=None):
-    module = 'stacktaskclient.v%s' % version
-    if submodule:
-        module = '.'.join((module, submodule))
-    return importutils.import_module(module)
-
-
-def format_parameters(params, parse_semicolon=True):
-    '''Reformat parameters into dict of format expected by the API.'''
-
-    if not params:
-        return {}
-
-    if parse_semicolon:
-        # expect multiple invocations of --parameters but fall back
-        # to ; delimited if only one --parameters is specified
-        if len(params) == 1:
-            params = params[0].split(';')
-
-    parameters = {}
-    for p in params:
-        try:
-            (n, v) = p.split(('='), 1)
-        except ValueError:
-            msg = _('Malformed parameter(%s). Use the key=value format.') % p
-            raise exc.CommandError(msg)
-
-        if n not in parameters:
-            parameters[n] = v
-        else:
-            if not isinstance(parameters[n], list):
-                parameters[n] = [parameters[n]]
-            parameters[n].append(v)
-
-    return parameters
-
-
-def format_all_parameters(params, param_files,
-                          template_file=None, template_url=None):
-    parameters = {}
-    parameters.update(format_parameters(params))
-    parameters.update(format_parameter_file(
-        param_files,
-        template_file,
-        template_url))
-    return parameters
-
-
-def format_parameter_file(param_files, template_file=None,
-                          template_url=None):
-    '''Reformat file parameters into dict of format expected by the API.'''
-    if not param_files:
-        return {}
-    params = format_parameters(param_files, False)
-
-    template_base_url = None
-    if template_file or template_url:
-        template_base_url = base_url_for_url(get_template_url(
-            template_file, template_url))
-
-    param_file = {}
-    for key, value in iter(params.items()):
-                param_file[key] = resolve_param_get_file(value,
-                                                         template_base_url)
-    return param_file
-
-
-def resolve_param_get_file(file, base_url):
-    if base_url and not base_url.endswith('/'):
-        base_url = base_url + '/'
-    str_url = parse.urljoin(base_url, file)
-    return read_url_content(str_url)
-
-
-def format_output(output, format='yaml'):
-    """Format the supplied dict as specified."""
-    output_format = format.lower()
-    try:
-        return supported_formats[output_format](output)
-    except KeyError:
-        raise exc.HTTPUnsupported(_("The format(%s) is unsupported.")
-                                  % output_format)
-
-
-def parse_query_url(url):
-    base_url, query_params = url.split('?')
-    return base_url, parse.parse_qs(query_params)
-
-
-def get_template_url(template_file=None, template_url=None):
-    if template_file:
-        template_url = normalise_file_path_to_url(template_file)
-    return template_url
-
-
-def read_url_content(url):
-    try:
-        content = request.urlopen(url).read()
-    except error.URLError:
-        raise exc.CommandError(_('Could not fetch contents for %s') % url)
-
-    if content:
-        try:
-            content.decode('utf-8')
-        except ValueError:
-            content = base64.encodestring(content)
-    return content
-
-
-def base_url_for_url(url):
-    parsed = parse.urlparse(url)
-    parsed_dir = os.path.dirname(parsed.path)
-    return parse.urljoin(url, parsed_dir)
-
-
-def normalise_file_path_to_url(path):
-    if parse.urlparse(path).scheme:
-        return path
-    path = os.path.abspath(path)
-    return parse.urljoin('file:', request.pathname2url(path))
-
-
-def get_response_body(resp):
-    body = resp.content
-    if 'application/json' in resp.headers.get('content-type', ''):
-        try:
-            body = resp.json()
-        except ValueError:
-            LOG.error(_LE('Could not decode response body as JSON'))
-    else:
-        body = None
-    return body
-
-
-def terminal_width():
-    if hasattr(os, 'get_terminal_size'):
-        # python 3.3 onwards has built-in support for getting terminal size
-        try:
-            return os.get_terminal_size().columns
-        except OSError:
-            return None
-    try:
-        # winsize structure has 4 unsigned short fields
-        winsize = b'\0' * struct.calcsize('hhhh')
-        try:
-            winsize = ioctl(sys.stdout, termios.TIOCGWINSZ, winsize)
-        except IOError:
-            return None
-        except TypeError:
-            # this is raised in unit tests as stdout is sometimes a StringIO
-            return None
-        winsize = struct.unpack('hhhh', winsize)
-        columns = winsize[1]
-        if not columns:
-            return None
-        return columns
-    except IOError:
-        return None
diff --git a/stacktaskclient/openstack/common/_i18n.py b/stacktaskclient/openstack/common/_i18n.py
deleted file mode 100644
index e3f8323..0000000
--- a/stacktaskclient/openstack/common/_i18n.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#    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.
-
-"""oslo.i18n integration module.
-
-See http://docs.openstack.org/developer/oslo.i18n/usage.html
-
-"""
-
-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='stacktaskclient')
-
-    # 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/stacktaskclient/openstack/common/apiclient/__init__.py b/stacktaskclient/openstack/common/apiclient/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/stacktaskclient/openstack/common/apiclient/auth.py b/stacktaskclient/openstack/common/apiclient/auth.py
deleted file mode 100644
index 1bd12d5..0000000
--- a/stacktaskclient/openstack/common/apiclient/auth.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# Copyright 2013 Spanish National Research Council.
-# 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.
-
-# 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-oslo-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
-
-import six
-from stevedore import extension
-
-from stacktaskclient.openstack.common.apiclient import exceptions
-
-
-_discovered_plugins = {}
-
-
-def discover_auth_systems():
-    """Discover the available auth-systems.
-
-    This won't take into account the old style auth-systems.
-    """
-    global _discovered_plugins
-    _discovered_plugins = {}
-
-    def add_plugin(ext):
-        _discovered_plugins[ext.name] = ext.plugin
-
-    ep_namespace = "stacktaskclient.openstack.common.apiclient.auth"
-    mgr = extension.ExtensionManager(ep_namespace)
-    mgr.map(add_plugin)
-
-
-def load_auth_system_opts(parser):
-    """Load options needed by the available auth-systems into a parser.
-
-    This function will try to populate the parser with options from the
-    available plugins.
-    """
-    group = parser.add_argument_group("Common auth options")
-    BaseAuthPlugin.add_common_opts(group)
-    for name, auth_plugin in six.iteritems(_discovered_plugins):
-        group = parser.add_argument_group(
-            "Auth-system '%s' options" % name,
-            conflict_handler="resolve")
-        auth_plugin.add_opts(group)
-
-
-def load_plugin(auth_system):
-    try:
-        plugin_class = _discovered_plugins[auth_system]
-    except KeyError:
-        raise exceptions.AuthSystemNotFound(auth_system)
-    return plugin_class(auth_system=auth_system)
-
-
-def load_plugin_from_args(args):
-    """Load required plugin and populate it with options.
-
-    Try to guess auth system if it is not specified. Systems are tried in
-    alphabetical order.
-
-    :type args: argparse.Namespace
-    :raises: AuthPluginOptionsMissing
-    """
-    auth_system = args.os_auth_system
-    if auth_system:
-        plugin = load_plugin(auth_system)
-        plugin.parse_opts(args)
-        plugin.sufficient_options()
-        return plugin
-
-    for plugin_auth_system in sorted(six.iterkeys(_discovered_plugins)):
-        plugin_class = _discovered_plugins[plugin_auth_system]
-        plugin = plugin_class()
-        plugin.parse_opts(args)
-        try:
-            plugin.sufficient_options()
-        except exceptions.AuthPluginOptionsMissing:
-            continue
-        return plugin
-    raise exceptions.AuthPluginOptionsMissing(["auth_system"])
-
-
-@six.add_metaclass(abc.ABCMeta)
-class BaseAuthPlugin(object):
-    """Base class for authentication plugins.
-
-    An authentication plugin needs to override at least the authenticate
-    method to be a valid plugin.
-    """
-
-    auth_system = None
-    opt_names = []
-    common_opt_names = [
-        "auth_system",
-        "username",
-        "password",
-        "tenant_name",
-        "token",
-        "auth_url",
-    ]
-
-    def __init__(self, auth_system=None, **kwargs):
-        self.auth_system = auth_system or self.auth_system
-        self.opts = dict((name, kwargs.get(name))
-                         for name in self.opt_names)
-
-    @staticmethod
-    def _parser_add_opt(parser, opt):
-        """Add an option to parser in two variants.
-
-        :param opt: option name (with underscores)
-        """
-        dashed_opt = opt.replace("_", "-")
-        env_var = "OS_%s" % opt.upper()
-        arg_default = os.environ.get(env_var, "")
-        arg_help = "Defaults to env[%s]." % env_var
-        parser.add_argument(
-            "--os-%s" % dashed_opt,
-            metavar="<%s>" % dashed_opt,
-            default=arg_default,
-            help=arg_help)
-        parser.add_argument(
-            "--os_%s" % opt,
-            metavar="<%s>" % dashed_opt,
-            help=argparse.SUPPRESS)
-
-    @classmethod
-    def add_opts(cls, parser):
-        """Populate the parser with the options for this plugin.
-        """
-        for opt in cls.opt_names:
-            # use `BaseAuthPlugin.common_opt_names` since it is never
-            # changed in child classes
-            if opt not in BaseAuthPlugin.common_opt_names:
-                cls._parser_add_opt(parser, opt)
-
-    @classmethod
-    def add_common_opts(cls, parser):
-        """Add options that are common for several plugins.
-        """
-        for opt in cls.common_opt_names:
-            cls._parser_add_opt(parser, opt)
-
-    @staticmethod
-    def get_opt(opt_name, args):
-        """Return option name and value.
-
-        :param opt_name: name of the option, e.g., "username"
-        :param args: parsed arguments
-        """
-        return (opt_name, getattr(args, "os_%s" % opt_name, None))
-
-    def parse_opts(self, args):
-        """Parse the actual auth-system options if any.
-
-        This method is expected to populate the attribute `self.opts` with a
-        dict containing the options and values needed to make authentication.
-        """
-        self.opts.update(dict(self.get_opt(opt_name, args)
-                              for opt_name in self.opt_names))
-
-    def authenticate(self, http_client):
-        """Authenticate using plugin defined method.
-
-        The method usually analyses `self.opts` and performs
-        a request to authentication server.
-
-        :param http_client: client object that needs authentication
-        :type http_client: HTTPClient
-        :raises: AuthorizationFailure
-        """
-        self.sufficient_options()
-        self._do_authenticate(http_client)
-
-    @abc.abstractmethod
-    def _do_authenticate(self, http_client):
-        """Protected method for authentication.
-        """
-
-    def sufficient_options(self):
-        """Check if all required options are present.
-
-        :raises: AuthPluginOptionsMissing
-        """
-        missing = [opt
-                   for opt in self.opt_names
-                   if not self.opts.get(opt)]
-        if missing:
-            raise exceptions.AuthPluginOptionsMissing(missing)
-
-    @abc.abstractmethod
-    def token_and_endpoint(self, endpoint_type, service_type):
-        """Return token and endpoint.
-
-        :param service_type: Service type of the endpoint
-        :type service_type: string
-        :param endpoint_type: Type of endpoint.
-                              Possible values: public or publicURL,
-                              internal or internalURL,
-                              admin or adminURL
-        :type endpoint_type: string
-        :returns: tuple of token and endpoint strings
-        :raises: EndpointException
-        """
diff --git a/stacktaskclient/openstack/common/apiclient/client.py b/stacktaskclient/openstack/common/apiclient/client.py
deleted file mode 100644
index e414227..0000000
--- a/stacktaskclient/openstack/common/apiclient/client.py
+++ /dev/null
@@ -1,388 +0,0 @@
-# Copyright 2010 Jacob Kaplan-Moss
-# Copyright 2011 OpenStack Foundation
-# Copyright 2011 Piston Cloud Computing, Inc.
-# Copyright 2013 Alessio Ababilov
-# Copyright 2013 Grid Dynamics
-# Copyright 2013 OpenStack Foundation
-# 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.
-
-"""
-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
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-from oslo_utils import encodeutils
-from oslo_utils import importutils
-import requests
-
-from stacktaskclient.openstack.common._i18n import _
-from stacktaskclient.openstack.common.apiclient import exceptions
-
-_logger = logging.getLogger(__name__)
-SENSITIVE_HEADERS = ('X-Auth-Token', 'X-Subject-Token',)
-
-
-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;
-    - encode/decode JSON bodies;
-    - raise exceptions on HTTP errors;
-    - pluggable authentication;
-    - store authentication information in a keyring;
-    - store time spent for requests;
-    - register clients for particular services, so one can use
-      `http_client.identity` or `http_client.compute`;
-    - log requests and responses in a format that is easy to copy-and-paste
-      into terminal and send the same request with curl.
-    """
-
-    user_agent = "stacktaskclient.openstack.common.apiclient"
-
-    def __init__(self,
-                 auth_plugin,
-                 region_name=None,
-                 endpoint_type="publicURL",
-                 original_ip=None,
-                 verify=True,
-                 cert=None,
-                 timeout=None,
-                 timings=False,
-                 keyring_saver=None,
-                 debug=False,
-                 user_agent=None,
-                 http=None):
-        self.auth_plugin = auth_plugin
-
-        self.endpoint_type = endpoint_type
-        self.region_name = region_name
-
-        self.original_ip = original_ip
-        self.timeout = timeout
-        self.verify = verify
-        self.cert = cert
-
-        self.keyring_saver = keyring_saver
-        self.debug = debug
-        self.user_agent = user_agent or self.user_agent
-
-        self.times = []  # [("item", starttime, endtime), ...]
-        self.timings = timings
-
-        # requests within the same session can reuse TCP connections from pool
-        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:
-            return
-
-        string_parts = [
-            "curl -g -i",
-            "-X '%s'" % method,
-            "'%s'" % url,
-        ]
-
-        for element in kwargs['headers']:
-            header = ("-H '%s: %s'" %
-                      self._safe_header(element, kwargs['headers'][element]))
-            string_parts.append(header)
-
-        _logger.debug("REQ: %s" % " ".join(string_parts))
-        if 'data' in kwargs:
-            _logger.debug("REQ BODY: %s\n" % (kwargs['data']))
-
-    def _http_log_resp(self, resp):
-        if not self.debug:
-            return
-        _logger.debug(
-            "RESP: [%s] %s\n",
-            resp.status_code,
-            resp.headers)
-        if resp._content_consumed:
-            _logger.debug(
-                "RESP BODY: %s\n",
-                resp.text)
-
-    def serialize(self, kwargs):
-        if kwargs.get('json') is not None:
-            kwargs['headers']['Content-Type'] = 'application/json'
-            kwargs['data'] = json.dumps(kwargs['json'])
-        try:
-            del kwargs['json']
-        except KeyError:
-            pass
-
-    def get_timings(self):
-        return self.times
-
-    def reset_timings(self):
-        self.times = []
-
-    def request(self, method, url, **kwargs):
-        """Send an http request with the specified characteristics.
-
-        Wrapper around `requests.Session.request` to handle tasks such as
-        setting headers, JSON encoding/decoding, and error handling.
-
-        :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`
-             that will be encoded as JSON and used as `data` argument
-        """
-        kwargs.setdefault("headers", {})
-        kwargs["headers"]["User-Agent"] = self.user_agent
-        if self.original_ip:
-            kwargs["headers"]["Forwarded"] = "for=%s;by=%s" % (
-                self.original_ip, self.user_agent)
-        if self.timeout is not None:
-            kwargs.setdefault("timeout", self.timeout)
-        kwargs.setdefault("verify", self.verify)
-        if self.cert is not None:
-            kwargs.setdefault("cert", self.cert)
-        self.serialize(kwargs)
-
-        self._http_log_req(method, url, kwargs)
-        if self.timings:
-            start_time = time.time()
-        resp = self.http.request(method, url, **kwargs)
-        if self.timings:
-            self.times.append(("%s %s" % (method, url),
-                               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",
-                resp.status_code)
-            raise exceptions.from_response(resp, method, url)
-
-        return resp
-
-    @staticmethod
-    def concat_url(endpoint, url):
-        """Concatenate endpoint and final URL.
-
-        E.g., "http://keystone/v2.0/" and "/tokens" are concatenated to
-        "http://keystone/v2.0/tokens".
-
-        :param endpoint: the base URL
-        :param url: the final URL
-        """
-        return "%s/%s" % (endpoint.rstrip("/"), url.strip("/"))
-
-    def client_request(self, client, method, url, **kwargs):
-        """Send an http request using `client`'s endpoint and specified `url`.
-
-        If request was rejected as unauthorized (possibly because the token is
-        expired), issue one authorization attempt and send the request once
-        again.
-
-        :param client: instance of BaseClient descendant
-        :param method: method of HTTP request
-        :param url: URL of HTTP request
-        :param kwargs: any other parameter that can be passed to
-            `HTTPClient.request`
-        """
-
-        filter_args = {
-            "endpoint_type": client.endpoint_type or self.endpoint_type,
-            "service_type": client.service_type,
-        }
-        token, endpoint = (self.cached_token, client.cached_endpoint)
-        just_authenticated = False
-        if not (token and endpoint):
-            try:
-                token, endpoint = self.auth_plugin.token_and_endpoint(
-                    **filter_args)
-            except exceptions.EndpointException:
-                pass
-            if not (token and endpoint):
-                self.authenticate()
-                just_authenticated = True
-                token, endpoint = self.auth_plugin.token_and_endpoint(
-                    **filter_args)
-                if not (token and endpoint):
-                    raise exceptions.AuthorizationFailure(
-                        _("Cannot find endpoint or token for request"))
-
-        old_token_endpoint = (token, endpoint)
-        kwargs.setdefault("headers", {})["X-Auth-Token"] = token
-        self.cached_token = token
-        client.cached_endpoint = endpoint
-        # Perform the request once. If we get Unauthorized, then it
-        # might be because the auth token expired, so try to
-        # re-authenticate and try again. If it still fails, bail.
-        try:
-            return self.request(
-                method, self.concat_url(endpoint, url), **kwargs)
-        except exceptions.Unauthorized as unauth_ex:
-            if just_authenticated:
-                raise
-            self.cached_token = None
-            client.cached_endpoint = None
-            if self.auth_plugin.opts.get('token'):
-                self.auth_plugin.opts['token'] = None
-            if self.auth_plugin.opts.get('endpoint'):
-                self.auth_plugin.opts['endpoint'] = None
-            self.authenticate()
-            try:
-                token, endpoint = self.auth_plugin.token_and_endpoint(
-                    **filter_args)
-            except exceptions.EndpointException:
-                raise unauth_ex
-            if (not (token and endpoint) or
-                    old_token_endpoint == (token, endpoint)):
-                raise unauth_ex
-            self.cached_token = token
-            client.cached_endpoint = endpoint
-            kwargs["headers"]["X-Auth-Token"] = token
-            return self.request(
-                method, self.concat_url(endpoint, url), **kwargs)
-
-    def add_client(self, base_client_instance):
-        """Add a new instance of :class:`BaseClient` descendant.
-
-        `self` will store a reference to `base_client_instance`.
-
-        Example:
-
-        >>> def test_clients():
-        ...     from keystoneclient.auth import keystone
-        ...     from openstack.common.apiclient import client
-        ...     auth = keystone.KeystoneAuthPlugin(
-        ...         username="user", password="pass", tenant_name="tenant",
-        ...         auth_url="http://auth:5000/v2.0")
-        ...     openstack_client = client.HTTPClient(auth)
-        ...     # create nova client
-        ...     from novaclient.v1_1 import client
-        ...     client.Client(openstack_client)
-        ...     # create keystone client
-        ...     from keystoneclient.v2_0 import client
-        ...     client.Client(openstack_client)
-        ...     # use them
-        ...     openstack_client.identity.tenants.list()
-        ...     openstack_client.compute.servers.list()
-        """
-        service_type = base_client_instance.service_type
-        if service_type and not hasattr(self, service_type):
-            setattr(self, service_type, base_client_instance)
-
-    def authenticate(self):
-        self.auth_plugin.authenticate(self)
-        # Store the authentication results in the keyring for later requests
-        if self.keyring_saver:
-            self.keyring_saver.save(self)
-
-
-class BaseClient(object):
-    """Top-level object to access the OpenStack API.
-
-    This client uses :class:`HTTPClient` to send requests. :class:`HTTPClient`
-    will handle a bunch of issues such as authentication.
-    """
-
-    service_type = None
-    endpoint_type = None  # "publicURL" will be used
-    cached_endpoint = None
-
-    def __init__(self, http_client, extensions=None):
-        self.http_client = http_client
-        http_client.add_client(self)
-
-        # Add in any extensions...
-        if extensions:
-            for extension in extensions:
-                if extension.manager_class:
-                    setattr(self, extension.name,
-                            extension.manager_class(self))
-
-    def client_request(self, method, url, **kwargs):
-        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)
-
-    def get(self, url, **kwargs):
-        return self.client_request("GET", url, **kwargs)
-
-    def post(self, url, **kwargs):
-        return self.client_request("POST", url, **kwargs)
-
-    def put(self, url, **kwargs):
-        return self.client_request("PUT", url, **kwargs)
-
-    def delete(self, url, **kwargs):
-        return self.client_request("DELETE", url, **kwargs)
-
-    def patch(self, url, **kwargs):
-        return self.client_request("PATCH", url, **kwargs)
-
-    @staticmethod
-    def get_class(api_name, version, version_map):
-        """Returns the client class for the requested API version
-
-        :param api_name: the name of the API, e.g. 'compute', 'image', etc
-        :param version: the requested API version
-        :param version_map: a dict of client classes keyed by version
-        :rtype: a client class for the requested API version
-        """
-        try:
-            client_path = version_map[str(version)]
-        except (KeyError, ValueError):
-            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/stacktaskclient/openstack/common/apiclient/exceptions.py b/stacktaskclient/openstack/common/apiclient/exceptions.py
deleted file mode 100644
index 7b8bc5d..0000000
--- a/stacktaskclient/openstack/common/apiclient/exceptions.py
+++ /dev/null
@@ -1,479 +0,0 @@
-# Copyright 2010 Jacob Kaplan-Moss
-# Copyright 2011 Nebula, Inc.
-# Copyright 2013 Alessio Ababilov
-# Copyright 2013 OpenStack Foundation
-# 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.
-
-"""
-Exception definitions.
-"""
-
-########################################################################
-#
-# THIS MODULE IS DEPRECATED
-#
-# Please refer to
-# https://etherpad.openstack.org/p/kilo-oslo-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
-
-import six
-
-from stacktaskclient.openstack.common._i18n import _
-
-
-class ClientException(Exception):
-    """The base exception class for all exceptions this library raises.
-    """
-    pass
-
-
-class ValidationError(ClientException):
-    """Error in validation on API client side."""
-    pass
-
-
-class UnsupportedVersion(ClientException):
-    """User is trying to use an unsupported version of the API."""
-    pass
-
-
-class CommandError(ClientException):
-    """Error in CLI tool."""
-    pass
-
-
-class AuthorizationFailure(ClientException):
-    """Cannot authorize API client."""
-    pass
-
-
-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):
-        super(AuthPluginOptionsMissing, self).__init__(
-            _("Authentication failed. Missing options: %s") %
-            ", ".join(opt_names))
-        self.opt_names = opt_names
-
-
-class AuthSystemNotFound(AuthorizationFailure):
-    """User has specified an AuthSystem that is not installed."""
-    def __init__(self, auth_system):
-        super(AuthSystemNotFound, self).__init__(
-            _("AuthSystemNotFound: %r") % auth_system)
-        self.auth_system = auth_system
-
-
-class NoUniqueMatch(ClientException):
-    """Multiple entities found instead of one."""
-    pass
-
-
-class EndpointException(ClientException):
-    """Something is rotten in Service Catalog."""
-    pass
-
-
-class EndpointNotFound(EndpointException):
-    """Could not find requested endpoint in Service Catalog."""
-    pass
-
-
-class AmbiguousEndpoints(EndpointException):
-    """Found more than one matching endpoint in Service Catalog."""
-    def __init__(self, endpoints=None):
-        super(AmbiguousEndpoints, self).__init__(
-            _("AmbiguousEndpoints: %r") % endpoints)
-        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)
-
-
-class HTTPRedirection(HttpError):
-    """HTTP Redirection."""
-    message = _("HTTP Redirection")
-
-
-class HTTPClientError(HttpError):
-    """Client-side HTTP error.
-
-    Exception for cases in which the client seems to have erred.
-    """
-    message = _("HTTP Client Error")
-
-
-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 MultipleChoices(HTTPRedirection):
-    """HTTP 300 - Multiple Choices.
-
-    Indicates multiple options for the resource that the client may follow.
-    """
-
-    http_status = 300
-    message = _("Multiple Choices")
-
-
-class BadRequest(HTTPClientError):
-    """HTTP 400 - Bad Request.
-
-    The request cannot be fulfilled due to bad syntax.
-    """
-    http_status = 400
-    message = _("Bad Request")
-
-
-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.
-    """
-    http_status = 401
-    message = _("Unauthorized")
-
-
-class PaymentRequired(HTTPClientError):
-    """HTTP 402 - Payment Required.
-
-    Reserved for future use.
-    """
-    http_status = 402
-    message = _("Payment Required")
-
-
-class Forbidden(HTTPClientError):
-    """HTTP 403 - Forbidden.
-
-    The request was a valid request, but the server is refusing to respond
-    to it.
-    """
-    http_status = 403
-    message = _("Forbidden")
-
-
-class NotFound(HTTPClientError):
-    """HTTP 404 - Not Found.
-
-    The requested resource could not be found but may be available again
-    in the future.
-    """
-    http_status = 404
-    message = _("Not Found")
-
-
-class MethodNotAllowed(HTTPClientError):
-    """HTTP 405 - Method Not Allowed.
-
-    A request was made of a resource using a request method not supported
-    by that resource.
-    """
-    http_status = 405
-    message = _("Method Not Allowed")
-
-
-class NotAcceptable(HTTPClientError):
-    """HTTP 406 - Not Acceptable.
-
-    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")
-
-
-class ProxyAuthenticationRequired(HTTPClientError):
-    """HTTP 407 - Proxy Authentication Required.
-
-    The client must first authenticate itself with the proxy.
-    """
-    http_status = 407
-    message = _("Proxy Authentication Required")
-
-
-class RequestTimeout(HTTPClientError):
-    """HTTP 408 - Request Timeout.
-
-    The server timed out waiting for the request.
-    """
-    http_status = 408
-    message = _("Request Timeout")
-
-
-class Conflict(HTTPClientError):
-    """HTTP 409 - Conflict.
-
-    Indicates that the request could not be processed because of conflict
-    in the request, such as an edit conflict.
-    """
-    http_status = 409
-    message = _("Conflict")
-
-
-class Gone(HTTPClientError):
-    """HTTP 410 - Gone.
-
-    Indicates that the resource requested is no longer available and will
-    not be available again.
-    """
-    http_status = 410
-    message = _("Gone")
-
-
-class LengthRequired(HTTPClientError):
-    """HTTP 411 - Length Required.
-
-    The request did not specify the length of its content, which is
-    required by the requested resource.
-    """
-    http_status = 411
-    message = _("Length Required")
-
-
-class PreconditionFailed(HTTPClientError):
-    """HTTP 412 - Precondition Failed.
-
-    The server does not meet one of the preconditions that the requester
-    put on the request.
-    """
-    http_status = 412
-    message = _("Precondition Failed")
-
-
-class RequestEntityTooLarge(HTTPClientError):
-    """HTTP 413 - Request Entity Too Large.
-
-    The request is larger than the server is willing or able to process.
-    """
-    http_status = 413
-    message = _("Request Entity Too Large")
-
-    def __init__(self, *args, **kwargs):
-        try:
-            self.retry_after = int(kwargs.pop('retry_after'))
-        except (KeyError, ValueError):
-            self.retry_after = 0
-
-        super(RequestEntityTooLarge, self).__init__(*args, **kwargs)
-
-
-class RequestUriTooLong(HTTPClientError):
-    """HTTP 414 - Request-URI Too Long.
-
-    The URI provided was too long for the server to process.
-    """
-    http_status = 414
-    message = _("Request-URI Too Long")
-
-
-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")
-
-
-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")
-
-
-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)
diff --git a/stacktaskclient/openstack/common/apiclient/fake_client.py b/stacktaskclient/openstack/common/apiclient/fake_client.py
deleted file mode 100644
index 25d3ada..0000000
--- a/stacktaskclient/openstack/common/apiclient/fake_client.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# 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.
-
-"""
-A fake server that "responds" to API methods with pre-canned responses.
-
-All of these responses come from the spec, so if for some reason the spec's
-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-oslo-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
-
-import json
-
-import requests
-import six
-from six.moves.urllib import parse
-
-from stacktaskclient.openstack.common.apiclient import client
-
-
-def assert_has_keys(dct, required=None, optional=None):
-    required = required or []
-    optional = optional or []
-    for k in required:
-        try:
-            assert k in dct
-        except AssertionError:
-            extra_keys = set(dct.keys()).difference(set(required + optional))
-            raise AssertionError("found unexpected keys: %s" %
-                                 list(extra_keys))
-
-
-class TestResponse(requests.Response):
-    """Wrap requests.Response and provide a convenient initialization.
-    """
-
-    def __init__(self, data):
-        super(TestResponse, self).__init__()
-        self._content_consumed = True
-        if isinstance(data, dict):
-            self.status_code = data.get('status_code', 200)
-            # Fake the text attribute to streamline Response creation
-            text = data.get('text', "")
-            if isinstance(text, (dict, list)):
-                self._content = json.dumps(text)
-                default_headers = {
-                    "Content-Type": "application/json",
-                }
-            else:
-                self._content = text
-                default_headers = {}
-            if six.PY3 and isinstance(self._content, six.string_types):
-                self._content = self._content.encode('utf-8', 'strict')
-            self.headers = data.get('headers') or default_headers
-        else:
-            self.status_code = data
-
-    def __eq__(self, other):
-        return (self.status_code == other.status_code and
-                self.headers == other.headers and
-                self._content == other._content)
-
-
-class FakeHTTPClient(client.HTTPClient):
-
-    def __init__(self, *args, **kwargs):
-        self.callstack = []
-        self.fixtures = kwargs.pop("fixtures", None) or {}
-        if not args and "auth_plugin" not in kwargs:
-            args = (None, )
-        super(FakeHTTPClient, self).__init__(*args, **kwargs)
-
-    def assert_called(self, method, url, body=None, pos=-1):
-        """Assert than an API method was just called.
-        """
-        expected = (method, url)
-        called = self.callstack[pos][0:2]
-        assert self.callstack, \
-            "Expected %s %s but no calls were made." % expected
-
-        assert expected == called, 'Expected %s %s; got %s %s' % \
-            (expected + called)
-
-        if body is not None:
-            if self.callstack[pos][3] != body:
-                raise AssertionError('%r != %r' %
-                                     (self.callstack[pos][3], body))
-
-    def assert_called_anytime(self, method, url, body=None):
-        """Assert than an API method was called anytime in the test.
-        """
-        expected = (method, url)
-
-        assert self.callstack, \
-            "Expected %s %s but no calls were made." % expected
-
-        found = False
-        entry = None
-        for entry in self.callstack:
-            if expected == entry[0:2]:
-                found = True
-                break
-
-        assert found, 'Expected %s %s; got %s' % \
-            (method, url, self.callstack)
-        if body is not None:
-            assert entry[3] == body, "%s != %s" % (entry[3], body)
-
-        self.callstack = []
-
-    def clear_callstack(self):
-        self.callstack = []
-
-    def authenticate(self):
-        pass
-
-    def client_request(self, client, method, url, **kwargs):
-        # Check that certain things are called correctly
-        if method in ["GET", "DELETE"]:
-            assert "json" not in kwargs
-
-        # Note the call
-        self.callstack.append(
-            (method,
-             url,
-             kwargs.get("headers") or {},
-             kwargs.get("json") or kwargs.get("data")))
-        try:
-            fixture = self.fixtures[url][method]
-        except KeyError:
-            pass
-        else:
-            return TestResponse({"headers": fixture[0],
-                                 "text": fixture[1]})
-
-        # Call the method
-        args = parse.parse_qsl(parse.urlparse(url)[4])
-        kwargs.update(args)
-        munged_url = url.rsplit('?', 1)[0]
-        munged_url = munged_url.strip('/').replace('/', '_').replace('.', '_')
-        munged_url = munged_url.replace('-', '_')
-
-        callback = "%s_%s" % (method.lower(), munged_url)
-
-        if not hasattr(self, callback):
-            raise AssertionError('Called unknown API method: %s %s, '
-                                 'expected fakes method name: %s' %
-                                 (method, url, callback))
-
-        resp = getattr(self, callback)(**kwargs)
-        if len(resp) == 3:
-            status, headers, body = resp
-        else:
-            status, body = resp
-            headers = {}
-        self.last_request_id = headers.get('x-openstack-request-id',
-                                           'req-test')
-        return TestResponse({
-            "status_code": status,
-            "text": body,
-            "headers": headers,
-        })
diff --git a/stacktaskclient/openstack/common/apiclient/utils.py b/stacktaskclient/openstack/common/apiclient/utils.py
deleted file mode 100644
index 8f7200d..0000000
--- a/stacktaskclient/openstack/common/apiclient/utils.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-#    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.
-
-########################################################################
-#
-# THIS MODULE IS DEPRECATED
-#
-# Please refer to
-# https://etherpad.openstack.org/p/kilo-oslo-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 stacktaskclient.openstack.common._i18n import _
-from stacktaskclient.openstack.common.apiclient import exceptions
-
-
-def find_resource(manager, name_or_id, **find_args):
-    """Look for resource in a given manager.
-
-    Used as a helper for the _find_* methods.
-    Example:
-
-    .. code-block:: python
-
-        def _find_hypervisor(cs, hypervisor):
-            #Get a hypervisor by name or ID.
-            return cliutils.find_resource(cs.hypervisors, hypervisor)
-    """
-    # first try to get entity as integer id
-    try:
-        return manager.get(int(name_or_id))
-    except (TypeError, ValueError, exceptions.NotFound):
-        pass
-
-    # now try to get entity as uuid
-    try:
-        if six.PY2:
-            tmp_id = encodeutils.safe_encode(name_or_id)
-        else:
-            tmp_id = encodeutils.safe_decode(name_or_id)
-
-        if uuidutils.is_uuid_like(tmp_id):
-            return manager.get(tmp_id)
-    except (TypeError, ValueError, exceptions.NotFound):
-        pass
-
-    # for str id which is not uuid
-    if getattr(manager, 'is_alphanum_id_allowed', False):
-        try:
-            return manager.get(name_or_id)
-        except exceptions.NotFound:
-            pass
-
-    try:
-        try:
-            return manager.find(human_id=name_or_id, **find_args)
-        except exceptions.NotFound:
-            pass
-
-        # finally try to find entity by name
-        try:
-            resource = getattr(manager, 'resource_class', None)
-            name_attr = resource.NAME_ATTR if resource else 'name'
-            kwargs = {name_attr: name_or_id}
-            kwargs.update(find_args)
-            return manager.find(**kwargs)
-        except exceptions.NotFound:
-            msg = _("No %(name)s with a name or "
-                    "ID of '%(name_or_id)s' exists.") % \
-                {
-                    "name": manager.resource_class.__name__.lower(),
-                    "name_or_id": name_or_id
-                }
-            raise exceptions.CommandError(msg)
-    except exceptions.NoUniqueMatch:
-        msg = _("Multiple %(name)s matches found for "
-                "'%(name_or_id)s', use an ID to be more specific.") % \
-            {
-                "name": manager.resource_class.__name__.lower(),
-                "name_or_id": name_or_id
-            }
-        raise exceptions.CommandError(msg)
diff --git a/stacktaskclient/openstack/common/cliutils.py b/stacktaskclient/openstack/common/cliutils.py
deleted file mode 100644
index 3303706..0000000
--- a/stacktaskclient/openstack/common/cliutils.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# Copyright 2012 Red Hat, Inc.
-#
-#    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.
-
-# W0603: Using the global statement
-# W0621: Redefining name %s from outer scope
-# pylint: disable=W0603,W0621
-
-from __future__ import print_function
-
-import getpass
-import inspect
-import os
-import sys
-import textwrap
-
-from oslo_utils import encodeutils
-from oslo_utils import strutils
-import prettytable
-import six
-from six import moves
-
-from stacktaskclient.openstack.common._i18n import _
-
-
-class MissingArgs(Exception):
-    """Supplied arguments are not sufficient for calling a function."""
-    def __init__(self, missing):
-        self.missing = missing
-        msg = _("Missing arguments: %s") % ", ".join(missing)
-        super(MissingArgs, self).__init__(msg)
-
-
-def validate_args(fn, *args, **kwargs):
-    """Check that the supplied args are sufficient for calling a function.
-
-    >>> validate_args(lambda a: None)
-    Traceback (most recent call last):
-        ...
-    MissingArgs: Missing argument(s): a
-    >>> validate_args(lambda a, b, c, d: None, 0, c=1)
-    Traceback (most recent call last):
-        ...
-    MissingArgs: Missing argument(s): b, d
-
-    :param fn: the function to check
-    :param arg: the positional arguments supplied
-    :param kwargs: the keyword arguments supplied
-    """
-    argspec = inspect.getargspec(fn)
-
-    num_defaults = len(argspec.defaults or [])
-    required_args = argspec.args[:len(argspec.args) - num_defaults]
-
-    def isbound(method):
-        return getattr(method, '__self__', None) is not None
-
-    if isbound(fn):
-        required_args.pop(0)
-
-    missing = [arg for arg in required_args if arg not in kwargs]
-    missing = missing[len(args):]
-    if missing:
-        raise MissingArgs(missing)
-
-
-def arg(*args, **kwargs):
-    """Decorator for CLI args.
-
-    Example:
-
-    >>> @arg("name", help="Name of the new entity")
-    ... def entity_create(args):
-    ...     pass
-    """
-    def _decorator(func):
-        add_arg(func, *args, **kwargs)
-        return func
-    return _decorator
-
-
-def env(*args, **kwargs):
-    """Returns the first environment variable set.
-
-    If all are empty, defaults to '' or keyword arg `default`.
-    """
-    for arg in args:
-        value = os.environ.get(arg)
-        if value:
-            return value
-    return kwargs.get('default', '')
-
-
-def add_arg(func, *args, **kwargs):
-    """Bind CLI arguments to a shell.py `do_foo` function."""
-
-    if not hasattr(func, 'arguments'):
-        func.arguments = []
-
-    # NOTE(sirp): avoid dups that can occur when the module is shared across
-    # tests.
-    if (args, kwargs) not in func.arguments:
-        # Because of the semantics of decorator composition if we just append
-        # to the options list positional options will appear to be backwards.
-        func.arguments.insert(0, (args, kwargs))
-
-
-def unauthenticated(func):
-    """Adds 'unauthenticated' attribute to decorated function.
-
-    Usage:
-
-    >>> @unauthenticated
-    ... def mymethod(f):
-    ...     pass
-    """
-    func.unauthenticated = True
-    return func
-
-
-def isunauthenticated(func):
-    """Checks if the function does not require authentication.
-
-    Mark such functions with the `@unauthenticated` decorator.
-
-    :returns: bool
-    """
-    return getattr(func, 'unauthenticated', False)
-
-
-def print_list(objs, fields, formatters=None, sortby_index=None,
-               mixed_case_fields=None, field_labels=None):
-    """Print a list or objects as a table, one row per object.
-
-    :param objs: iterable of :class:`Resource`
-    :param fields: attributes that correspond to columns, in order
-    :param formatters: `dict` of callables for field formatting
-    :param sortby_index: index of the field for sorting table rows
-    :param mixed_case_fields: fields corresponding to object attributes that
-        have mixed case names (e.g., 'serverId')
-    :param field_labels: Labels to use in the heading of the table, default to
-        fields.
-    """
-    formatters = formatters or {}
-    mixed_case_fields = mixed_case_fields or []
-    field_labels = field_labels or fields
-    if len(field_labels) != len(fields):
-        raise ValueError(_("Field labels list %(labels)s has different number "
-                           "of elements than fields list %(fields)s"),
-                         {'labels': field_labels, 'fields': fields})
-
-    if sortby_index is None:
-        kwargs = {}
-    else:
-        kwargs = {'sortby': field_labels[sortby_index]}
-    pt = prettytable.PrettyTable(field_labels)
-    pt.align = 'l'
-
-    for o in objs:
-        row = []
-        for field in fields:
-            if field in formatters:
-                row.append(formatters[field](o))
-            else:
-                if field in mixed_case_fields:
-                    field_name = field.replace(' ', '_')
-                else:
-                    field_name = field.lower().replace(' ', '_')
-                data = getattr(o, field_name, '')
-                row.append(data)
-        pt.add_row(row)
-
-    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):
-    """Print a `dict` as a table of two columns.
-
-    :param dct: `dict` to print
-    :param dict_property: name of the first column
-    :param wrap: wrapping for the second column
-    """
-    pt = prettytable.PrettyTable([dict_property, 'Value'])
-    pt.align = 'l'
-    for k, v in six.iteritems(dct):
-        # convert dict to str to check length
-        if isinstance(v, dict):
-            v = six.text_type(v)
-        if wrap > 0:
-            v = textwrap.fill(six.text_type(v), wrap)
-        # if value has a newline, add in multiple rows
-        # e.g. fault with stacktrace
-        if v and isinstance(v, six.string_types) and r'\n' in v:
-            lines = v.strip().split(r'\n')
-            col1 = k
-            for line in lines:
-                pt.add_row([col1, line])
-                col1 = ''
-        else:
-            pt.add_row([k, v])
-
-    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):
-    """Read password from TTY."""
-    verify = strutils.bool_from_string(env("OS_VERIFY_PASSWORD"))
-    pw = None
-    if hasattr(sys.stdin, "isatty") and sys.stdin.isatty():
-        # Check for Ctrl-D
-        try:
-            for __ in moves.range(max_password_prompts):
-                pw1 = getpass.getpass("OS Password: ")
-                if verify:
-                    pw2 = getpass.getpass("Please verify: ")
-                else:
-                    pw2 = pw1
-                if pw1 == pw2 and pw1:
-                    pw = pw1
-                    break
-        except EOFError:
-            pass
-    return pw
-
-
-def service_type(stype):
-    """Adds 'service_type' attribute to decorated function.
-
-    Usage:
-
-    .. code-block:: python
-
-       @service_type('volume')
-       def mymethod(f):
-       ...
-    """
-    def inner(f):
-        f.service_type = stype
-        return f
-    return inner
-
-
-def get_service_type(f):
-    """Retrieves service type from function."""
-    return getattr(f, 'service_type', None)
-
-
-def pretty_choice_list(l):
-    return ', '.join("'%s'" % i for i in l)
-
-
-def exit(msg=''):
-    if msg:
-        print (msg, file=sys.stderr)
-    sys.exit(1)
diff --git a/stacktaskclient/osc/__init__.py b/stacktaskclient/osc/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/stacktaskclient/osc/v1/__init__.py b/stacktaskclient/osc/v1/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/stacktaskclient/shell.py b/stacktaskclient/shell.py
deleted file mode 100644
index 896bd7e..0000000
--- a/stacktaskclient/shell.py
+++ /dev/null
@@ -1,593 +0,0 @@
-#    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.
-
-"""
-Command-line interface to the Stacktask API.
-"""
-
-from __future__ import print_function
-
-import argparse
-import logging
-import sys
-
-from oslo_utils import encodeutils
-from oslo_utils import importutils
-import six
-
-from keystoneauth1.identity import generic
-from keystoneauth1 import session as kssession
-
-import stacktaskclient
-from stacktaskclient import client as stacktask_client
-from stacktaskclient.common import utils
-from stacktaskclient import exc
-from stacktaskclient.openstack.common._i18n import _
-
-logger = logging.getLogger(__name__)
-osprofiler_profiler = importutils.try_import("osprofiler.profiler")
-
-
-class StacktaskShell(object):
-
-    def _append_global_identity_args(self, parser):
-        parser.add_argument(
-            '-k', '--insecure',
-            default=False,
-            action='store_true',
-            help=_(
-                'Explicitly allow this client to perform '
-                '\"insecure SSL\" (https) requests. The server\'s '
-                'certificate will not be verified against any '
-                'certificate authorities. This option should '
-                'be used with caution.'))
-
-        parser.add_argument(
-            '--os-cert',
-            help=_(
-                'Path of certificate file to use in SSL '
-                'connection. This file can optionally be '
-                'prepended with the private key.'))
-
-        parser.add_argument(
-            '--os-key',
-            help=_(
-                'Path of client key to use in SSL '
-                'connection. This option is not necessary '
-                'if your key is prepended to your cert file.'))
-
-        parser.add_argument(
-            '--os-cacert',
-            metavar='<ca-certificate-file>',
-            dest='os_cacert',
-            default=utils.env('OS_CACERT'),
-            help=_(
-                'Path of CA TLS certificate(s) used to '
-                'verify the remote server\'s certificate. '
-                'Without this option glance looks for the '
-                'default system CA certificates.'))
-
-        parser.add_argument(
-            '--os-username',
-            default=utils.env('OS_USERNAME'),
-            help=_('Defaults to %(value)s.') % {'value': 'env[OS_USERNAME]'})
-
-        parser.add_argument('--os_username', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-user-id',
-            default=utils.env('OS_USER_ID'),
-            help=_('Defaults to %(value)s.') % {'value': 'env[OS_USER_ID]'})
-
-        parser.add_argument('--os_user_id', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-user-domain-id',
-            default=utils.env('OS_USER_DOMAIN_ID'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_USER_DOMAIN_ID]'
-            })
-
-        parser.add_argument('--os_user_domain_id', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-user-domain-name',
-            default=utils.env('OS_USER_DOMAIN_NAME'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_USER_DOMAIN_NAME]'
-            })
-
-        parser.add_argument('--os_user_domain_name', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-project-id',
-            default=utils.env('OS_PROJECT_ID'),
-            help=(
-                _('Another way to specify tenant ID. '
-                  'This option is mutually exclusive with '
-                  '%(arg)s. Defaults to %(value)s.') %
-                {'arg': '--os-tenant-id', 'value': 'env[OS_PROJECT_ID]'}))
-
-        parser.add_argument('--os_project_id', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-project-name',
-            default=utils.env('OS_PROJECT_NAME'),
-            help=(
-                _('Another way to specify tenant name. '
-                  'This option is mutually exclusive with '
-                  '%(arg)s. Defaults to %(value)s.') %
-                {'arg': '--os-tenant-name', 'value': 'env[OS_PROJECT_NAME]'}))
-
-        parser.add_argument('--os_project_name', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-project-domain-id',
-            default=utils.env('OS_PROJECT_DOMAIN_ID'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_PROJECT_DOMAIN_ID]'
-            })
-
-        parser.add_argument('--os_project_domain_id', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-project-domain-name',
-            default=utils.env('OS_PROJECT_DOMAIN_NAME'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_PROJECT_DOMAIN_NAME]'
-            })
-
-        parser.add_argument('--os_project_domain_name', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-password',
-            default=utils.env('OS_PASSWORD'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_PASSWORD]'
-            })
-
-        parser.add_argument('--os_password', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-tenant-id',
-            default=utils.env('OS_TENANT_ID'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_TENANT_ID]'
-            })
-
-        parser.add_argument(
-            '--os_tenant_id',
-            default=utils.env('OS_TENANT_ID'),
-            help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-tenant-name',
-            default=utils.env('OS_TENANT_NAME'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_TENANT_NAME]'
-            })
-
-        parser.add_argument(
-            '--os_tenant_name',
-            default=utils.env('OS_TENANT_NAME'),
-            help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-auth-url',
-            default=utils.env('OS_AUTH_URL'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_AUTH_URL]'
-            })
-
-        parser.add_argument('--os_auth_url', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-region-name',
-            default=utils.env('OS_REGION_NAME'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_REGION_NAME]'
-            })
-
-        parser.add_argument('--os_region_name', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-token',
-            default=utils.env('OS_TOKEN'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_TOKEN]'
-            })
-
-        parser.add_argument('--os_token', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-service-type',
-            default=utils.env('OS_SERVICE_TYPE'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_SERVICE_TYPE]'
-            })
-
-        parser.add_argument('--os_service_type', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--os-endpoint-type',
-            default=utils.env('OS_ENDPOINT_TYPE'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[OS_ENDPOINT_TYPE]'
-            })
-
-        parser.add_argument('--os_endpoint_type', help=argparse.SUPPRESS)
-
-    def get_base_parser(self):
-        parser = argparse.ArgumentParser(
-            prog='stacktask',
-            description=__doc__.strip(),
-            epilog=_('See "%(arg)s" for help on a specific command.') % {
-                'arg': 'stacktask help COMMAND'
-            },
-            add_help=False,
-            formatter_class=HelpFormatter,
-        )
-
-        # Global arguments
-        parser.add_argument(
-            '-h', '--help', action='store_true', help=argparse.SUPPRESS)
-
-        parser.add_argument(
-            '--version', action='version',
-            version=stacktaskclient.__version__,
-            help=_("Shows the client version and exits."))
-
-        parser.add_argument(
-            '-d', '--debug',
-            default=bool(utils.env('STACKTASKCLIENT_DEBUG')),
-            action='store_true',
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[STACKTASKCLIENT_DEBUG]'
-            })
-
-        parser.add_argument(
-            '-v', '--verbose',
-            default=False, action="store_true",
-            help=_("Print more verbose output."))
-
-        parser.add_argument(
-            '--api-timeout',
-            help=_('Number of seconds to wait for an '
-                   'API response, '
-                   'defaults to system socket timeout'))
-
-        # os-no-client-auth tells stacktaskclient to use token, instead of
-        # env[OS_AUTH_URL]
-        parser.add_argument(
-            '--os-no-client-auth',
-            default=utils.env('OS_NO_CLIENT_AUTH'),
-            action='store_true',
-            help=(_("Do not contact keystone for a token. "
-                    "Defaults to %(value)s.") %
-                  {'value': 'env[OS_NO_CLIENT_AUTH]'}))
-
-        parser.add_argument(
-            '--bypass-url',
-            default=utils.env('STACKTASK_BYPASS_URL'),
-            help=_('Defaults to %(value)s.') % {
-                'value': 'env[STACKTASK_BYPASS_URL]'
-            })
-
-        parser.add_argument(
-            '--api-version',
-            default=utils.env('STACKTASK_API_VERSION',
-                              default='1'),
-            help=_('Defaults to %(value)s or 1.') % {
-                'value': 'env[STACKTASK_API_VERSION]'
-            })
-
-        self._append_global_identity_args(parser)
-
-        if osprofiler_profiler:
-            parser.add_argument(
-                '--profile',
-                metavar='HMAC_KEY',
-                help=_(
-                    'HMAC key to use for encrypting '
-                    'context data for performance profiling of '
-                    'operation. This key should be the value of '
-                    'HMAC key configured in osprofiler middleware '
-                    'in heat, it is specified in the paste '
-                    'configuration (/etc/heat/api-paste.ini). '
-                    'Without the key, profiling will not be '
-                    'triggered even if osprofiler is enabled '
-                    'on server side.'))
-        return parser
-
-    def get_subcommand_parser(self, version):
-        parser = self.get_base_parser()
-
-        self.subcommands = {}
-        subparsers = parser.add_subparsers(metavar='<subcommand>')
-        submodule = utils.import_versioned_module(version, 'shell')
-        self._find_actions(subparsers, submodule)
-        self._find_actions(subparsers, self)
-        self._add_bash_completion_subparser(subparsers)
-
-        return parser
-
-    def _add_bash_completion_subparser(self, subparsers):
-        subparser = subparsers.add_parser(
-            'bash_completion',
-            add_help=False,
-            formatter_class=HelpFormatter
-        )
-        self.subcommands['bash_completion'] = subparser
-        subparser.set_defaults(func=self.do_bash_completion)
-
-    def _find_actions(self, subparsers, actions_module):
-        for attr in (a for a in dir(actions_module) if a.startswith('do_')):
-            # I prefer to be hyphen-separated instead of underscores.
-            command = attr[3:].replace('_', '-')
-            callback = getattr(actions_module, attr)
-            desc = callback.__doc__ or ''
-            help = desc.strip().split('\n')[0]
-            arguments = getattr(callback, 'arguments', [])
-
-            subparser = subparsers.add_parser(command,
-                                              help=help,
-                                              description=desc,
-                                              add_help=False,
-                                              formatter_class=HelpFormatter)
-            subparser.add_argument('-h', '--help',
-                                   action='help',
-                                   help=argparse.SUPPRESS)
-            self.subcommands[command] = subparser
-            for (args, kwargs) in arguments:
-                subparser.add_argument(*args, **kwargs)
-            subparser.set_defaults(func=callback)
-
-    def _setup_logging(self, debug):
-        log_lvl = logging.DEBUG if debug else logging.WARNING
-        logging.basicConfig(
-            format="%(levelname)s (%(module)s) %(message)s",
-            level=log_lvl)
-        logging.getLogger('iso8601').setLevel(logging.WARNING)
-        logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
-
-    def _setup_verbose(self, verbose):
-        if verbose:
-            exc.verbose = 1
-
-    def _get_keystone_session(self, **kwargs):
-        # first create a Keystone session
-        cacert = kwargs.pop('cacert', None)
-        cert = kwargs.pop('cert', None)
-        key = kwargs.pop('key', None)
-        insecure = kwargs.pop('insecure', False)
-        timeout = kwargs.pop('timeout', None)
-        verify = kwargs.pop('verify', None)
-
-        if verify is None:
-            if insecure:
-                verify = False
-            else:
-                verify = cacert or True
-        if cert and key:
-            # passing cert and key together is deprecated in favour of the
-            # requests lib form of having the cert and key as a tuple
-            cert = (cert, key)
-
-        return kssession.Session(verify=verify, cert=cert, timeout=timeout)
-
-    def main(self, argv):
-        # Parse args once to find version
-        parser = self.get_base_parser()
-        (options, args) = parser.parse_known_args(argv)
-        self._setup_logging(options.debug)
-        self._setup_verbose(options.verbose)
-
-        # build available subcommands based on version
-        api_version = options.api_version
-        subcommand_parser = self.get_subcommand_parser(api_version)
-        self.parser = subcommand_parser
-
-        # Handle top-level --help/-h before attempting to parse
-        # a command off the command line
-        if not args and options.help or not argv:
-            self.do_help(options)
-            return 0
-
-        # Parse args again and call whatever callback was selected
-        args = subcommand_parser.parse_args(argv)
-
-        # Short-circuit and deal with help command right away.
-        if args.func == self.do_help:
-            self.do_help(args)
-            return 0
-        elif args.func == self.do_bash_completion:
-            self.do_bash_completion(args)
-            return 0
-
-        if (not args.os_username and not args.os_token and
-                not args.os_no_client_auth):
-            raise exc.CommandError(
-                _("You must provide a username via either "
-                  "--os-username or env[OS_USERNAME] "
-                  "or a token via --os-token or "
-                  "env[OS_TOKEN]"))
-
-        if (not args.os_password and not args.os_token and
-                not args.os_no_client_auth):
-            raise exc.CommandError(
-                _("You must provide a password via either "
-                  "--os-password or env[OS_PASSWORD] "
-                  "or a token via --os-token or "
-                  "env[OS_TOKEN]"))
-
-        if args.os_no_client_auth:
-            if not args.bypass_url:
-                raise exc.CommandError(
-                    _("If you specify --os-no-client-auth "
-                      "you must also specify a Stacktask API "
-                      "URL via either --bypass-url or "
-                      "env[STACKTASK_BYPASS_URL]"))
-        else:
-            # Tenant/project name or ID is needed to make keystoneclient
-            # retrieve a service catalog, it's not required if
-            # os_no_client_auth is specified, neither is the auth URL
-
-            if not (args.os_tenant_id or args.os_tenant_name or
-                    args.os_project_id or args.os_project_name):
-                raise exc.CommandError(
-                    _("You must provide a tenant id via either "
-                      "--os-tenant-id or env[OS_TENANT_ID] or a tenant name "
-                      "via either --os-tenant-name or env[OS_TENANT_NAME] "
-                      "or a project id via either --os-project-id or "
-                      "env[OS_PROJECT_ID] or a project name via "
-                      "either --os-project-name or env[OS_PROJECT_NAME]"))
-
-            if not args.os_auth_url:
-                raise exc.CommandError(
-                    _("You must provide an auth url via "
-                      "either --os-auth-url or via "
-                      "env[OS_AUTH_URL]"))
-        kwargs = {
-            'insecure': args.insecure,
-            'cacert': args.os_cacert,
-            'cert': args.os_cert,
-            'key': args.os_key,
-            'timeout': args.api_timeout
-        }
-
-        endpoint = args.bypass_url
-        service_type = args.os_service_type or 'registration'
-        if args.os_no_client_auth:
-            # Do not use session since no_client_auth means using heat to
-            # to authenticate
-            kwargs = {
-                'username': args.os_username,
-                'password': args.os_password,
-                'auth_url': args.os_auth_url,
-                'token': args.os_token,
-                'include_pass': None,  # args.include_password,
-                'insecure': args.insecure,
-                'timeout': args.api_timeout
-            }
-        else:
-            keystone_session = self._get_keystone_session(**kwargs)
-            endpoint_type = args.os_endpoint_type or 'publicURL'
-            if args.os_token:
-                kwargs = {
-                    'token': args.os_token,
-                    'auth_url': args.os_auth_url
-                }
-                keystone_auth = generic.Token(**kwargs)
-            else:
-                project_id = args.os_project_id or args.os_tenant_id
-                project_name = args.os_project_name or args.os_tenant_name
-                kwargs = {
-                    'username': args.os_username,
-                    'user_id': args.os_user_id,
-                    'user_domain_id': args.os_user_domain_id,
-                    'user_domain_name': args.os_user_domain_name,
-                    'password': args.os_password,
-                    'auth_url': args.os_auth_url,
-                    'project_id': project_id,
-                    'project_name': project_name,
-                    'project_domain_id': args.os_project_domain_id,
-                    'project_domain_name': args.os_project_domain_name,
-                }
-                keystone_auth = generic.Password(**kwargs)
-            if not endpoint:
-                svc_type = service_type
-                region_name = args.os_region_name
-                endpoint = keystone_auth.get_endpoint(keystone_session,
-                                                      service_type=svc_type,
-                                                      interface=endpoint_type,
-                                                      region_name=region_name)
-            kwargs = {
-                'auth_url': args.os_auth_url,
-                'session': keystone_session,
-                'auth': keystone_auth,
-                'service_type': service_type,
-                'endpoint_type': endpoint_type,
-                'region_name': args.os_region_name,
-                'username': args.os_username,
-                'password': args.os_password,
-                'include_pass': None  # args.include_password
-            }
-
-        client = stacktask_client.Client(api_version, endpoint, **kwargs)
-
-        profile = osprofiler_profiler and options.profile
-        if profile:
-            osprofiler_profiler.init(options.profile)
-
-        args.func(client, args)
-
-        if profile:
-            trace_id = osprofiler_profiler.get().get_base_id()
-            print(_("Trace ID: %s") % trace_id)
-            print(_("To display trace use next command:\n"
-                  "osprofiler trace show --html %s ") % trace_id)
-
-    def do_bash_completion(self, args):
-        """Prints all of the commands and options to stdout.
-
-        The heat.bash_completion script doesn't have to hard code them.
-        """
-        commands = set()
-        options = set()
-        for sc_str, sc in self.subcommands.items():
-            commands.add(sc_str)
-            for option in list(sc._optionals._option_string_actions):
-                options.add(option)
-
-        commands.remove('bash-completion')
-        commands.remove('bash_completion')
-        print(' '.join(commands | options))
-
-    @utils.arg('command', metavar='<subcommand>', nargs='?',
-               help=_('Display help for <subcommand>.'))
-    def do_help(self, args):
-        """Display help about this program or one of its subcommands."""
-        if getattr(args, 'command', None):
-            if args.command in self.subcommands:
-                self.subcommands[args.command].print_help()
-            else:
-                raise exc.CommandError("'%s' is not a valid subcommand" %
-                                       args.command)
-        else:
-            self.parser.print_help()
-
-
-class HelpFormatter(argparse.HelpFormatter):
-    def start_section(self, heading):
-        # Title-case the headings
-        heading = '%s%s' % (heading[0].upper(), heading[1:])
-        super(HelpFormatter, self).start_section(heading)
-
-
-def main(args=None):
-    try:
-        if args is None:
-            args = sys.argv[1:]
-
-        StacktaskShell().main(args)
-    except KeyboardInterrupt:
-        print(_("... terminating stacktask client"), file=sys.stderr)
-        sys.exit(130)
-    except Exception as e:
-        if '--debug' in args or '-d' in args:
-            raise
-        else:
-            print(encodeutils.safe_encode(six.text_type(e)), file=sys.stderr)
-        sys.exit(1)
-
-if __name__ == "__main__":
-    main()
diff --git a/stacktaskclient/v1/build_info.py b/stacktaskclient/v1/build_info.py
deleted file mode 100644
index 75c6b61..0000000
--- a/stacktaskclient/v1/build_info.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# 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.
-
-from stacktaskclient.common import utils
-from stacktaskclient.openstack.common.apiclient import base
-
-
-class BuildInfo(base.Resource):
-    def __repr__(self):
-        return "<BuildInfo %s>" % self._info
-
-    def build_info(self):
-        return self.manager.build_info()
-
-
-class BuildInfoManager(base.BaseManager):
-    resource_class = BuildInfo
-
-    def build_info(self):
-        resp = self.client.get('/build_info')
-        body = utils.get_response_body(resp)
-        return body
diff --git a/stacktaskclient/v1/shell.py b/stacktaskclient/v1/shell.py
deleted file mode 100644
index c4461af..0000000
--- a/stacktaskclient/v1/shell.py
+++ /dev/null
@@ -1,525 +0,0 @@
-# Copyright (C) 2016 Catalyst IT Ltd
-#
-#    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 logging
-
-import json
-from stacktaskclient.common import utils
-from stacktaskclient.common import http
-
-from stacktaskclient.openstack.common._i18n import _
-
-import stacktaskclient.exc as exc
-
-logger = logging.getLogger(__name__)
-
-
-def _authenticated_fetcher(sc):
-    """
-    A wrapper around the stacktask client object to fetch a template.
-    """
-    def _do(*args, **kwargs):
-        if isinstance(sc.http_client, http.SessionClient):
-            method, url = args
-            return sc.http_client.request(url, method, **kwargs).content
-        else:
-            return sc.http_client.raw_request(*args, **kwargs).content
-
-    return _do
-
-
-def show_deprecated(deprecated, recommended):
-    logger.warning('"%(old)s" is deprecated, '
-                   'please use "%(new)s" instead',
-                   {'old': deprecated,
-                    'new': recommended}
-                   )
-
-
-# Tasks
-
-@utils.arg('task_id', metavar='<taskid>',
-           help=_('Task ID.'))
-def do_task_show(sc, args):
-    """
-    Get individual task.
-    """
-    show_deprecated('stacktask task-show', 'openstack admin task show')
-
-    try:
-        task = sc.tasks.get(task_id=args.task_id)
-
-        formatters = {
-            'actions': utils.json_formatter,
-            'action_notes': utils.json_formatter,
-            'keystone_user': utils.json_formatter,
-            'approved_by': utils.json_formatter
-        }
-        utils.print_dict(task.to_dict(), formatters=formatters)
-    except exc.HTTPNotFound:
-        raise exc.CommandError(_('Task not found: %s') %
-                               args.task_id)
-    except exc.HTTPBadRequest as e:
-        print e.message
-
-
-@utils.arg('--filters', default={},
-           help=_('Filters to use when getting the list.'))
-def do_task_list(sc, args):
-    """
-    Show all tasks in the current project
-    """
-    show_deprecated('stacktask task-list', 'openstack admin task list')
-    fields = [
-        'uuid', 'task_type', 'created_on',
-        'approved_on', 'completed_on', 'cancelled']
-    tasks_list = sc.tasks.list(filters=args.filters)
-    utils.print_list(tasks_list, fields)
-
-
-@utils.arg('task_id', metavar='<taskid>',
-           help=_('Task ID.'))
-@utils.arg('--data', required=True,
-           help=_('New data to update the Task with.'))
-def do_task_update(sc, args):
-    """
-    Update a task with new data and rerun pre-approve validation.
-    """
-    show_deprecated('stacktask task-update', 'openstack admin task update')
-    try:
-        resp = sc.tasks.update(args.task_id, args.data)
-    except exc.HTTPNotFound as e:
-        print e.message
-    except exc.HTTPBadRequest as e:
-        print e.message
-    else:
-        print 'Success:', ' '.join(resp.notes)
-        do_task_show(sc, args)
-
-
-@utils.arg('task_id', metavar='<taskid>',
-           help=_('Task ID.'))
-def do_task_approve(sc, args):
-    """
-    Approve a task.
-
-    If already approved will rerun post-approve validation
-    and resend token.
-    """
-    show_deprecated('stacktask task-approve', 'openstack admin task approve')
-    try:
-        resp = sc.tasks.approve(args.task_id)
-    except exc.HTTPNotFound as e:
-        print e.message
-    except exc.HTTPBadRequest as e:
-        print e.message
-    else:
-        print 'Success:', ' '.join(resp.notes)
-        do_task_show(sc, args)
-
-
-@utils.arg('task_id', metavar='<taskid>',
-           help=_('Task ID.'))
-def do_task_reissue_token(sc, args):
-    """
-    Re-issues the token for the provided pending task.
-    """
-    show_deprecated('stacktask task-reissue-token',
-                    'openstack admin task token reissue')
-    try:
-        resp = sc.tokens.reissue(task_id=args.task_id)
-    except exc.HTTPNotFound as e:
-        print e.message
-    except exc.HTTPBadRequest as e:
-        print e.message
-    else:
-        print 'Success:', ' '.join(resp.notes)
-        do_task_show(sc, args)
-
-
-@utils.arg('task_id', metavar='<taskid>',
-           help=_('Task ID.'))
-def do_task_cancel(sc, args):
-    """
-    Canel the task.
-    """
-    show_deprecated('stacktask task-approve', 'openstack admin task cancel')
-    try:
-        resp = sc.tasks.cancel(args.task_id)
-    except exc.HTTPNotFound as e:
-        print e.message
-    except exc.HTTPBadRequest as e:
-        print e.message
-    else:
-        print 'Success: %s' % resp.json()['notes']
-        do_task_show(sc, args)
-
-
-# Notifications
-
-@utils.arg('note_id', metavar='<noteid>',
-           help=_('Notification ID.'))
-def do_notification_show(sc, args):
-    """
-    Get individual notification.
-    """
-    show_deprecated('stacktask notification-show',
-                    'openstack admin task notification show')
-
-    try:
-        notification = sc.notifications.get(note_id=args.note_id)
-
-        formatters = {
-            'notes': utils.json_formatter
-        }
-        utils.print_dict(notification.to_dict(), formatters=formatters)
-    except exc.HTTPNotFound:
-        raise exc.CommandError(_('Notification not found: %s') %
-                               args.note_id)
-    except exc.HTTPBadRequest as e:
-        print e.message
-
-
-@utils.arg('--filters', default={},
-           help=_('Filters to use when getting the list.'))
-def do_notification_list(sc, args):
-    """
-    Show all notification.
-
-    This is an admin only endpoint.
-    """
-    show_deprecated('stacktask notification-list',
-                    'openstack admin task notificaion list')
-
-    fields = ['uuid', 'task', 'acknowledged', 'created_on']
-    notification_list = sc.notifications.list(filters=args.filters)
-    utils.print_list(notification_list, fields)
-
-
-@utils.arg('note_ids', metavar='<noteids>', nargs='+',
-           help=_('Notification IDs to acknowledge.'))
-def do_notification_acknowledge(sc, args):
-    """
-    Acknowledge notification.
-    """
-    show_deprecated('stacktask notification-acknowledge',
-                    'openstack admin task notification acknowledge')
-
-    try:
-        resp = sc.notifications.acknowledge(note_list=args.note_ids)
-
-        print 'Success:', ' '.join(resp.notes)
-    except exc.HTTPNotFound:
-        raise exc.CommandError(_('Notification not found: %s') %
-                               args.note_id)
-    except exc.HTTPBadRequest as e:
-        print e.message
-
-
-# Tokens
-
-@utils.arg('--filters', default={},
-           help=_('Filters to use when getting the list.'))
-def do_token_list(sc, args):
-    """
-    Show all tokens.
-
-    This is an admin only endpoint.
-    """
-    show_deprecated('stacktask token-list',
-                    'openstack admin task token list')
-    fields = ['token', 'task', 'created_on', 'expires']
-    token_list = sc.tokens.list(filters=args.filters)
-    utils.print_list(token_list, fields)
-
-
-@utils.arg('token', metavar='<token>',
-           help=_('Token id of the task'))
-def do_token_show(sc, args):
-    """
-    Show details of this token
-    including the arguments required for submit
-    """
-    show_deprecated('stacktask token-show',
-                    'openstack admin task token show')
-    try:
-        token = sc.tokens.get(args.token)
-    except exc.HTTPNotFound as e:
-        print e.message
-        print "Requested Token was not found."
-    else:
-        utils.print_dict(token.to_dict())
-
-
-@utils.arg('token', metavar='<token>',
-           help=_('Token id of the task'))
-@utils.arg('--password', metavar='<password>', required=True,
-           help=_('Password of the new user.'))
-def do_token_submit_password(sc, args):
-    """
-    Submit this token to set or update your password.
-    """
-    show_deprecated('stacktask token-submit-password',
-                    'openstack admin task token submit')
-    json_data = {'password': args.password}
-    _token_submit(sc, args, json_data)
-
-
-@utils.arg('token', metavar='<token>',
-           help=_('Token id of the task'))
-@utils.arg('--data', metavar='<data>', required=True,
-           help=_('Json with the data to submit.'))
-def do_token_submit(sc, args):
-    """
-    Submit this token to finalise Task.
-    """
-    show_deprecated('stacktask token-submit',
-                    'openstack admin task token submit')
-    try:
-        json_data = json.loads(args.data)
-    except ValueError as e:
-        print e.message
-        print "Json data invalid."
-        return
-    _token_submit(sc, args, json_data)
-
-
-def _token_submit(sc, args, json_data):
-    try:
-        sc.tokens.submit(args.token, json_data)
-    except exc.HTTPNotFound as e:
-        print e.message
-        print "Requested token was not found."
-    except exc.BadRequest as e:
-        print e.message
-        print "Bad request. Did you omit a required parameter?"
-    else:
-        print "Token submitted."
-
-
-def do_token_clear_expired(sc, args):
-    """
-    Clear all expired tokens.
-
-    This is an admin only endpoint.
-    """
-    show_deprecated('stacktask token-clear-expired',
-                    'openstack admin task token clear')
-    try:
-        resp = sc.tokens.clear_expired()
-    except exc.HTTPNotFound as e:
-        print e.message
-    except exc.HTTPBadRequest as e:
-        print e.message
-    else:
-        print 'Success: %s' % resp.json()['notes']
-        fields = ['token', 'task', 'created_on', 'expires']
-        token_list = sc.tokens.list({})
-        utils.print_list(token_list, fields)
-
-
-# User
-
-@utils.arg('user_id', metavar='<userid>',
-           help=_('User id.'))
-def do_user_show(sc, args):
-    """
-    Show user details.
-    """
-    show_deprecated('stacktask user-show', 'openstack project user show')
-
-    try:
-        user = sc.users.get(args.user_id)
-    except exc.HTTPNotFound as e:
-        print e.message
-        print "Requested User was not found."
-    else:
-        utils.print_dict(user.to_dict())
-
-
-def do_user_list(sc, args):
-    """List all users in project"""
-    show_deprecated('stacktask user-list', 'openstack project user list')
-
-    kwargs = {}
-    fields = ['id', 'email', 'name', 'roles', 'cohort', 'status']
-
-    project_users = sc.users.list(**kwargs)
-    utils.print_list(project_users, fields, sortby_index=1)
-
-
-@utils.arg('--roles', metavar='<roles>', nargs='+', required=True,
-           help=_('Roles to grant to new user'))
-@utils.arg('--username', metavar='<username>', default=None,
-           help=_('username of user to invite'))
-@utils.arg('--email', metavar='<email>', required=True,
-           help=_('Email address of user to invite'))
-def do_user_invite(sc, args):
-    """
-    Invites a user to become a member of a project.
-    User does not need to have an existing openstack account.
-    """
-    show_deprecated('stacktask user-invite', 'openstack project user invite')
-
-    roles = args.roles or ['Member']
-
-    try:
-        sc.users.invite(
-            username=args.username, email=args.email, role_list=roles)
-    except exc.HTTPNotFound as e:
-        print e.message
-        print e
-    except exc.HTTPBadRequest as e:
-        print "400 Bad Request: " + e.message
-        print e
-    else:
-        print "Invitation sent."
-        do_user_list(sc, args)
-
-
-@utils.arg('user_id', metavar='<userid>',
-           help=_('User id for unconfirmed user.'))
-def do_user_invite_cancel(sc, args):
-    """ Cancel user invitation. """
-    show_deprecated('stacktask user-invite-cancel',
-                    'openstack project user invite cancel')
-    try:
-        resp = sc.users.cancel(args.user_id)
-        print 'Success: %s' % resp.json()
-    except exc.HTTPNotFound as e:
-        print e.message
-        print "Requested User was not found."
-
-
-@utils.arg('--user', '--user-id', metavar='<user>', required=True,
-           help=_('Name or ID of user.'))
-def do_user_role_list(sc, args):
-    """ List the current roles of a user"""
-    show_deprecated('stacktask user-role-list',
-                    'openstack project user role list')
-    fields = ['id', 'name']
-    user = utils.find_resource(sc.users, args.user)
-    kwargs = {'user': user.id}
-    roles = sc.user_roles.list(**kwargs)
-    utils.print_list(roles, fields, sortby_index=0)
-
-
-@utils.arg('--user', '--user-id', metavar='<user>', required=True,
-           help=_('Name or ID of user.'))
-@utils.arg('--role', '--role-id', metavar='<role>', required=True,
-           help=_('Name or ID of role.'))
-def do_user_role_add(sc, args):
-    """Add a role to user"""
-    show_deprecated('stacktask user-role-add',
-                    'openstack project user role add')
-
-    role = utils.find_resource(sc.managed_roles, args.role)
-    user = utils.find_resource(sc.users, args.user)
-    if sc.user_roles.add(user.id, role=role.name):
-        print "Task has been sucessfully completed.\n"
-        do_user_list(sc, args)
-    else:
-        print "Your task was not sucessfully completed."
-
-
-@utils.arg('--user', '--user-id', metavar='<user>',
-           help=_('Name or ID of user.'))
-@utils.arg('--role', '--role-id', metavar='<role>', required=True,
-           help=_('Name or ID of role.'))
-def do_user_role_remove(sc, args):
-    """Remove a role from a user"""
-    show_deprecated('stacktask user-role-remove',
-                    'openstack project user role remove')
-
-    role = utils.find_resource(sc.managed_roles, args.role)
-    user = utils.find_resource(sc.users, args.user)
-    if sc.user_roles.remove(user.id, role=role.name):
-        print "Task has been sucessfully completed.\n"
-        do_user_list(sc, args)
-    else:
-        print "Your task was not sucessfully completed."
-
-
-@utils.arg('email', metavar='<email>',
-           help=_('email of the user account to reset'))
-def do_user_password_forgot(sc, args):
-    show_deprecated('stacktask user-password-forgot',
-                    'openstack password forgot')
-
-    """Request a password reset email for a user."""
-    sc.users.password_forgot(args.email)
-    print "Task has been sucessfully submitted."
-    print "If a user with that email exists, a reset token will be issued."
-
-
-@utils.arg('email', metavar='<email>',
-           help=_('email of the user account to reset'))
-def do_user_password_reset(sc, args):
-    show_deprecated('stacktask user-password-reset',
-                    'openstack password-reset')
-
-    """Force a password reset for a user. This is an admin only function."""
-    sc.users.password_force_reset(args.email)
-    print "Task has been sucessfully submitted."
-    print "If a user with that email exists, a reset token will be issued."
-
-
-def do_managed_role_list(sc, args):
-    """List roles that may be managed in a given project"""
-    show_deprecated('stacktask managed-role-list',
-                    'openstack project manageable roles')
-
-    fields = ['id', 'name']
-    kwargs = {}
-    roles = sc.managed_roles.list(**kwargs)
-    utils.print_list(roles, fields, sortby_index=1)
-
-
-# Status
-
-def do_status(sc, args):
-    """Requests server status endpoint and returns details of the api server"""
-    show_deprecated('stacktask status', 'openstack stacktask status')
-
-    status = sc.status.get()
-    if status.status_code != 200:
-        print "Failed: %s" % status.reason
-        return
-    print json.dumps(
-        status.json(), sort_keys=True,
-        indent=4, separators=(',', ': '))
-
-
-# Sign-up
-@utils.arg('user', metavar='<user>',
-           help=_('User name for new account.'))
-@utils.arg('email', metavar='<email>',
-           help=_('email of the new account'))
-@utils.arg('project_name', metavar='<project_name>',
-           help=_('name of the new project'))
-def do_sign_up(sc, args):
-    """Submits a sign-up from a user requesting a new project and account.
-
-    Note: You can perform an unauthenticated request to this endpoint using
-    --os-no-client-auth and --bypass-url <stacktask url>
-    """
-    show_deprecated('stacktask sign-up', 'openstack signup')
-
-    status = sc.signup.post(args.user, args.email, args.project_name)
-    if status.status_code != 200:
-        print "Failed: %s" % status.reason
-        return
-    print json.dumps(
-        status.json(), sort_keys=True,
-        indent=4, separators=(',', ': '))