Merge "Change v3 identity client methods to return one value"
diff --git a/doc/source/index.rst b/doc/source/index.rst
index bc4fc46..1f06bc5 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -37,6 +37,7 @@
    :maxdepth: 1
 
    cleanup
+   javelin
 
 ==================
 Indices and tables
diff --git a/doc/source/javelin.rst b/doc/source/javelin.rst
new file mode 100644
index 0000000..01090ca
--- /dev/null
+++ b/doc/source/javelin.rst
@@ -0,0 +1,5 @@
+----------------------------------------------------------
+Javelin2 - How to check that resources survived an upgrade
+----------------------------------------------------------
+
+.. automodule:: tempest.cmd.javelin
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 441e17c..a9778e3 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -256,9 +256,6 @@
 # Catalog type of the Compute service. (string value)
 #catalog_type = compute
 
-# Catalog type of the Compute v3 service. (string value)
-#catalog_v3_type = computev3
-
 # The endpoint type to use for the compute service. (string value)
 #endpoint_type = publicURL
 
@@ -363,27 +360,6 @@
 #volume_device_name = vdb
 
 
-[compute-admin]
-
-#
-# From tempest.config
-#
-
-# Domain name for authentication as admin (Keystone V3).The same
-# domain applies to user and project (string value)
-#domain_name = <None>
-
-# API key to use when authenticating as admin. (string value)
-#password = <None>
-
-# Administrative Tenant name to use for Nova API requests. (string
-# value)
-#tenant_name = <None>
-
-# Administrative Username to use for Nova API requests. (string value)
-#username = <None>
-
-
 [compute-feature-enabled]
 
 #
@@ -396,15 +372,6 @@
 # disabled (list value)
 #api_extensions = all
 
-# If false, skip all nova v3 tests. (boolean value)
-#api_v3 = false
-
-# A list of enabled v3 extensions with a special entry all which
-# indicates every extension is enabled. Each extension should be
-# specified with alias name. Empty list indicates all extensions are
-# disabled (list value)
-#api_v3_extensions = all
-
 # Does the test environment block migration support cinder iSCSI
 # volumes (boolean value)
 #block_migrate_cinder_iscsi = false
@@ -750,7 +717,7 @@
 # Catalog type of the Neutron service. (string value)
 #catalog_type = network
 
-# List of dns servers whichs hould be used for subnet creation (list
+# List of dns servers which should be used for subnet creation (list
 # value)
 #dns_servers = 8.8.8.8,8.8.4.4
 
diff --git a/requirements.txt b/requirements.txt
index f9d8036..a6e7dd1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,7 +10,7 @@
 paramiko>=1.13.0
 netaddr>=0.7.12
 python-ceilometerclient>=1.0.6
-python-glanceclient>=0.14.0
+python-glanceclient>=0.15.0
 python-keystoneclient>=0.11.1
 python-novaclient>=2.18.0
 python-neutronclient>=2.3.6,<3
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index de5b6c1..c6d48bc 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -36,6 +36,8 @@
         personality = []
         max_file_limit = \
             self.user_client.get_specific_absolute_limit("maxPersonality")
+        if max_file_limit == -1:
+            raise self.skipException("No limit for personality files")
         for i in range(0, int(max_file_limit) + 1):
             path = 'etc/test' + str(i) + '.txt'
             personality.append({'path': path,
@@ -52,6 +54,8 @@
         file_contents = 'This is a test file.'
         max_file_limit = \
             self.user_client.get_specific_absolute_limit("maxPersonality")
+        if max_file_limit == -1:
+            raise self.skipException("No limit for personality files")
         person = []
         for i in range(0, int(max_file_limit)):
             path = 'etc/test' + str(i) + '.txt'
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 38a623a..bc45da5 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -232,99 +232,6 @@
         self.assertFalse(self.created_set - self.dup_set <= result_set)
 
 
-class ListSnapshotImagesTest(base.BaseV1ImageTest):
-    @classmethod
-    def resource_setup(cls):
-        # This test class only uses nova v3 api to create snapshot
-        # as the similar test which uses nova v2 api already exists
-        # in nova v2 compute images api tests.
-        # Since nova v3 doesn't have images api proxy, this test
-        # class was added in the image api tests.
-        if not CONF.compute_feature_enabled.api_v3:
-            skip_msg = ("%s skipped as nova v3 api is not available" %
-                        cls.__name__)
-            raise cls.skipException(skip_msg)
-        super(ListSnapshotImagesTest, cls).resource_setup()
-        cls.servers_client = cls.os.servers_v3_client
-        cls.servers = []
-        # We add a few images here to test the listing functionality of
-        # the images API
-        cls.snapshot = cls._create_snapshot(
-            'snapshot', CONF.compute.image_ref,
-            CONF.compute.flavor_ref)
-        cls.snapshot_set = set((cls.snapshot,))
-
-        image_file = StringIO.StringIO('*' * 42)
-        _, image = cls.create_image(name="Standard Image",
-                                    container_format='ami',
-                                    disk_format='ami',
-                                    is_public=False, data=image_file)
-        cls.image_id = image['id']
-        cls.client.wait_for_image_status(image['id'], 'active')
-
-    @classmethod
-    def resource_cleanup(cls):
-        for server in getattr(cls, "servers", []):
-            cls.servers_client.delete_server(server['id'])
-        super(ListSnapshotImagesTest, cls).resource_cleanup()
-
-    @classmethod
-    def _create_snapshot(cls, name, image_id, flavor, **kwargs):
-        _, server = cls.servers_client.create_server(
-            name, image_id, flavor, **kwargs)
-        cls.servers.append(server)
-        cls.servers_client.wait_for_server_status(
-            server['id'], 'ACTIVE')
-        resp, _ = cls.servers_client.create_image(server['id'], name)
-        image_id = data_utils.parse_image_id(resp['location'])
-        cls.created_images.append(image_id)
-        cls.client.wait_for_image_status(image_id,
-                                         'active')
-        return image_id
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_server_id(self):
-        # The images should contain images filtered by server id
-        _, images = self.client.image_list_detail(
-            {'instance_uuid': self.servers[0]['id']})
-        result_set = set(map(lambda x: x['id'], images))
-        self.assertEqual(self.snapshot_set, result_set)
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_type(self):
-        # The list of servers should be filtered by image type
-        params = {'image_type': 'snapshot'}
-        _, images = self.client.image_list_detail(params)
-
-        result_set = set(map(lambda x: x['id'], images))
-        self.assertIn(self.snapshot, result_set)
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_limit(self):
-        # Verify only the expected number of results are returned
-        _, images = self.client.image_list_detail(limit=1)
-
-        self.assertEqual(1, len(images))
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_by_change_since(self):
-        # Verify an update image is returned
-        # Becoming ACTIVE will modify the updated time
-        # Filter by the image's created time
-        _, image = self.client.get_image_meta(self.snapshot)
-        self.assertEqual(self.snapshot, image['id'])
-        _, images = self.client.image_list_detail(
-            changes_since=image['updated_at'])
-
-        result_set = set(map(lambda x: x['id'], images))
-        self.assertIn(self.image_id, result_set)
-        self.assertNotIn(self.snapshot, result_set)
-
-
 class UpdateImageMetaTest(base.BaseV1ImageTest):
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 12b2d13..10cda53 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -396,8 +396,11 @@
         body = cls.client.list_router_interfaces(router['id'])
         interfaces = body['ports']
         for i in interfaces:
-            cls.client.remove_router_interface_with_subnet_id(
-                router['id'], i['fixed_ips'][0]['subnet_id'])
+            try:
+                cls.client.remove_router_interface_with_subnet_id(
+                    router['id'], i['fixed_ips'][0]['subnet_id'])
+            except exceptions.NotFound:
+                pass
         cls.client.delete_router(router['id'])
 
     @classmethod
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 5643c88..6ce1216 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -25,7 +25,6 @@
 
 
 class NetworksTestDHCPv6(base.BaseNetworkTest):
-    _interface = 'json'
     _ip_version = 6
 
     """ Test DHCPv6 specific features using SLAAC, stateless and
@@ -39,7 +38,7 @@
     """
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
         msg = None
         if not CONF.network_feature_enabled.ipv6:
             msg = "IPv6 is not enabled"
@@ -47,6 +46,9 @@
             msg = "DHCPv6 attributes are not enabled."
         if msg:
             raise cls.skipException(msg)
+
+    @classmethod
+    def resource_setup(cls):
         super(NetworksTestDHCPv6, cls).resource_setup()
         cls.network = cls.create_network()
 
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 1f827da..e70519e 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -66,7 +66,8 @@
         super(NetworksTestJSON, cls).resource_setup()
         cls.network = cls.create_network()
         cls.name = cls.network['name']
-        cls.subnet = cls.create_subnet(cls.network)
+        cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
+                                                               cls._ip_version)
         cls.cidr = cls.subnet['cidr']
         cls._subnet_data = {6: {'gateway':
                                 str(cls._get_gateway_from_tempest_conf(6)),
@@ -96,6 +97,23 @@
                                 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
 
     @classmethod
+    def _create_subnet_with_last_subnet_block(cls, network, ip_version):
+        """Derive last subnet CIDR block from tenant CIDR and
+           create the subnet with that derived CIDR
+        """
+        if ip_version == 4:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            mask_bits = CONF.network.tenant_network_mask_bits
+        elif ip_version == 6:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+            mask_bits = CONF.network.tenant_network_v6_mask_bits
+
+        subnet_cidr = list(cidr.subnet(mask_bits))[-1]
+        gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
+        return cls.create_subnet(network, gateway=gateway_ip,
+                                 cidr=subnet_cidr, mask_bits=mask_bits)
+
+    @classmethod
     def _get_gateway_from_tempest_conf(cls, ip_version):
         """Return first subnet gateway for configured CIDR """
         if ip_version == 4:
@@ -129,6 +147,15 @@
         self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
                         expected, exclude_keys))
 
+    def _delete_network(self, network):
+        # Deleting network also deletes its subnets if exists
+        self.client.delete_network(network['id'])
+        if network in self.networks:
+            self.networks.remove(network)
+        for subnet in self.subnets:
+            if subnet['network_id'] == network['id']:
+                self.subnets.remove(subnet)
+
     def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
                                      **kwargs):
         network = self.create_network()
@@ -156,6 +183,7 @@
         # Create a network
         name = data_utils.rand_name('network-')
         network = self.create_network(network_name=name)
+        self.addCleanup(self._delete_network, network)
         net_id = network['id']
         self.assertEqual('ACTIVE', network['status'])
         # Verify network update
@@ -312,6 +340,7 @@
     @test.attr(type='smoke')
     def test_update_subnet_gw_dns_host_routes_dhcp(self):
         network = self.create_network()
+        self.addCleanup(self._delete_network, network)
 
         subnet = self.create_subnet(
             network, **self.subnet_dict(['gateway', 'host_routes',
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 80097db..7ab5ebd 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -221,13 +221,17 @@
 
     @test.attr(type='smoke')
     def test_create_port_with_no_securitygroups(self):
-        port = self.create_port(self.create_network(), security_groups=[])
+        network = self.create_network()
+        self.create_subnet(network)
+        port = self.create_port(network, security_groups=[])
         self.assertIsNotNone(port['security_groups'])
         self.assertEmpty(port['security_groups'])
 
     @test.attr(type='smoke')
     def test_update_port_with_no_securitygroups(self):
-        port = self.create_port(self.create_network())
+        network = self.create_network()
+        self.create_subnet(network)
+        port = self.create_port(network)
         # Verify that port is created with default security group
         self.assertIsNotNone(port['security_groups'])
         self.assertNotEmpty(port['security_groups'])
diff --git a/tempest/auth.py b/tempest/auth.py
index 2550cfb..9687905 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -499,7 +499,6 @@
     ATTRIBUTES = []
     TYPES = {
         'identity_admin': ('identity', 'admin'),
-        'compute_admin': ('compute_admin', None),
         'user': ('identity', None),
         'alt_user': ('identity', 'alt')
     }
diff --git a/tempest/clients.py b/tempest/clients.py
index 261b27c..99339c1 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -158,8 +158,7 @@
             self.telemetry_client = TelemetryClientJSON(
                 self.auth_provider)
         self.negative_client = rest_client.NegativeRestClient(
-            self.auth_provider)
-        self.negative_client.service = service
+            self.auth_provider, service)
 
         # TODO(andreaf) EC2 client still do their auth, v2 only
         ec2_client_args = (self.credentials.username,
@@ -289,18 +288,3 @@
             credentials=auth.get_default_credentials('identity_admin'),
             interface=interface,
             service=service)
-
-
-class ComputeAdminManager(Manager):
-
-    """
-    Manager object that uses the compute_admin credentials for its
-    managed client objects
-    """
-
-    def __init__(self, interface='json', service=None):
-        base = super(ComputeAdminManager, self)
-        base.__init__(
-            credentials=auth.get_default_credentials('compute_admin'),
-            interface=interface,
-            service=service)
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index f36ef56..28f0aa8 100755
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -19,18 +19,18 @@
 Runtime Arguments
 -----------------
 
---init-saved-state: Before you can execute cleanup you must initialize
-the saved state by running it with the --init-saved-state flag
+**--init-saved-state**: Before you can execute cleanup you must initialize
+the saved state by running it with the **--init-saved-state** flag
 (creating ./saved_state.json), which protects your deployment from
 cleanup deleting objects you want to keep.  Typically you would run
-cleanup with --init-saved-state prior to a tempest run. If this is not
+cleanup with **--init-saved-state** prior to a tempest run. If this is not
 the case saved_state.json must be edited, removing objects you want
 cleanup to delete.
 
---dry-run: Creates a report (dry_run.json) of the tenants that will be
+**--dry-run**: Creates a report (dry_run.json) of the tenants that will be
 cleaned up (in the "_tenants_to_clean" array), and the global objects
 that will be removed (tenants, users, flavors and images).  Once
-cleanup is executed in normal mode, running it again with --dry-run
+cleanup is executed in normal mode, running it again with **--dry-run**
 should yield an empty report.
 
 **NOTE**: The _tenants_to_clean array in dry-run.json lists the
@@ -38,17 +38,17 @@
 delete the tenant itself. This may differ from the tenants array as you
 can clean the tempest and alternate tempest tenants but by default,
 cleanup deletes the objects in the tempest and alternate tempest tenants
-but does not delete those tenants unless the --delete-tempest-conf-objects
+but does not delete those tenants unless the **--delete-tempest-conf-objects**
 flag is used to force their deletion.
 
 **Normal mode**: running with no arguments, will query your deployment and
 build a list of objects to delete after filtering out the objects found in
-saved_state.json and based on the --delete-tempest-conf-objects flag.
+saved_state.json and based on the **--delete-tempest-conf-objects** flag.
 
 By default the tempest and alternate tempest users and tenants are not
 deleted and the admin user specified in tempest.conf is never deleted.
 
-Please run with --help to see full list of options.
+Please run with **--help** to see full list of options.
 """
 import argparse
 import json
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 97aa62b..c7ec359 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -12,11 +12,94 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-"""Javelin makes resources that should survive an upgrade.
-
-Javelin is a tool for creating, verifying, and deleting a small set of
+"""Javelin is a tool for creating, verifying, and deleting a small set of
 resources in a declarative way.
 
+Javelin is meant to be used as a way to validate quickly that resources can
+survive an upgrade process.
+
+Authentication
+--------------
+
+Javelin will be creating (and removing) users and tenants so it needs the admin
+credentials of your cloud to operate properly. The corresponding info can be
+given the usual way, either through CLI options or environment variables.
+
+You're probably familiar with these, but just in case::
+
+    +----------+------------------+----------------------+
+    | Param    | CLI              | Environment Variable |
+    +----------+------------------+----------------------+
+    | Username | --os-username    | OS_USERNAME          |
+    | Password | --os-password    | OS_PASSWORD          |
+    | Tenant   | --os-tenant-name | OS_TENANT_NAME       |
+    +----------+------------------+----------------------+
+
+
+Runtime Arguments
+-----------------
+
+**-m/--mode**: (Required) Has to be one of 'check', 'create' or 'destroy'. It
+indicates which actions javelin is going to perform.
+
+**-r/--resources**: (Required) The path to a YAML file describing the resources
+used by Javelin.
+
+**-d/--devstack-base**: (Required) The path to the devstack repo used to
+retrieve artefacts (like images) that will be referenced in the resource files.
+
+**-c/--config-file**: (Optional) The path to a valid Tempest config file
+describing your cloud. Javelin may use this to determine if certain services
+are enabled and modify its behavior accordingly.
+
+
+Resource file
+-------------
+
+The resource file is a valid YAML file describing the resources that will be
+created, checked and destroyed by javelin. Here's a canonical example of a
+resource file::
+
+  tenants:
+    - javelin
+    - discuss
+
+  users:
+    - name: javelin
+      pass: gungnir
+      tenant: javelin
+    - name: javelin2
+      pass: gungnir2
+      tenant: discuss
+
+  # resources that we want to create
+  images:
+    - name: javelin_cirros
+      owner: javelin
+      file: cirros-0.3.2-x86_64-blank.img
+      format: ami
+      aki: cirros-0.3.2-x86_64-vmlinuz
+      ari: cirros-0.3.2-x86_64-initrd
+
+  servers:
+    - name: peltast
+      owner: javelin
+      flavor: m1.small
+      image: javelin_cirros
+    - name: hoplite
+      owner: javelin
+      flavor: m1.medium
+      image: javelin_cirros
+
+
+An important piece of the resource definition is the *owner* field, which is
+the user (that we've created) that is the owner of that resource. All
+operations on that resource will happen as that regular user to ensure that
+admin level access does not mask issues.
+
+The check phase will act like a unit test, using well known assert methods to
+verify that the correct resources exist.
+
 """
 
 import argparse
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index e27fb4a..abf8fc3 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -104,13 +104,6 @@
                             not CONF.identity_feature_enabled.api_v3, update)
 
 
-def verify_nova_api_versions(os, update):
-    versions = _get_api_versions(os, 'nova')
-    if CONF.compute_feature_enabled.api_v3 != ('v3.0' in versions):
-        print_and_or_update('api_v3', 'compute_feature_enabled',
-                            not CONF.compute_feature_enabled.api_v3, update)
-
-
 def verify_cinder_api_versions(os, update):
     # Check cinder api versions
     versions = _get_api_versions(os, 'cinder')
@@ -127,7 +120,6 @@
         'cinder': verify_cinder_api_versions,
         'glance': verify_glance_api_versions,
         'keystone': verify_keystone_api_versions,
-        'nova': verify_nova_api_versions,
     }
     if service not in verify:
         return
@@ -335,7 +327,7 @@
         CONF_PARSER = moves.configparser.SafeConfigParser()
         CONF_PARSER.optionxform = str
         CONF_PARSER.readfp(conf_file)
-    os = clients.ComputeAdminManager(interface='json')
+    os = clients.AdminManager(interface='json')
     services = check_service_availability(os, update)
     results = {}
     for service in ['nova', 'cinder', 'neutron', 'swift']:
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index c54f698..ca87a75 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -78,16 +78,17 @@
 
     LOG = logging.getLogger(__name__)
 
-    def __init__(self, auth_provider):
+    def __init__(self, auth_provider, service, endpoint_type='publicURL',
+                 build_interval=1, build_timeout=60):
         self.auth_provider = auth_provider
+        self.service = service
+        self.endpoint_type = endpoint_type
+        self.build_interval = build_interval
+        self.build_timeout = build_timeout
 
-        self.endpoint_url = None
-        self.service = None
         # The version of the API this client implements
         self.api_version = None
         self._skip_path = False
-        self.build_interval = CONF.compute.build_interval
-        self.build_timeout = CONF.compute.build_timeout
         self.general_header_lc = set(('cache-control', 'connection',
                                       'date', 'pragma', 'trailer',
                                       'transfer-encoding', 'via',
@@ -138,23 +139,6 @@
             service_region = CONF.identity.region
         return service_region
 
-    def _get_endpoint_type(self, service):
-        """
-        Returns the endpoint type for a specific service
-        """
-        # If the client requests a specific endpoint type, then be it
-        if self.endpoint_url:
-            return self.endpoint_url
-        endpoint_type = None
-        for cfgname in dir(CONF._config):
-            # Find all config.FOO.catalog_type and assume FOO is a service.
-            cfg = getattr(CONF, cfgname)
-            catalog_type = getattr(cfg, 'catalog_type', None)
-            if catalog_type == service:
-                endpoint_type = getattr(cfg, 'endpoint_type', 'publicURL')
-                break
-        return endpoint_type
-
     @property
     def user(self):
         return self.auth_provider.credentials.username
@@ -187,7 +171,7 @@
     def filters(self):
         _filters = dict(
             service=self.service,
-            endpoint_type=self._get_endpoint_type(self.service),
+            endpoint_type=self.endpoint_type,
             region=self._get_region(self.service)
         )
         if self.api_version is not None:
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 93f02c9..3066667 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -28,11 +28,7 @@
     """Waits for a server to reach a given status."""
 
     def _get_task_state(body):
-        if client.service == CONF.compute.catalog_v3_type:
-            task_state = body.get("os-extended-status:task_state", None)
-        else:
-            task_state = body.get('OS-EXT-STS:task_state', None)
-        return task_state
+        return body.get('OS-EXT-STS:task_state', None)
 
     # NOTE(afazekas): UNKNOWN status possible on ERROR
     # or in a very early stage.
diff --git a/tempest/config.py b/tempest/config.py
index dbe9bc2..54a4dd1 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -251,9 +251,6 @@
                choices=['public', 'admin', 'internal',
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the compute service."),
-    cfg.StrOpt('catalog_v3_type',
-               default='computev3',
-               help="Catalog type of the Compute v3 service."),
     cfg.StrOpt('path_to_private_key',
                help="Path to a private key file for SSH access to remote "
                     "hosts"),
@@ -280,9 +277,6 @@
                                       title="Enabled Compute Service Features")
 
 ComputeFeaturesGroup = [
-    cfg.BoolOpt('api_v3',
-                default=False,
-                help="If false, skip all nova v3 tests."),
     cfg.BoolOpt('disk_config',
                 default=True,
                 help="If false, skip disk config tests"),
@@ -292,12 +286,6 @@
                      'entry all which indicates every extension is enabled. '
                      'Each extension should be specified with alias name. '
                      'Empty list indicates all extensions are disabled'),
-    cfg.ListOpt('api_v3_extensions',
-                default=['all'],
-                help='A list of enabled v3 extensions with a special entry all'
-                     ' which indicates every extension is enabled. '
-                     'Each extension should be specified with alias name. '
-                     'Empty list indicates all extensions are disabled'),
     cfg.BoolOpt('change_password',
                 default=False,
                 help="Does the test environment support changing the admin "
@@ -362,23 +350,6 @@
 ]
 
 
-compute_admin_group = cfg.OptGroup(name='compute-admin',
-                                   title="Compute Admin Options")
-
-ComputeAdminGroup = [
-    cfg.StrOpt('username',
-               help="Administrative Username to use for Nova API requests."),
-    cfg.StrOpt('tenant_name',
-               help="Administrative Tenant name to use for Nova API "
-                    "requests."),
-    cfg.StrOpt('password',
-               help="API key to use when authenticating as admin.",
-               secret=True),
-    cfg.StrOpt('domain_name',
-               help="Domain name for authentication as admin (Keystone V3)."
-                    "The same domain applies to user and project"),
-]
-
 image_group = cfg.OptGroup(name='image',
                            title="Image Service Options")
 
@@ -469,7 +440,7 @@
                     "checks."),
     cfg.ListOpt('dns_servers',
                 default=["8.8.8.8", "8.8.4.4"],
-                help="List of dns servers whichs hould be used"
+                help="List of dns servers which should be used"
                      " for subnet creation")
 ]
 
@@ -1062,7 +1033,6 @@
     (dashboard_group, DashboardGroup),
     (data_processing_group, DataProcessingGroup),
     (boto_group, BotoGroup),
-    (compute_admin_group, ComputeAdminGroup),
     (stress_group, StressGroup),
     (scenario_group, ScenarioGroup),
     (service_available_group, ServiceAvailableGroup),
@@ -1133,7 +1103,6 @@
         self.dashboard = cfg.CONF.dashboard
         self.data_processing = cfg.CONF.data_processing
         self.boto = cfg.CONF.boto
-        self.compute_admin = cfg.CONF['compute-admin']
         self.stress = cfg.CONF.stress
         self.scenario = cfg.CONF.scenario
         self.service_available = cfg.CONF.service_available
@@ -1142,17 +1111,11 @@
         self.input_scenario = cfg.CONF['input-scenario']
         self.cli = cfg.CONF.cli
         self.negative = cfg.CONF.negative
-        if not self.compute_admin.username:
-            self.compute_admin.username = self.identity.admin_username
-            self.compute_admin.password = self.identity.admin_password
-            self.compute_admin.tenant_name = self.identity.admin_tenant_name
         cfg.CONF.set_default('domain_name', self.identity.admin_domain_name,
                              group='identity')
         cfg.CONF.set_default('alt_domain_name',
                              self.identity.admin_domain_name,
                              group='identity')
-        cfg.CONF.set_default('domain_name', self.identity.admin_domain_name,
-                             group='compute-admin')
 
     def __init__(self, parse_conf=True, config_path=None):
         """Initialize a configuration from a conf directory and conf file."""
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 20b95e4..9cb24b9 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -14,7 +14,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import logging
 import os
 import subprocess
 
@@ -36,13 +35,6 @@
 
 LOG = log.getLogger(__name__)
 
-# NOTE(afazekas): Workaround for the stdout logging
-LOG_nova_client = logging.getLogger('novaclient.client')
-LOG_nova_client.addHandler(log.NullHandler())
-
-LOG_cinder_client = logging.getLogger('cinderclient.client')
-LOG_cinder_client.addHandler(log.NullHandler())
-
 
 class ScenarioTest(tempest.test.BaseTestCase):
     """Base class for scenario tests. Uses tempest own clients. """
@@ -751,9 +743,9 @@
         # The target login is assumed to have been configured for
         # key-based authentication by cloud-init.
         try:
-            for net_name, ip_addresses in server['networks'].iteritems():
+            for net_name, ip_addresses in server['addresses'].iteritems():
                 for ip_address in ip_addresses:
-                    self.check_vm_connectivity(ip_address,
+                    self.check_vm_connectivity(ip_address['addr'],
                                                username,
                                                private_key,
                                                should_connect=should_connect)
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 4933300..4bcf2aa 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -49,8 +49,9 @@
     """
 
     def __init__(self, auth_provider):
-        super(BaremetalClient, self).__init__(auth_provider)
-        self.service = CONF.baremetal.catalog_type
+        super(BaremetalClient, self).__init__(
+            auth_provider, CONF.baremetal.catalog_type,
+            endpoint_type=CONF.baremetal.endpoint_type)
         self.uri_prefix = ''
 
     def serialize(self, object_type, object_dict):
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index 5b76a56..eacd367 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -17,21 +17,14 @@
 
 from tempest.api_schema.response.compute import agents as common_schema
 from tempest.api_schema.response.compute.v2 import agents as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class AgentsClientJSON(rest_client.RestClient):
+class AgentsClientJSON(base.ComputeClient):
     """
     Tests Agents API
     """
 
-    def __init__(self, auth_provider):
-        super(AgentsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
-
     def list_agents(self, params=None):
         """List all agent builds."""
         url = 'os-agents'
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 09927d3..1539259 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -17,18 +17,11 @@
 
 from tempest.api_schema.response.compute import aggregates as schema
 from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class AggregatesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(AggregatesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class AggregatesClientJSON(base.ComputeClient):
 
     def list_aggregates(self):
         """Get aggregate list."""
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 00f8330..b8bda68 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -16,18 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import availability_zone as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class AvailabilityZoneClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(AvailabilityZoneClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.compute.catalog_type
+class AvailabilityZoneClientJSON(base.ComputeClient):
 
     def get_availability_zone_list(self):
         resp, body = self.get('os-availability-zone')
diff --git a/tempest/services/compute/json/base.py b/tempest/services/compute/json/base.py
new file mode 100644
index 0000000..9187cc4
--- /dev/null
+++ b/tempest/services/compute/json/base.py
@@ -0,0 +1,38 @@
+# Copyright 2014 NEC Corporation.  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 tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class ComputeClient(rest_client.RestClient):
+    """
+    Base compute client class
+    """
+
+    def __init__(self, auth_provider,
+                 build_interval=None, build_timeout=None):
+        if build_interval is None:
+            build_interval = CONF.compute.build_interval
+        if build_timeout is None:
+            build_timeout = CONF.compute.build_timeout
+
+        super(ComputeClient, self).__init__(
+            auth_provider,
+            CONF.compute.catalog_type,
+            endpoint_type=CONF.compute.endpoint_type,
+            build_interval=build_interval,
+            build_timeout=build_timeout)
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 356ded2..123f0b9 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import certificates as schema
 from tempest.api_schema.response.compute.v2 import certificates as v2schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class CertificatesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(CertificatesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class CertificatesClientJSON(base.ComputeClient):
 
     def get_certificate(self, id):
         url = "os-certificates/%s" % (id)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index 41d1c4e..69ad7c0 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -16,17 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import extensions as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class ExtensionsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ExtensionsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class ExtensionsClientJSON(base.ComputeClient):
 
     def list_extensions(self):
         url = 'extensions'
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 5903334..8fd24b6 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -16,17 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import fixed_ips as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class FixedIPsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(FixedIPsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class FixedIPsClientJSON(base.ComputeClient):
 
     def get_fixed_ip_details(self, fixed_ip):
         url = "os-fixed-ips/%s" % (fixed_ip)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 8faf8a7..6276d3c 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -21,17 +21,10 @@
 from tempest.api_schema.response.compute import flavors_extra_specs \
     as schema_extra_specs
 from tempest.api_schema.response.compute.v2 import flavors as v2schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class FlavorsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(FlavorsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class FlavorsClientJSON(base.ComputeClient):
 
     def list_flavors(self, params=None):
         url = 'flavors'
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 0ed1720..788b4d2 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -17,17 +17,11 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import floating_ips as schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class FloatingIPsClientJSON(rest_client.RestClient):
-    def __init__(self, auth_provider):
-        super(FloatingIPsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class FloatingIPsClientJSON(base.ComputeClient):
 
     def list_floating_ips(self, params=None):
         """Returns a list of all floating IPs filtered by any parameters."""
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index 8644173..5d306f9 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import hosts as schema
 from tempest.api_schema.response.compute.v2 import hosts as v2_schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class HostsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(HostsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class HostsClientJSON(base.ComputeClient):
 
     def list_hosts(self, params=None):
         """Lists all hosts."""
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 8eacf61..52b50c8 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import hypervisors as common_schema
 from tempest.api_schema.response.compute.v2 import hypervisors as v2schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class HypervisorClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(HypervisorClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class HypervisorClientJSON(base.ComputeClient):
 
     def get_hypervisor_list(self):
         """List hypervisors information."""
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 079a91e..a4cfe57 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -17,21 +17,12 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import images as schema
-from tempest.common import rest_client
 from tempest.common import waiters
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class ImagesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ImagesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
-        self.build_interval = CONF.compute.build_interval
-        self.build_timeout = CONF.compute.build_timeout
+class ImagesClientJSON(base.ComputeClient):
 
     def create_image(self, server_id, name, meta=None):
         """Creates an image of the original server."""
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 4b0362b..f79c3de 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -17,18 +17,10 @@
 
 from tempest.api_schema.response.compute.v2 import instance_usage_audit_logs \
     as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class InstanceUsagesAuditLogClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(InstanceUsagesAuditLogClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.compute.catalog_type
+class InstanceUsagesAuditLogClientJSON(base.ComputeClient):
 
     def list_instance_usage_audit_logs(self):
         url = 'os-instance_usage_audit_log'
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 620ed68..f1e2660 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -19,18 +19,11 @@
 from tempest.api_schema.response.compute import interfaces as common_schema
 from tempest.api_schema.response.compute import servers as servers_schema
 from tempest.api_schema.response.compute.v2 import interfaces as schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class InterfacesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(InterfacesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class InterfacesClientJSON(base.ComputeClient):
 
     def list_interfaces(self, server):
         resp, body = self.get('servers/%s/os-interface' % server)
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 31c42a5..c4406f5 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import keypairs as common_schema
 from tempest.api_schema.response.compute.v2 import keypairs as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class KeyPairsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(KeyPairsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class KeyPairsClientJSON(base.ComputeClient):
 
     def list_keypairs(self):
         resp, body = self.get("os-keypairs")
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 81c602b..66a0649 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -16,17 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import limits as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class LimitsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(LimitsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class LimitsClientJSON(base.ComputeClient):
 
     def get_absolute_limits(self):
         resp, body = self.get("limits")
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index f4abbb2..de183f1 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -16,17 +16,10 @@
 import urllib
 
 from tempest.api_schema.response.compute import migrations as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class MigrationsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(MigrationsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class MigrationsClientJSON(base.ComputeClient):
 
     def list_migrations(self, params=None):
         """Lists all migrations."""
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index 40eb1a6..5a2744d 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -15,17 +15,10 @@
 
 import json
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class NetworksClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(NetworksClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class NetworksClientJSON(base.ComputeClient):
 
     def list_networks(self):
         resp, body = self.get("os-networks")
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index b691529..0fee57a 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -18,17 +18,10 @@
 from tempest.api_schema.response.compute.v2\
     import quota_classes as classes_schema
 from tempest.api_schema.response.compute.v2 import quotas as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class QuotasClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(QuotasClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class QuotasClientJSON(base.ComputeClient):
 
     def get_quota_set(self, tenant_id, user_id=None):
         """List the quota set for a tenant."""
@@ -122,11 +115,7 @@
         return resp, body
 
 
-class QuotaClassesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(QuotaClassesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class QuotaClassesClientJSON(base.ComputeClient):
 
     def get_quota_class_set(self, quota_class_id):
         """List the quota class set for a quota class."""
diff --git a/tempest/services/compute/json/security_group_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
index 7743f9c..efaf329 100644
--- a/tempest/services/compute/json/security_group_default_rules_client.py
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -17,18 +17,10 @@
 
 from tempest.api_schema.response.compute.v2 import \
     security_group_default_rule as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class SecurityGroupDefaultRulesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(SecurityGroupDefaultRulesClientJSON,
-              self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class SecurityGroupDefaultRulesClientJSON(base.ComputeClient):
 
     def create_security_default_group_rule(self, ip_protocol, from_port,
                                            to_port, **kwargs):
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 733a50b..a301a0f 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -17,18 +17,11 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import security_groups as schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class SecurityGroupsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(SecurityGroupsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class SecurityGroupsClientJSON(base.ComputeClient):
 
     def list_security_groups(self, params=None):
         """List all security groups for a user."""
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 4268b1a..400f9a7 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -20,20 +20,15 @@
 
 from tempest.api_schema.response.compute import servers as common_schema
 from tempest.api_schema.response.compute.v2 import servers as schema
-from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
+from tempest.services.compute.json import base
 
 CONF = config.CONF
 
 
-class ServersClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ServersClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.compute.catalog_type
+class ServersClientJSON(base.ComputeClient):
 
     def create_server(self, name, image_ref, flavor_ref, **kwargs):
         """
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index e56263c..8d73c37 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -18,17 +18,10 @@
 import urllib
 
 from tempest.api_schema.response.compute import services as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class ServicesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ServicesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class ServicesClientJSON(base.ComputeClient):
 
     def list_services(self, params=None):
         url = 'os-services'
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index a0b9b4a..eac23bb 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -17,17 +17,10 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import tenant_usages as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class TenantUsagesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(TenantUsagesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class TenantUsagesClientJSON(base.ComputeClient):
 
     def list_tenant_usages(self, params=None):
         url = 'os-simple-tenant-usage'
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index afa6937..69b9bea 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -18,21 +18,20 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import volumes as schema
-from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
+from tempest.services.compute.json import base
 
 CONF = config.CONF
 
 
-class VolumesExtensionsClientJSON(rest_client.RestClient):
+class VolumesExtensionsClientJSON(base.ComputeClient):
 
     def __init__(self, auth_provider):
         super(VolumesExtensionsClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.compute.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
+            auth_provider,
+            build_interval=CONF.volume.build_interval,
+            build_timeout=CONF.volume.build_timeout)
 
     def list_volumes(self, params=None):
         """List all the volumes created."""
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/client.py
index 7acbae7..6004b22 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/client.py
@@ -21,9 +21,11 @@
 
 
 class DataProcessingClient(rest_client.RestClient):
+
     def __init__(self, auth_provider):
-        super(DataProcessingClient, self).__init__(auth_provider)
-        self.service = CONF.data_processing.catalog_type
+        super(DataProcessingClient, self).__init__(
+            auth_provider, CONF.data_processing.catalog_type,
+            endpoint_type=CONF.data_processing.endpoint_type)
 
     def _request_and_check_resp(self, request_func, uri, resp_status):
         """Make a request using specified request_func and check response
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index f276a45..a57b045 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -24,8 +24,8 @@
 class DatabaseFlavorsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(DatabaseFlavorsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.database.catalog_type
+        super(DatabaseFlavorsClientJSON, self).__init__(
+            auth_provider, CONF.database.catalog_type)
 
     def list_db_flavors(self, params=None):
         url = 'flavors'
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index 81c0e6c..911b55d 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -24,9 +24,9 @@
 class DatabaseVersionsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(DatabaseVersionsClientJSON, self).__init__(auth_provider)
+        super(DatabaseVersionsClientJSON, self).__init__(
+            auth_provider, CONF.database.catalog_type)
         self.skip_path()
-        self.service = CONF.database.catalog_type
 
     def list_db_versions(self, params=None):
         """List all versions."""
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 281464c..c91b63e 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -22,9 +22,9 @@
 class IdentityClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(IdentityClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
+        super(IdentityClientJSON, self).__init__(auth_provider,
+                                                 CONF.identity.catalog_type,
+                                                 endpoint_type='adminURL')
 
     def has_admin_extensions(self):
         """
diff --git a/tempest/services/identity/v3/json/base.py b/tempest/services/identity/v3/json/base.py
index 3df0dab..da8e287 100644
--- a/tempest/services/identity/v3/json/base.py
+++ b/tempest/services/identity/v3/json/base.py
@@ -24,7 +24,7 @@
     """
 
     def __init__(self, auth_provider):
-        super(IdentityV3Client, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
+        super(IdentityV3Client, self).__init__(auth_provider,
+                                               CONF.identity.catalog_type,
+                                               endpoint_type='adminURL')
         self.api_version = "v3"
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 8c45572..48ba909 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -523,7 +523,7 @@
 class V3TokenClientJSON(rest_client.RestClient):
 
     def __init__(self):
-        super(V3TokenClientJSON, self).__init__(None)
+        super(V3TokenClientJSON, self).__init__(None, None)
         auth_url = CONF.identity.uri_v3
         if not auth_url:
             raise exceptions.InvalidConfiguration('you must specify a v3 uri '
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index d60c9d9..ba3a814 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -35,8 +35,10 @@
 class ImageClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(ImageClientJSON, self).__init__(auth_provider)
-        self.service = CONF.image.catalog_type
+        super(ImageClientJSON, self).__init__(
+            auth_provider,
+            CONF.image.catalog_type,
+            endpoint_type=CONF.image.endpoint_type)
         self._http = None
 
     def _image_meta_from_headers(self, headers):
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 7421508..23810f9 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -29,8 +29,10 @@
 class ImageClientV2JSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(ImageClientV2JSON, self).__init__(auth_provider)
-        self.service = CONF.image.catalog_type
+        super(ImageClientV2JSON, self).__init__(
+            auth_provider,
+            CONF.image.catalog_type,
+            endpoint_type=CONF.image.endpoint_type)
         self._http = None
 
     def _get_http(self):
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index 2794ea9..caed02f 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -28,8 +28,8 @@
 class MessagingClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(MessagingClientJSON, self).__init__(auth_provider)
-        self.service = CONF.messaging.catalog_type
+        super(MessagingClientJSON, self).__init__(auth_provider,
+                                                  CONF.messaging.catalog_type)
         self.version = '1'
         self.uri_prefix = 'v{0}'.format(self.version)
 
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index c622ee4..c279efd 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -38,10 +38,11 @@
     """
 
     def __init__(self, auth_provider):
-        super(NetworkClientJSON, self).__init__(auth_provider)
-        self.service = CONF.network.catalog_type
-        self.build_timeout = CONF.network.build_timeout
-        self.build_interval = CONF.network.build_interval
+        super(NetworkClientJSON, self).__init__(
+            auth_provider, CONF.network.catalog_type,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout)
         self.version = '2.0'
         self.uri_prefix = "v%s" % (self.version)
 
diff --git a/tempest/services/object_storage/base.py b/tempest/services/object_storage/base.py
index c903ca5..3900e82 100644
--- a/tempest/services/object_storage/base.py
+++ b/tempest/services/object_storage/base.py
@@ -24,6 +24,7 @@
     """
 
     def __init__(self, auth_provider):
-        super(ObjectStorageClient, self).__init__(auth_provider)
-        self.service = CONF.object_storage.catalog_type
+        super(ObjectStorageClient, self).__init__(
+            auth_provider, CONF.object_storage.catalog_type,
+            endpoint_type=CONF.object_storage.endpoint_type)
         self.format = 'json'
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index 9b4700a..2dedf01 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -28,10 +28,12 @@
 class OrchestrationClient(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(OrchestrationClient, self).__init__(auth_provider)
-        self.service = CONF.orchestration.catalog_type
-        self.build_interval = CONF.orchestration.build_interval
-        self.build_timeout = CONF.orchestration.build_timeout
+        super(OrchestrationClient, self).__init__(
+            auth_provider,
+            CONF.orchestration.catalog_type,
+            endpoint_type=CONF.orchestration.endpoint_type,
+            build_interval=CONF.orchestration.build_interval,
+            build_timeout=CONF.orchestration.build_timeout)
 
     def list_stacks(self, params=None):
         """Lists all stacks for a user."""
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 996aceb..622c996 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -13,15 +13,24 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import urllib
+
 from tempest.common import rest_client
+from tempest import config
 from tempest.openstack.common import jsonutils as json
-import tempest.services.telemetry.telemetry_client_base as client
+
+CONF = config.CONF
 
 
-class TelemetryClientJSON(client.TelemetryClientBase):
+class TelemetryClientJSON(rest_client.RestClient):
 
-    def get_rest_client(self, auth_provider):
-        return rest_client.RestClient(auth_provider)
+    def __init__(self, auth_provider):
+        super(TelemetryClientJSON, self).__init__(
+            auth_provider,
+            CONF.telemetry.catalog_type,
+            endpoint_type=CONF.telemetry.endpoint_type)
+        self.version = '2'
+        self.uri_prefix = "v%s" % self.version
 
     def deserialize(self, body):
         return json.loads(body.replace("\n", ""))
@@ -42,4 +51,87 @@
 
     def create_sample(self, meter_name, sample_list):
         uri = "%s/meters/%s" % (self.uri_prefix, meter_name)
-        return self.post(uri, str(sample_list))
+        body = self.serialize(sample_list)
+        resp, body = self.post(uri, body)
+        body = self.deserialize(body)
+        return resp, body
+
+    def helper_list(self, uri, query=None, period=None):
+        uri_dict = {}
+        if query:
+            uri_dict = {'q.field': query[0],
+                        'q.op': query[1],
+                        'q.value': query[2]}
+        if period:
+            uri_dict['period'] = period
+        if uri_dict:
+            uri += "?%s" % urllib.urlencode(uri_dict)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def list_resources(self, query=None):
+        uri = '%s/resources' % self.uri_prefix
+        return self.helper_list(uri, query)
+
+    def list_meters(self, query=None):
+        uri = '%s/meters' % self.uri_prefix
+        return self.helper_list(uri, query)
+
+    def list_alarms(self, query=None):
+        uri = '%s/alarms' % self.uri_prefix
+        return self.helper_list(uri, query)
+
+    def list_statistics(self, meter, period=None, query=None):
+        uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
+        return self.helper_list(uri, query, period)
+
+    def list_samples(self, meter_id, query=None):
+        uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
+        return self.helper_list(uri, query)
+
+    def get_resource(self, resource_id):
+        uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def get_alarm(self, alarm_id):
+        uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def delete_alarm(self, alarm_id):
+        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
+        resp, body = self.delete(uri)
+        if body:
+            body = self.deserialize(body)
+        return resp, body
+
+    def create_alarm(self, **kwargs):
+        uri = "%s/alarms" % self.uri_prefix
+        body = self.serialize(kwargs)
+        resp, body = self.post(uri, body)
+        body = self.deserialize(body)
+        return resp, body
+
+    def update_alarm(self, alarm_id, **kwargs):
+        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
+        body = self.serialize(kwargs)
+        resp, body = self.put(uri, body)
+        body = self.deserialize(body)
+        return resp, body
+
+    def alarm_get_state(self, alarm_id):
+        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def alarm_set_state(self, alarm_id, state):
+        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
+        body = self.serialize(state)
+        resp, body = self.put(uri, body)
+        body = self.deserialize(body)
+        return resp, body
diff --git a/tempest/services/telemetry/telemetry_client_base.py b/tempest/services/telemetry/telemetry_client_base.py
deleted file mode 100644
index a184a77..0000000
--- a/tempest/services/telemetry/telemetry_client_base.py
+++ /dev/null
@@ -1,151 +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.
-
-import abc
-import urllib
-
-import six
-
-from tempest import config
-
-CONF = config.CONF
-
-
-@six.add_metaclass(abc.ABCMeta)
-class TelemetryClientBase(object):
-
-    """
-    Tempest REST client for Ceilometer V2 API.
-    Implements the following basic Ceilometer abstractions:
-    resources
-    meters
-    alarms
-    queries
-    statistics
-    """
-
-    def __init__(self, auth_provider):
-        self.rest_client = self.get_rest_client(auth_provider)
-        self.rest_client.service = CONF.telemetry.catalog_type
-        self.version = '2'
-        self.uri_prefix = "v%s" % self.version
-
-    @abc.abstractmethod
-    def get_rest_client(self, auth_provider):
-        """
-        :param config:
-        :param username:
-        :param password:
-        :param auth_url:
-        :param tenant_name:
-        :return: RestClient
-        """
-
-    @abc.abstractmethod
-    def deserialize(self, body):
-        """
-        :param body:
-        :return: Deserialize body
-        """
-
-    @abc.abstractmethod
-    def serialize(self, body):
-        """
-        :param body:
-        :return: Serialize body
-        """
-
-    def post(self, uri, body):
-        body = self.serialize(body)
-        resp, body = self.rest_client.post(uri, body)
-        body = self.deserialize(body)
-        return resp, body
-
-    def put(self, uri, body):
-        body = self.serialize(body)
-        resp, body = self.rest_client.put(uri, body)
-        body = self.deserialize(body)
-        return resp, body
-
-    def get(self, uri):
-        resp, body = self.rest_client.get(uri)
-        body = self.deserialize(body)
-        return resp, body
-
-    def delete(self, uri):
-        resp, body = self.rest_client.delete(uri)
-        if body:
-            body = self.deserialize(body)
-        return resp, body
-
-    def helper_list(self, uri, query=None, period=None):
-        uri_dict = {}
-        if query:
-            uri_dict = {'q.field': query[0],
-                        'q.op': query[1],
-                        'q.value': query[2]}
-        if period:
-            uri_dict['period'] = period
-        if uri_dict:
-            uri += "?%s" % urllib.urlencode(uri_dict)
-        return self.get(uri)
-
-    def list_resources(self, query=None):
-        uri = '%s/resources' % self.uri_prefix
-        return self.helper_list(uri, query)
-
-    def list_meters(self, query=None):
-        uri = '%s/meters' % self.uri_prefix
-        return self.helper_list(uri, query)
-
-    def list_alarms(self, query=None):
-        uri = '%s/alarms' % self.uri_prefix
-        return self.helper_list(uri, query)
-
-    def list_statistics(self, meter, period=None, query=None):
-        uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
-        return self.helper_list(uri, query, period)
-
-    def list_samples(self, meter_id, query=None):
-        uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
-        return self.helper_list(uri, query)
-
-    def get_resource(self, resource_id):
-        uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
-        return self.get(uri)
-
-    def get_alarm(self, alarm_id):
-        uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
-        return self.get(uri)
-
-    def delete_alarm(self, alarm_id):
-        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
-        return self.delete(uri)
-
-    def create_alarm(self, **kwargs):
-        uri = "%s/alarms" % self.uri_prefix
-        return self.post(uri, kwargs)
-
-    def update_alarm(self, alarm_id, **kwargs):
-        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
-        return self.put(uri, kwargs)
-
-    def alarm_get_state(self, alarm_id):
-        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
-        return self.get(uri)
-
-    def alarm_set_state(self, alarm_id, state):
-        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
-        return self.put(uri, state)
diff --git a/tempest/services/volume/json/base.py b/tempest/services/volume/json/base.py
index 8bc2f93..1800ee6 100644
--- a/tempest/services/volume/json/base.py
+++ b/tempest/services/volume/json/base.py
@@ -24,7 +24,9 @@
     """
 
     def __init__(self, auth_provider):
-        super(VolumeClient, self).__init__(auth_provider)
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
+        super(VolumeClient, self).__init__(
+            auth_provider,
+            CONF.volume.catalog_type,
+            endpoint_type=CONF.volume.endpoint_type,
+            build_interval=CONF.volume.build_interval,
+            build_timeout=CONF.volume.build_timeout)
diff --git a/tempest/test.py b/tempest/test.py
index ff829f3..cc8370c 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -194,7 +194,6 @@
     """
     config_dict = {
         'compute': CONF.compute_feature_enabled.api_extensions,
-        'compute_v3': CONF.compute_feature_enabled.api_v3_extensions,
         'volume': CONF.volume_feature_enabled.api_extensions,
         'network': CONF.network_feature_enabled.api_extensions,
         'object': CONF.object_storage_feature_enabled.discoverable_apis,
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 3b9a990..65106cc 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -15,7 +15,6 @@
 import json
 
 import mock
-from oslo.config import cfg
 
 from tempest.cmd import verify_tempest_config
 from tempest import config
@@ -87,7 +86,7 @@
         self.assertIn('v3.0', versions)
 
     def test_verify_api_versions(self):
-        api_services = ['cinder', 'glance', 'keystone', 'nova']
+        api_services = ['cinder', 'glance', 'keystone']
         fake_os = mock.MagicMock()
         for svc in api_services:
             m = 'verify_%s_api_versions' % svc
@@ -96,7 +95,7 @@
                 verify_mock.assert_called_once_with(fake_os, True)
 
     def test_verify_api_versions_not_implemented(self):
-        api_services = ['cinder', 'glance', 'keystone', 'nova']
+        api_services = ['cinder', 'glance', 'keystone']
         fake_os = mock.MagicMock()
         for svc in api_services:
             m = 'verify_%s_api_versions' % svc
@@ -170,23 +169,6 @@
         print_mock.assert_called_once_with('api_v1', 'volume_feature_enabled',
                                            False, True)
 
-    def test_verify_nova_versions(self):
-        cfg.CONF.set_default('api_v3', True, 'compute-feature-enabled')
-        self.useFixture(mockpatch.PatchObject(
-            verify_tempest_config, '_get_unversioned_endpoint',
-            return_value='http://fake_endpoint:5000'))
-        fake_resp = {'versions': [{'id': 'v2.0'}]}
-        fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.PatchObject(
-            verify_tempest_config.RAW_HTTP, 'request',
-            return_value=(None, fake_resp)))
-        fake_os = mock.MagicMock()
-        with mock.patch.object(verify_tempest_config,
-                               'print_and_or_update') as print_mock:
-            verify_tempest_config.verify_nova_api_versions(fake_os, True)
-        print_mock.assert_called_once_with('api_v3', 'compute_feature_enabled',
-                                           False, True)
-
     def test_verify_glance_version_no_v2_with_v1_1(self):
         def fake_get_versions():
             return (None, ['v1.1'])
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index 9e56916..2f8efa1 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -52,9 +52,6 @@
                 self.conf.set_default(prefix + config_option,
                                       'fake_' + config_option,
                                       group='identity')
-            # Compute Admin group items
-            self.conf.set_default(config_option, 'fake_' + config_option,
-                                  group='compute-admin')
 
 
 class FakePrivate(config.TempestConfigPrivate):
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index fc80fe2..aa3df36 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -194,9 +194,6 @@
         for prefix in ['', 'alt_', 'admin_']:
             cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
                                  group='identity')
-        # Compute Admin group items
-        cfg.CONF.set_default('domain_name', 'fake_domain_name',
-                             group='compute-admin')
 
     def test_default(self):
         self.useFixture(fixtures.LockFixture('auth_version'))
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index 5b2ce7a..42ba5a0 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -38,7 +38,7 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.rest_client = rest_client.RestClient(
-            fake_auth_provider.FakeAuthProvider())
+            fake_auth_provider.FakeAuthProvider(), None)
         self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
         self.useFixture(mockpatch.PatchObject(self.rest_client, '_get_region',
                                               side_effect=self._get_region()))
@@ -304,7 +304,7 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.rest_client = rest_client.RestClient(
-            fake_auth_provider.FakeAuthProvider())
+            fake_auth_provider.FakeAuthProvider(), None)
 
     def test_response_less_than_400(self):
         self.rest_client._error_checker(**self.set_data("399"))
@@ -434,7 +434,7 @@
         self.fake_http = fake_http.fake_httplib2()
         super(TestNegativeRestClient, self).setUp()
         self.negative_rest_client = rest_client.NegativeRestClient(
-            fake_auth_provider.FakeAuthProvider())
+            fake_auth_provider.FakeAuthProvider(), None)
         self.useFixture(mockpatch.PatchObject(self.negative_rest_client,
                                               '_log_request'))
 
diff --git a/tox.ini b/tox.ini
index edfee15..fe2f79e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,7 +7,8 @@
 sitepackages = True
 setenv = VIRTUAL_ENV={envdir}
          OS_TEST_PATH=./tempest/test_discover
-deps = -r{toxinidir}/requirements.txt
+deps = setuptools
+       -r{toxinidir}/requirements.txt
 
 [testenv]
 setenv = VIRTUAL_ENV={envdir}