port test_aggregates and test_hosts into nova v3 part2

this port test_aggregates and test_hosts into nova v3,
and port the corresponding client aggregate_client and
host_client.

Partially implements blueprint nova-v3-api-tests

Change-Id: I0f7b4f548f68b634258bb396bd3d245b02561e3a
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 73d274c..1e5b6d2 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -270,6 +270,8 @@
         cls.volumes_client = cls.os.volumes_client
         cls.certificates_client = cls.os.certificates_v3_client
         cls.keypairs_client = cls.os.keypairs_v3_client
+        cls.aggregates_client = cls.os.aggregates_v3_client
+        cls.hosts_client = cls.os.hosts_v3_client
 
     @classmethod
     def create_image_from_server(cls, server_id, **kwargs):
@@ -328,10 +330,12 @@
             os_adm = clients.ComputeAdminManager(interface=cls._interface)
 
         cls.os_adm = os_adm
-        cls.severs_admin_client = cls.os_adm.servers_v3_client
+        cls.servers_admin_client = cls.os_adm.servers_v3_client
         cls.services_admin_client = cls.os_adm.services_v3_client
         cls.availability_zone_admin_client = \
             cls.os_adm.availability_zone_v3_client
         cls.hypervisor_admin_client = cls.os_adm.hypervisor_v3_client
         cls.tenant_usages_admin_client = cls.os_adm.tenant_usages_v3_client
         cls.flavors_admin_client = cls.os_adm.flavors_v3_client
+        cls.aggregates_admin_client = cls.os_adm.aggregates_v3_client
+        cls.hosts_admin_client = cls.os_adm.hosts_v3_client
diff --git a/tempest/api/compute/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
index 609d2c6..144dc44 100644
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ b/tempest/api/compute/v3/admin/test_aggregates.py
@@ -18,58 +18,59 @@
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
-class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest):
+class AggregatesAdminV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
     Tests Aggregates API that require admin privileges
     """
 
-    _host_key = 'OS-EXT-SRV-ATTR:host'
+    _host_key = 'os-extended-server-attributes:host'
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(AggregatesAdminTestJSON, cls).setUpClass()
-        cls.client = cls.os_adm.aggregates_client
+        super(AggregatesAdminV3TestJSON, cls).setUpClass()
+        cls.client = cls.aggregates_admin_client
+        cls.user_client = cls.aggregates_client
         cls.aggregate_name_prefix = 'test_aggregate_'
         cls.az_name_prefix = 'test_az_'
 
-        resp, hosts_all = cls.os_adm.hosts_client.list_hosts()
+        resp, hosts_all = cls.hosts_admin_client.list_hosts()
         hosts = map(lambda x: x['host_name'],
                     filter(lambda y: y['service'] == 'compute', hosts_all))
         cls.host = hosts[0]
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_delete(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.assertEqual(aggregate_name, aggregate['name'])
         self.assertEqual(None, aggregate['availability_zone'])
 
         resp, _ = self.client.delete_aggregate(aggregate['id'])
-        self.assertEqual(200, resp.status)
+        self.assertEqual(204, resp.status)
         self.client.wait_for_resource_deletion(aggregate['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_delete_with_az(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         az_name = data_utils.rand_name(self.az_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name, az_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.assertEqual(aggregate_name, aggregate['name'])
         self.assertEqual(az_name, aggregate['availability_zone'])
 
         resp, _ = self.client.delete_aggregate(aggregate['id'])
-        self.assertEqual(200, resp.status)
+        self.assertEqual(204, resp.status)
         self.client.wait_for_resource_deletion(aggregate['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_verify_entry_in_list(self):
         # Create an aggregate and ensure it is listed.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -82,7 +83,7 @@
                       map(lambda x: (x['id'], x['availability_zone']),
                           aggregates))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_update_metadata_get_details(self):
         # Create an aggregate and ensure its details are returned.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -107,7 +108,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(meta, body["metadata"])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_update_with_az(self):
         # Update an aggregate and ensure properties are updated correctly
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -116,7 +117,7 @@
         resp, aggregate = self.client.create_aggregate(aggregate_name, az_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.assertEqual(aggregate_name, aggregate['name'])
         self.assertEqual(az_name, aggregate['availability_zone'])
         self.assertIsNotNone(aggregate['id'])
@@ -139,7 +140,7 @@
                          (x['id'], x['name'], x['availability_zone']),
                           aggregates))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_remove_host(self):
         # Add an host to the given aggregate and remove.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -148,20 +149,20 @@
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         resp, body = self.client.add_host(aggregate['id'], self.host)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(202, resp.status)
         self.assertEqual(aggregate_name, body['name'])
         self.assertEqual(aggregate['availability_zone'],
                          body['availability_zone'])
         self.assertIn(self.host, body['hosts'])
 
         resp, body = self.client.remove_host(aggregate['id'], self.host)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(202, resp.status)
         self.assertEqual(aggregate_name, body['name'])
         self.assertEqual(aggregate['availability_zone'],
                          body['availability_zone'])
         self.assertNotIn(self.host, body['hosts'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_host_list(self):
         # Add an host to the given aggregate and list.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -179,7 +180,7 @@
         self.assertEqual(None, agg['availability_zone'])
         self.assertIn(self.host, agg['hosts'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_host_get_details(self):
         # Add an host to the given aggregate and get details.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -194,7 +195,7 @@
         self.assertEqual(None, body['availability_zone'])
         self.assertIn(self.host, body['hosts'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_host_create_server_with_az(self):
         # Add an host to the given aggregate and create a server.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -205,7 +206,7 @@
         self.client.add_host(aggregate['id'], self.host)
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
         server_name = data_utils.rand_name('test_server_')
-        admin_servers_client = self.os_adm.servers_client
+        admin_servers_client = self.servers_admin_client
         resp, server = self.create_test_server(name=server_name,
                                                availability_zone=az_name,
                                                wait_until='ACTIVE')
@@ -213,7 +214,8 @@
         self.assertEqual(self.host, body[self._host_key])
 
 
-class AggregatesAdminTestXML(AggregatesAdminTestJSON):
+class AggregatesAdminV3TestXML(AggregatesAdminV3TestJSON):
     _host_key = (
-        '{http://docs.openstack.org/compute/ext/extended_status/api/v1.1}host')
+        '{http://docs.openstack.org/compute/ext/'
+        'extended_server_attributes/api/v3}host')
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_aggregates_negative.py b/tempest/api/compute/v3/admin/test_aggregates_negative.py
index 8506206..87eadce 100644
--- a/tempest/api/compute/v3/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/v3/admin/test_aggregates_negative.py
@@ -19,10 +19,10 @@
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
-class AggregatesAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
+class AggregatesAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
     Tests Aggregates API that require admin privileges
@@ -32,18 +32,18 @@
 
     @classmethod
     def setUpClass(cls):
-        super(AggregatesAdminNegativeTestJSON, cls).setUpClass()
-        cls.client = cls.os_adm.aggregates_client
+        super(AggregatesAdminNegativeV3TestJSON, cls).setUpClass()
+        cls.client = cls.aggregates_admin_client
         cls.user_client = cls.aggregates_client
         cls.aggregate_name_prefix = 'test_aggregate_'
         cls.az_name_prefix = 'test_az_'
 
-        resp, hosts_all = cls.os_adm.hosts_client.list_hosts()
+        resp, hosts_all = cls.hosts_admin_client.list_hosts()
         hosts = map(lambda x: x['host_name'],
                     filter(lambda y: y['service'] == 'compute', hosts_all))
         cls.host = hosts[0]
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_as_user(self):
         # Regular user is not allowed to create an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -51,14 +51,14 @@
                           self.user_client.create_aggregate,
                           aggregate_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_aggregate_name_length_less_than_1(self):
         # the length of aggregate name should >= 1 and <=255
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_aggregate,
                           '')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_aggregate_name_length_exceeds_255(self):
         # the length of aggregate name should >= 1 and <=255
         aggregate_name = 'a' * 256
@@ -66,64 +66,64 @@
                           self.client.create_aggregate,
                           aggregate_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_with_existent_aggregate_name(self):
         # creating an aggregate with existent aggregate name is forbidden
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         self.assertRaises(exceptions.Conflict,
                           self.client.create_aggregate,
                           aggregate_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_delete_as_user(self):
         # Regular user is not allowed to delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         self.assertRaises(exceptions.Unauthorized,
                           self.user_client.delete_aggregate,
                           aggregate['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_list_as_user(self):
         # Regular user is not allowed to list aggregates.
         self.assertRaises(exceptions.Unauthorized,
                           self.user_client.list_aggregates)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_get_details_as_user(self):
         # Regular user is not allowed to get aggregate details.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         self.assertRaises(exceptions.Unauthorized,
                           self.user_client.get_aggregate,
                           aggregate['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_delete_with_invalid_id(self):
         # Delete an aggregate with invalid id should raise exceptions.
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_aggregate, -1)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_get_details_with_invalid_id(self):
         # Get aggregate details with invalid id should raise exceptions.
         self.assertRaises(exceptions.NotFound,
                           self.client.get_aggregate, -1)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_add_non_exist_host(self):
         # Adding a non-exist host to an aggregate should raise exceptions.
-        resp, hosts_all = self.os_adm.hosts_client.list_hosts()
+        resp, hosts_all = self.hosts_admin_client.list_hosts()
         hosts = map(lambda x: x['host_name'], hosts_all)
         while True:
             non_exist_host = data_utils.rand_name('nonexist_host_')
@@ -137,60 +137,60 @@
         self.assertRaises(exceptions.NotFound, self.client.add_host,
                           aggregate['id'], non_exist_host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_add_host_as_user(self):
         # Regular user is not allowed to add a host to an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         self.assertRaises(exceptions.Unauthorized,
                           self.user_client.add_host,
                           aggregate['id'], self.host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_add_existent_host(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         resp, body = self.client.add_host(aggregate['id'], self.host)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(202, resp.status)
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
 
         self.assertRaises(exceptions.Conflict, self.client.add_host,
                           aggregate['id'], self.host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_remove_host_as_user(self):
         # Regular user is not allowed to remove a host from an aggregate.
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
         resp, body = self.client.add_host(aggregate['id'], self.host)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(202, resp.status)
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
 
         self.assertRaises(exceptions.Unauthorized,
                           self.user_client.remove_host,
                           aggregate['id'], self.host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_remove_nonexistent_host(self):
         non_exist_host = data_utils.rand_name('nonexist_host_')
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         self.assertRaises(exceptions.NotFound, self.client.remove_host,
                           aggregate['id'], non_exist_host)
 
 
-class AggregatesAdminNegativeTestXML(AggregatesAdminNegativeTestJSON):
+class AggregatesAdminNegativeV3TestXML(AggregatesAdminNegativeV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_hosts.py b/tempest/api/compute/v3/admin/test_hosts.py
index 22e6cf1..896d6a7 100644
--- a/tempest/api/compute/v3/admin/test_hosts.py
+++ b/tempest/api/compute/v3/admin/test_hosts.py
@@ -16,10 +16,10 @@
 
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
-from tempest.test import attr
+from tempest import test
 
 
-class HostsAdminTestJSON(base.BaseV2ComputeAdminTest):
+class HostsAdminV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
     Tests hosts API using admin privileges.
@@ -29,16 +29,16 @@
 
     @classmethod
     def setUpClass(cls):
-        super(HostsAdminTestJSON, cls).setUpClass()
-        cls.client = cls.os_adm.hosts_client
+        super(HostsAdminV3TestJSON, cls).setUpClass()
+        cls.client = cls.hosts_admin_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts(self):
         resp, hosts = self.client.list_hosts()
         self.assertEqual(200, resp.status)
         self.assertTrue(len(hosts) >= 2, str(hosts))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts_with_zone(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         resp, hosts = self.client.list_hosts()
@@ -50,7 +50,7 @@
         self.assertTrue(len(hosts) >= 1)
         self.assertIn(host, hosts)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts_with_a_blank_zone(self):
         # If send the request with a blank zone, the request will be successful
         # and it will return all the hosts list
@@ -59,7 +59,7 @@
         self.assertNotEqual(0, len(hosts))
         self.assertEqual(200, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts_with_nonexistent_zone(self):
         # If send the request with a nonexistent zone, the request will be
         # successful and no hosts will be retured
@@ -68,7 +68,7 @@
         self.assertEqual(0, len(hosts))
         self.assertEqual(200, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_show_host_detail(self):
         resp, hosts = self.client.list_hosts()
         self.assertEqual(200, resp.status)
@@ -90,5 +90,5 @@
             self.assertEqual(hostname, host_resource['host'])
 
 
-class HostsAdminTestXML(HostsAdminTestJSON):
+class HostsAdminV3TestXML(HostsAdminV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_hosts_negative.py b/tempest/api/compute/v3/admin/test_hosts_negative.py
index dbf7967..755fa2b 100644
--- a/tempest/api/compute/v3/admin/test_hosts_negative.py
+++ b/tempest/api/compute/v3/admin/test_hosts_negative.py
@@ -20,7 +20,7 @@
 from tempest import test
 
 
-class HostsAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
+class HostsAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
     Tests hosts API using admin privileges.
@@ -30,9 +30,9 @@
 
     @classmethod
     def setUpClass(cls):
-        super(HostsAdminNegativeTestJSON, cls).setUpClass()
-        cls.client = cls.os_adm.hosts_client
-        cls.non_admin_client = cls.os.hosts_client
+        super(HostsAdminNegativeV3TestJSON, cls).setUpClass()
+        cls.client = cls.hosts_admin_client
+        cls.non_admin_client = cls.hosts_client
 
     def _get_host_name(self):
         resp, hosts = self.client.list_hosts()
@@ -68,7 +68,6 @@
                           self.non_admin_client.update_host,
                           hostname)
 
-    @test.skip_because(bug="1261964", interface="xml")
     @test.attr(type=['negative', 'gate'])
     def test_update_host_with_extra_param(self):
         # only 'status' and 'maintenance_mode' are the valid params.
@@ -171,5 +170,5 @@
                           hostname)
 
 
-class HostsAdminNegativeTestXML(HostsAdminNegativeTestJSON):
+class HostsAdminNegativeV3TestXML(HostsAdminNegativeV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/clients.py b/tempest/clients.py
index 1f2e1de..f4548d5 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -50,6 +50,8 @@
     TenantUsagesClientJSON
 from tempest.services.compute.json.volumes_extensions_client import \
     VolumesExtensionsClientJSON
+from tempest.services.compute.v3.json.aggregates_client import \
+    AggregatesV3ClientJSON
 from tempest.services.compute.v3.json.availability_zone_client import \
     AvailabilityZoneV3ClientJSON
 from tempest.services.compute.v3.json.certificates_client import \
@@ -57,6 +59,7 @@
 from tempest.services.compute.v3.json.extensions_client import \
     ExtensionsV3ClientJSON
 from tempest.services.compute.v3.json.flavors_client import FlavorsV3ClientJSON
+from tempest.services.compute.v3.json.hosts_client import HostsV3ClientJSON
 from tempest.services.compute.v3.json.hypervisor_client import \
     HypervisorV3ClientJSON
 from tempest.services.compute.v3.json.interfaces_client import \
@@ -69,6 +72,8 @@
     ServicesV3ClientJSON
 from tempest.services.compute.v3.json.tenant_usages_client import \
     TenantUsagesV3ClientJSON
+from tempest.services.compute.v3.xml.aggregates_client import \
+    AggregatesV3ClientXML
 from tempest.services.compute.v3.xml.availability_zone_client import \
     AvailabilityZoneV3ClientXML
 from tempest.services.compute.v3.xml.certificates_client import \
@@ -76,6 +81,7 @@
 from tempest.services.compute.v3.xml.extensions_client import \
     ExtensionsV3ClientXML
 from tempest.services.compute.v3.xml.flavors_client import FlavorsV3ClientXML
+from tempest.services.compute.v3.xml.hosts_client import HostsV3ClientXML
 from tempest.services.compute.v3.xml.hypervisor_client import \
     HypervisorV3ClientXML
 from tempest.services.compute.v3.xml.interfaces_client import \
@@ -254,6 +260,7 @@
                 *client_args)
             self.services_v3_client = ServicesV3ClientXML(*client_args)
             self.service_client = ServiceClientXML(*client_args)
+            self.aggregates_v3_client = AggregatesV3ClientXML(*client_args)
             self.aggregates_client = AggregatesClientXML(*client_args)
             self.services_client = ServicesClientXML(*client_args)
             self.tenant_usages_v3_client = TenantUsagesV3ClientXML(
@@ -271,6 +278,7 @@
             self.volume_hosts_client = VolumeHostsClientXML(*client_args)
             self.volumes_extension_client = VolumeExtensionClientXML(
                 *client_args)
+            self.hosts_v3_client = HostsV3ClientXML(*client_args)
 
             if client_args_v3_auth:
                 self.servers_client_v3_auth = ServersClientXML(
@@ -312,6 +320,7 @@
                 *client_args)
             self.services_v3_client = ServicesV3ClientJSON(*client_args)
             self.service_client = ServiceClientJSON(*client_args)
+            self.aggregates_v3_client = AggregatesV3ClientJSON(*client_args)
             self.aggregates_client = AggregatesClientJSON(*client_args)
             self.services_client = ServicesClientJSON(*client_args)
             self.tenant_usages_v3_client = TenantUsagesV3ClientJSON(
@@ -329,6 +338,7 @@
             self.volume_hosts_client = VolumeHostsClientJSON(*client_args)
             self.volumes_extension_client = VolumeExtensionClientJSON(
                 *client_args)
+            self.hosts_v3_client = HostsV3ClientJSON(*client_args)
 
             if client_args_v3_auth:
                 self.servers_client_v3_auth = ServersClientJSON(
diff --git a/tempest/services/compute/v3/json/aggregates_client.py b/tempest/services/compute/v3/json/aggregates_client.py
index b7c6bf1..8ca2770 100644
--- a/tempest/services/compute/v3/json/aggregates_client.py
+++ b/tempest/services/compute/v3/json/aggregates_client.py
@@ -21,12 +21,13 @@
 from tempest import exceptions
 
 
-class AggregatesClientJSON(RestClient):
+class AggregatesV3ClientJSON(RestClient):
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(AggregatesClientJSON, self).__init__(config, username, password,
-                                                   auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
+        super(AggregatesV3ClientJSON, self).__init__(config, username,
+                                                     password, auth_url,
+                                                     tenant_name)
+        self.service = self.config.compute.catalog_v3_type
 
     def list_aggregates(self):
         """Get aggregate list."""
diff --git a/tempest/services/compute/v3/json/hosts_client.py b/tempest/services/compute/v3/json/hosts_client.py
index f51879d..85cc34f 100644
--- a/tempest/services/compute/v3/json/hosts_client.py
+++ b/tempest/services/compute/v3/json/hosts_client.py
@@ -20,12 +20,12 @@
 from tempest.common.rest_client import RestClient
 
 
-class HostsClientJSON(RestClient):
+class HostsV3ClientJSON(RestClient):
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(HostsClientJSON, self).__init__(config, username, password,
-                                              auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
+        super(HostsV3ClientJSON, self).__init__(config, username, password,
+                                                auth_url, tenant_name)
+        self.service = self.config.compute.catalog_v3_type
 
     def list_hosts(self, params=None):
         """Lists all hosts."""
@@ -53,7 +53,7 @@
             'maintenance_mode': None,
         }
         request_body.update(**kwargs)
-        request_body = json.dumps(request_body)
+        request_body = json.dumps({'host': request_body})
 
         resp, body = self.put("os-hosts/%s" % str(hostname), request_body,
                               self.headers)
diff --git a/tempest/services/compute/v3/xml/aggregates_client.py b/tempest/services/compute/v3/xml/aggregates_client.py
index 5faaff5..7563fd6 100644
--- a/tempest/services/compute/v3/xml/aggregates_client.py
+++ b/tempest/services/compute/v3/xml/aggregates_client.py
@@ -25,12 +25,12 @@
 from tempest.services.compute.xml.common import xml_to_json
 
 
-class AggregatesClientXML(RestClientXML):
+class AggregatesV3ClientXML(RestClientXML):
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(AggregatesClientXML, self).__init__(config, username, password,
-                                                  auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
+        super(AggregatesV3ClientXML, self).__init__(config, username, password,
+                                                    auth_url, tenant_name)
+        self.service = self.config.compute.catalog_v3_type
 
     def _format_aggregate(self, g):
         agg = xml_to_json(g)
diff --git a/tempest/services/compute/v3/xml/hosts_client.py b/tempest/services/compute/v3/xml/hosts_client.py
index 519798e..82fb076 100644
--- a/tempest/services/compute/v3/xml/hosts_client.py
+++ b/tempest/services/compute/v3/xml/hosts_client.py
@@ -23,12 +23,12 @@
 from tempest.services.compute.xml.common import xml_to_json
 
 
-class HostsClientXML(RestClientXML):
+class HostsV3ClientXML(RestClientXML):
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(HostsClientXML, self).__init__(config, username, password,
-                                             auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
+        super(HostsV3ClientXML, self).__init__(config, username, password,
+                                               auth_url, tenant_name)
+        self.service = self.config.compute.catalog_v3_type
 
     def list_hosts(self, params=None):
         """Lists all hosts."""
@@ -53,7 +53,7 @@
     def update_host(self, hostname, **kwargs):
         """Update a host."""
 
-        request_body = Element("updates")
+        request_body = Element("host")
         if kwargs:
             for k, v in kwargs.iteritems():
                 request_body.append(Element(k, v))