Merge "Use Tempest-lib's compute images_client"
diff --git a/requirements.txt b/requirements.txt
index 370bb65..ffe6f26 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -13,11 +13,11 @@
 testrepository>=0.0.18
 pyOpenSSL>=0.14
 oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=2.6.0 # Apache-2.0
+oslo.config>=2.7.0 # Apache-2.0
 oslo.i18n>=1.5.0 # Apache-2.0
 oslo.log>=1.12.0 # Apache-2.0
 oslo.serialization>=1.10.0 # Apache-2.0
-oslo.utils!=2.6.0,>=2.4.0 # Apache-2.0
+oslo.utils>=2.8.0 # Apache-2.0
 six>=1.9.0
 iso8601>=0.1.9
 fixtures>=1.3.1
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 993d39e..b038c6b 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -147,7 +147,7 @@
     @test.idempotent_id('31ff3486-b8a0-4f56-a6c0-aab460531db3')
     def test_get_server_diagnostics_by_admin(self):
         # Retrieve server diagnostics by admin user
-        diagnostic = self.client.get_server_diagnostics(self.s1_id)
+        diagnostic = self.client.show_server_diagnostics(self.s1_id)
         basic_attrs = ['rx_packets', 'rx_errors', 'rx_drop',
                        'tx_packets', 'tx_errors', 'tx_drop',
                        'read_req', 'write_req', 'cpu', 'memory']
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 3d0ce35..7c5e8d0 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -130,7 +130,7 @@
     def test_get_server_diagnostics_by_non_admin(self):
         # Non-admin user can not view server diagnostics according to policy
         self.assertRaises(lib_exc.Forbidden,
-                          self.non_adm_client.get_server_diagnostics,
+                          self.non_adm_client.show_server_diagnostics,
                           self.s1_id)
 
     @test.attr(type=['negative'])
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index 97d47fd..814aec7 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -47,7 +47,7 @@
     @test.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
     def test_get_instance_action(self):
         # Get the action details of the provided server
-        body = self.client.get_instance_action(
+        body = self.client.show_instance_action(
             self.server_id, self.request_id)['instanceAction']
         self.assertEqual(self.server_id, body['instance_uuid'])
         self.assertEqual('create', body['action'])
diff --git a/tempest/api/compute/servers/test_instance_actions_negative.py b/tempest/api/compute/servers/test_instance_actions_negative.py
index 6567da1..ac66d05 100644
--- a/tempest/api/compute/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/servers/test_instance_actions_negative.py
@@ -46,5 +46,5 @@
     @test.idempotent_id('0269f40a-6f18-456c-b336-c03623c897f1')
     def test_get_instance_action_invalid_request(self):
         # Get the action details of the provided server with invalid request
-        self.assertRaises(lib_exc.NotFound, self.client.get_instance_action,
+        self.assertRaises(lib_exc.NotFound, self.client.show_instance_action,
                           self.server_id, '999')
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 77ddb3b..9c07677 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -87,8 +87,8 @@
     @test.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
     def test_get_server_metadata_item(self):
         # The value for a specific metadata key should be returned
-        meta = self.client.get_server_metadata_item(self.server_id,
-                                                    'key2')['meta']
+        meta = self.client.show_server_metadata_item(self.server_id,
+                                                     'key2')['meta']
         self.assertEqual('value2', meta['key2'])
 
     @test.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index cee60fb..18d80be 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -67,7 +67,7 @@
         # GET on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.get_server_metadata_item,
+                          self.client.show_server_metadata_item,
                           non_existent_server_id,
                           'test2')
 
diff --git a/tempest/api/compute/servers/test_server_password.py b/tempest/api/compute/servers/test_server_password.py
index 35c2cfd..9b41708 100644
--- a/tempest/api/compute/servers/test_server_password.py
+++ b/tempest/api/compute/servers/test_server_password.py
@@ -32,7 +32,7 @@
 
     @test.idempotent_id('f83b582f-62a8-4f22-85b0-0dee50ff783a')
     def test_get_server_password(self):
-        self.client.get_password(self.server['id'])
+        self.client.show_password(self.server['id'])
 
     @test.idempotent_id('f8229e8b-b625-4493-800a-bde86ac611ea')
     def test_delete_server_password(self):
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index f8d0cca..436ed2f 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -400,7 +400,7 @@
         self.addCleanup(self.client.delete_server_metadata_item,
                         self.server['id'], 'meta1')
         self.assertRaises(lib_exc.NotFound,
-                          self.alt_client.get_server_metadata_item,
+                          self.alt_client.show_server_metadata_item,
                           self.server['id'], 'meta1')
 
     @test.idempotent_id('16b2d724-0d3b-4216-a9fa-97bd4d9cf670')
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index ab4ddf7..b4837f7 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -144,7 +144,7 @@
         self.assertIn(self.attachment, body)
 
         # Get Volume attachment of the server
-        body = self.servers_client.get_volume_attachment(
+        body = self.servers_client.show_volume_attachment(
             self.server['id'],
             self.attachment['id'])['volumeAttachment']
         self.assertEqual(self.server['id'], body['serverId'])
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 5ce6354..d5af4b4 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -24,21 +24,20 @@
     def test_group_create_update_get(self):
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
-        group = self.client.create_group(name,
-                                         description=description)['group']
-        self.addCleanup(self.client.delete_group, group['id'])
+        group = self.groups_client.create_group(
+            name, description=description)['group']
+        self.addCleanup(self.groups_client.delete_group, group['id'])
         self.assertEqual(group['name'], name)
         self.assertEqual(group['description'], description)
 
         new_name = data_utils.rand_name('UpdateGroup')
         new_desc = data_utils.rand_name('UpdateDescription')
-        updated_group = self.client.update_group(group['id'],
-                                                 name=new_name,
-                                                 description=new_desc)['group']
+        updated_group = self.groups_client.update_group(
+            group['id'], name=new_name, description=new_desc)['group']
         self.assertEqual(updated_group['name'], new_name)
         self.assertEqual(updated_group['description'], new_desc)
 
-        new_group = self.client.get_group(group['id'])['group']
+        new_group = self.groups_client.get_group(group['id'])['group']
         self.assertEqual(group['id'], new_group['id'])
         self.assertEqual(new_name, new_group['name'])
         self.assertEqual(new_desc, new_group['description'])
@@ -47,8 +46,8 @@
     @test.idempotent_id('1598521a-2f36-4606-8df9-30772bd51339')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
-        group = self.client.create_group(name)['group']
-        self.addCleanup(self.client.delete_group, group['id'])
+        group = self.groups_client.create_group(name)['group']
+        self.addCleanup(self.groups_client.delete_group, group['id'])
         # add user into group
         users = []
         for i in range(3):
@@ -56,16 +55,15 @@
             user = self.client.create_user(name)['user']
             users.append(user)
             self.addCleanup(self.client.delete_user, user['id'])
-            self.client.add_group_user(group['id'], user['id'])
+            self.groups_client.add_group_user(group['id'], user['id'])
 
         # list users in group
-        group_users = self.client.list_group_users(group['id'])['users']
+        group_users = self.groups_client.list_group_users(group['id'])['users']
         self.assertEqual(sorted(users), sorted(group_users))
         # delete user in group
         for user in users:
-            self.client.delete_group_user(group['id'],
-                                          user['id'])
-        group_users = self.client.list_group_users(group['id'])['users']
+            self.groups_client.delete_group_user(group['id'], user['id'])
+        group_users = self.groups_client.list_group_users(group['id'])['users']
         self.assertEqual(len(group_users), 0)
 
     @test.idempotent_id('64573281-d26a-4a52-b899-503cb0f4e4ec')
@@ -79,10 +77,10 @@
         groups = []
         for i in range(2):
             name = data_utils.rand_name('Group')
-            group = self.client.create_group(name)['group']
+            group = self.groups_client.create_group(name)['group']
             groups.append(group)
-            self.addCleanup(self.client.delete_group, group['id'])
-            self.client.add_group_user(group['id'], user['id'])
+            self.addCleanup(self.groups_client.delete_group, group['id'])
+            self.groups_client.add_group_user(group['id'], user['id'])
         # list groups which user belongs to
         user_groups = self.client.list_user_groups(user['id'])['groups']
         self.assertEqual(sorted(groups), sorted(user_groups))
@@ -96,12 +94,12 @@
         for _ in range(3):
             name = data_utils.rand_name('Group')
             description = data_utils.rand_name('Description')
-            group = self.client.create_group(name,
-                                             description=description)['group']
-            self.addCleanup(self.client.delete_group, group['id'])
+            group = self.groups_client.create_group(
+                name, description=description)['group']
+            self.addCleanup(self.groups_client.delete_group, group['id'])
             group_ids.append(group['id'])
         # List and Verify Groups
-        body = self.client.list_groups()['groups']
+        body = self.groups_client.list_groups()['groups']
         for g in body:
             fetched_ids.append(g['id'])
         missing_groups = [g for g in group_ids if g not in fetched_ids]
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 8595dde..524340c 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -39,7 +39,7 @@
             data_utils.rand_name('project'),
             description=data_utils.rand_name('project-desc'),
             domain_id=cls.domain['id'])['project']
-        cls.group_body = cls.client.create_group(
+        cls.group_body = cls.groups_client.create_group(
             data_utils.rand_name('Group'), project_id=cls.project['id'],
             domain_id=cls.domain['id'])['group']
         cls.user_body = cls.client.create_user(
@@ -52,7 +52,7 @@
     @classmethod
     def resource_cleanup(cls):
         cls.client.delete_role(cls.role['id'])
-        cls.client.delete_group(cls.group_body['id'])
+        cls.groups_client.delete_group(cls.group_body['id'])
         cls.client.delete_user(cls.user_body['id'])
         cls.client.delete_project(cls.project['id'])
         # NOTE(harika-vakadi): It is necessary to disable the domain
@@ -137,8 +137,9 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
         # Add user to group, and insure user has role on project
-        self.client.add_group_user(self.group_body['id'], self.user_body['id'])
-        self.addCleanup(self.client.delete_group_user,
+        self.groups_client.add_group_user(self.group_body['id'],
+                                          self.user_body['id'])
+        self.addCleanup(self.groups_client.delete_group_user,
                         self.group_body['id'], self.user_body['id'])
         body = self.token.auth(user_id=self.user_body['id'],
                                password=self.u_password,
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index f9395bc..c56f4fb 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -120,11 +120,6 @@
         super(BaseIdentityV3Test, cls).setup_clients()
         cls.non_admin_client = cls.os.identity_v3_client
         cls.non_admin_token = cls.os.token_v3_client
-        cls.non_admin_endpoints_client = cls.os.endpoints_client
-        cls.non_admin_region_client = cls.os.region_client
-        cls.non_admin_service_client = cls.os.service_client
-        cls.non_admin_policy_client = cls.os.policy_client
-        cls.non_admin_creds_client = cls.os.credentials_client
 
     @classmethod
     def resource_cleanup(cls):
@@ -142,10 +137,12 @@
         cls.token = cls.os_adm.token_v3_client
         cls.endpoints_client = cls.os_adm.endpoints_client
         cls.region_client = cls.os_adm.region_client
-        cls.data = DataGenerator(cls.client)
         cls.service_client = cls.os_adm.service_client
         cls.policy_client = cls.os_adm.policy_client
         cls.creds_client = cls.os_adm.credentials_client
+        cls.groups_client = cls.os_adm.groups_client
+
+        cls.data = DataGenerator(cls.client)
 
     @classmethod
     def resource_cleanup(cls):
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
index 50aaa25..03c6621 100644
--- a/tempest/api/identity/v2/test_users.py
+++ b/tempest/api/identity/v2/test_users.py
@@ -55,6 +55,10 @@
             new_pass=old_pass,
             old_pass=new_pass)
 
+        # user updates own password
+        resp = self.non_admin_client.update_user_own_password(
+            user_id=user_id, new_pass=new_pass, old_pass=old_pass)['access']
+
         # TODO(lbragstad): Sleeping after the response status has been checked
         # and the body loaded as JSON allows requests to fail-fast. The sleep
         # is necessary because keystone will err on the side of security and
@@ -64,10 +68,6 @@
         # sub-second precision.
         time.sleep(1)
 
-        # user updates own password
-        resp = self.non_admin_client.update_user_own_password(
-            user_id=user_id, new_pass=new_pass, old_pass=old_pass)['access']
-
         # check authorization with new token
         self.non_admin_token_client.auth_token(resp['token']['id'])
         # check authorization with new password
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 14a866f..2bab5d1 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -54,6 +54,10 @@
             password=old_pass,
             original_password=new_pass)
 
+        # user updates own password
+        self.non_admin_client.update_user_password(
+            user_id=user_id, password=new_pass, original_password=old_pass)
+
         # TODO(lbragstad): Sleeping after the response status has been checked
         # and the body loaded as JSON allows requests to fail-fast. The sleep
         # is necessary because keystone will err on the side of security and
@@ -63,10 +67,6 @@
         # sub-second precision.
         time.sleep(1)
 
-        # user updates own password
-        self.non_admin_client.update_user_password(
-            user_id=user_id, password=new_pass, original_password=old_pass)
-
         # check authorization with new password
         self.non_admin_token.auth(user_id=self.user_id, password=new_pass)
 
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index fce63ac..a32bfbc 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -94,8 +94,6 @@
         # Verifies external network can be deleted while still holding
         # (unassociated) floating IPs
 
-        # Set cls.client to admin to use base.create_subnet()
-        client = self.admin_client
         body = self.admin_networks_client.create_network(
             **{'router:external': True})
         external_network = body['network']
@@ -105,19 +103,19 @@
         subnet = self.create_subnet(
             external_network, client=self.admin_subnets_client,
             enable_dhcp=False)
-        body = client.create_floatingip(
+        body = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=external_network['id'])
         created_floating_ip = body['floatingip']
         self.addCleanup(self._try_delete_resource,
-                        client.delete_floatingip,
+                        self.admin_floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
-        floatingip_list = client.list_floatingips(
+        floatingip_list = self.admin_floating_ips_client.list_floatingips(
             network=external_network['id'])
         self.assertIn(created_floating_ip['id'],
                       (f['id'] for f in floatingip_list['floatingips']))
         self.admin_networks_client.delete_network(external_network['id'])
         # Verifies floating ip is deleted
-        floatingip_list = client.list_floatingips()
+        floatingip_list = self.admin_floating_ips_client.list_floatingips()
         self.assertNotIn(created_floating_ip['id'],
                          (f['id'] for f in floatingip_list['floatingips']))
         # Verifies subnet is deleted
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index 1e1573e..d031108 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -32,12 +32,11 @@
         # pre-created floating-ip should be denied.
 
         # create a floating ip
-        client = self.admin_client
-        body = client.create_floatingip(
+        body = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=CONF.network.public_network_id)
         created_floating_ip = body['floatingip']
         self.addCleanup(self._try_delete_resource,
-                        client.delete_floatingip,
+                        self.admin_floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
         floating_ip_address = created_floating_ip['floating_ip_address']
         self.assertIsNotNone(floating_ip_address)
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index dfe7307..6ad374b 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -29,6 +29,7 @@
     def setup_clients(cls):
         super(FloatingIPAdminTestJSON, cls).setup_clients()
         cls.alt_client = cls.alt_manager.network_client
+        cls.alt_floating_ips_client = cls.alt_manager.floating_ips_client
 
     @classmethod
     def resource_setup(cls):
@@ -45,18 +46,18 @@
     @test.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
     def test_list_floating_ips_from_admin_and_nonadmin(self):
         # Create floating ip from admin user
-        floating_ip_admin = self.admin_client.create_floatingip(
+        floating_ip_admin = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
-        self.addCleanup(self.admin_client.delete_floatingip,
+        self.addCleanup(self.admin_floating_ips_client.delete_floatingip,
                         floating_ip_admin['floatingip']['id'])
         # Create floating ip from alt user
-        body = self.alt_client.create_floatingip(
+        body = self.alt_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
         floating_ip_alt = body['floatingip']
-        self.addCleanup(self.alt_client.delete_floatingip,
+        self.addCleanup(self.alt_floating_ips_client.delete_floatingip,
                         floating_ip_alt['id'])
         # List floating ips from admin
-        body = self.admin_client.list_floatingips()
+        body = self.admin_floating_ips_client.list_floatingips()
         floating_ip_ids_admin = [f['id'] for f in body['floatingips']]
         # Check that admin sees all floating ips
         self.assertIn(self.floating_ip['id'], floating_ip_ids_admin)
@@ -64,7 +65,7 @@
                       floating_ip_ids_admin)
         self.assertIn(floating_ip_alt['id'], floating_ip_ids_admin)
         # List floating ips from nonadmin
-        body = self.client.list_floatingips()
+        body = self.floating_ips_client.list_floatingips()
         floating_ip_ids = [f['id'] for f in body['floatingips']]
         # Check that nonadmin user doesn't see floating ip created from admin
         # and floating ip that is created in another tenant (alt user)
@@ -76,12 +77,12 @@
     @test.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
     def test_create_list_show_floating_ip_with_tenant_id_by_admin(self):
         # Creates a floating IP
-        body = self.admin_client.create_floatingip(
+        body = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             tenant_id=self.network['tenant_id'],
             port_id=self.port['id'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip,
+        self.addCleanup(self.floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['tenant_id'])
@@ -93,7 +94,7 @@
         self.assertEqual(created_floating_ip['fixed_ip_address'],
                          port[0]['ip_address'])
         # Verifies the details of a floating_ip
-        floating_ip = self.admin_client.show_floatingip(
+        floating_ip = self.admin_floating_ips_client.show_floatingip(
             created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
@@ -105,6 +106,6 @@
                          created_floating_ip['floating_ip_address'])
         self.assertEqual(shown_floating_ip['port_id'], self.port['id'])
         # Verify the floating ip exists in the list of all floating_ips
-        floating_ips = self.admin_client.list_floatingips()
+        floating_ips = self.admin_floating_ips_client.list_floatingips()
         floatingip_id_list = [f['id'] for f in floating_ips['floatingips']]
         self.assertIn(created_floating_ip['id'], floatingip_id_list)
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 2c0b981..b798cb2 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -74,6 +74,7 @@
         cls.networks_client = cls.os.networks_client
         cls.subnets_client = cls.os.subnets_client
         cls.ports_client = cls.os.ports_client
+        cls.floating_ips_client = cls.os.floating_ips_client
 
     @classmethod
     def resource_setup(cls):
@@ -92,8 +93,9 @@
         if CONF.service_available.neutron:
             # Clean up floating IPs
             for floating_ip in cls.floating_ips:
-                cls._try_delete_resource(cls.client.delete_floatingip,
-                                         floating_ip['id'])
+                cls._try_delete_resource(
+                    cls.floating_ips_client.delete_floatingip,
+                    floating_ip['id'])
 
             # Clean up metering label rules
             for metering_label_rule in cls.metering_label_rules:
@@ -232,7 +234,7 @@
     @classmethod
     def create_floatingip(cls, external_network_id):
         """Wrapper utility that returns a test floating IP."""
-        body = cls.client.create_floatingip(
+        body = cls.floating_ips_client.create_floatingip(
             floating_network_id=external_network_id)
         fip = body['floatingip']
         cls.floating_ips.append(fip)
@@ -269,6 +271,7 @@
         cls.admin_networks_client = cls.os_adm.networks_client
         cls.admin_subnets_client = cls.os_adm.subnets_client
         cls.admin_ports_client = cls.os_adm.ports_client
+        cls.admin_floating_ips_client = cls.os_adm.floating_ips_client
 
     @classmethod
     def create_metering_label(cls, name, description):
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index e9a553a..ce9c4be 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -68,11 +68,11 @@
     @test.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
     def test_create_list_show_update_delete_floating_ip(self):
         # Creates a floating IP
-        body = self.client.create_floatingip(
+        body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=self.ports[0]['id'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip,
+        self.addCleanup(self.floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['tenant_id'])
@@ -83,7 +83,8 @@
         self.assertIn(created_floating_ip['fixed_ip_address'],
                       [ip['ip_address'] for ip in self.ports[0]['fixed_ips']])
         # Verifies the details of a floating_ip
-        floating_ip = self.client.show_floatingip(created_floating_ip['id'])
+        floating_ip = self.floating_ips_client.show_floatingip(
+            created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
         self.assertEqual(shown_floating_ip['floating_network_id'],
@@ -95,13 +96,13 @@
         self.assertEqual(shown_floating_ip['port_id'], self.ports[0]['id'])
 
         # Verify the floating ip exists in the list of all floating_ips
-        floating_ips = self.client.list_floatingips()
+        floating_ips = self.floating_ips_client.list_floatingips()
         floatingip_id_list = list()
         for f in floating_ips['floatingips']:
             floatingip_id_list.append(f['id'])
         self.assertIn(created_floating_ip['id'], floatingip_id_list)
         # Associate floating IP to the other port
-        floating_ip = self.client.update_floatingip(
+        floating_ip = self.floating_ips_client.update_floatingip(
             created_floating_ip['id'],
             port_id=self.ports[1]['id'])
         updated_floating_ip = floating_ip['floatingip']
@@ -111,7 +112,7 @@
         self.assertEqual(updated_floating_ip['router_id'], self.router['id'])
 
         # Disassociate floating IP from the port
-        floating_ip = self.client.update_floatingip(
+        floating_ip = self.floating_ips_client.update_floatingip(
             created_floating_ip['id'],
             port_id=None)
         updated_floating_ip = floating_ip['floatingip']
@@ -122,21 +123,22 @@
     @test.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
     def test_floating_ip_delete_port(self):
         # Create a floating IP
-        body = self.client.create_floatingip(
+        body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip,
+        self.addCleanup(self.floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
         # Create a port
         port = self.ports_client.create_port(network_id=self.network['id'])
         created_port = port['port']
-        floating_ip = self.client.update_floatingip(
+        floating_ip = self.floating_ips_client.update_floatingip(
             created_floating_ip['id'],
             port_id=created_port['id'])
         # Delete port
         self.ports_client.delete_port(created_port['id'])
         # Verifies the details of the floating_ip
-        floating_ip = self.client.show_floatingip(created_floating_ip['id'])
+        floating_ip = self.floating_ips_client.show_floatingip(
+            created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         # Confirm the fields are back to None
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
@@ -147,11 +149,11 @@
     @test.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
     def test_floating_ip_update_different_router(self):
         # Associate a floating IP to a port on a router
-        body = self.client.create_floatingip(
+        body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=self.ports[1]['id'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip,
+        self.addCleanup(self.floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
         self.assertEqual(created_floating_ip['router_id'], self.router['id'])
         network2 = self.create_network()
@@ -161,7 +163,7 @@
         self.create_router_interface(router2['id'], subnet2['id'])
         port_other_router = self.create_port(network2)
         # Associate floating IP to the other port on another router
-        floating_ip = self.client.update_floatingip(
+        floating_ip = self.floating_ips_client.update_floatingip(
             created_floating_ip['id'],
             port_id=port_other_router['id'])
         updated_floating_ip = floating_ip['floatingip']
@@ -173,17 +175,17 @@
     @test.attr(type='smoke')
     @test.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
     def test_create_floating_ip_specifying_a_fixed_ip_address(self):
-        body = self.client.create_floatingip(
+        body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=self.ports[1]['id'],
             fixed_ip_address=self.ports[1]['fixed_ips'][0]['ip_address'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip,
+        self.addCleanup(self.floating_ips_client.delete_floatingip,
                         created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertEqual(created_floating_ip['fixed_ip_address'],
                          self.ports[1]['fixed_ips'][0]['ip_address'])
-        floating_ip = self.client.update_floatingip(
+        floating_ip = self.floating_ips_client.update_floatingip(
             created_floating_ip['id'],
             port_id=None)
         self.assertIsNone(floating_ip['floatingip']['port_id'])
@@ -200,18 +202,19 @@
         port = body['port']
         self.addCleanup(self.ports_client.delete_port, port['id'])
         # Create floating ip
-        body = self.client.create_floatingip(
+        body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=port['id'],
             fixed_ip_address=list_ips[0])
         floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip, floating_ip['id'])
+        self.addCleanup(self.floating_ips_client.delete_floatingip,
+                        floating_ip['id'])
         self.assertIsNotNone(floating_ip['id'])
         self.assertEqual(floating_ip['fixed_ip_address'], list_ips[0])
         # Update floating ip
-        body = self.client.update_floatingip(floating_ip['id'],
-                                             port_id=port['id'],
-                                             fixed_ip_address=list_ips[1])
+        body = self.floating_ips_client.update_floatingip(
+            floating_ip['id'], port_id=port['id'],
+            fixed_ip_address=list_ips[1])
         update_floating_ip = body['floatingip']
         self.assertEqual(update_floating_ip['fixed_ip_address'],
                          list_ips[1])
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 5f56fec..f915615 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -53,17 +53,17 @@
     @test.attr(type=['negative'])
     @test.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
     def test_create_floatingip_with_port_ext_net_unreachable(self):
-        self.assertRaises(lib_exc.NotFound, self.client.create_floatingip,
-                          floating_network_id=self.ext_net_id,
-                          port_id=self.port['id'],
-                          fixed_ip_address=self.port['fixed_ips'][0]
-                                                    ['ip_address'])
+        self.assertRaises(
+            lib_exc.NotFound, self.floating_ips_client.create_floatingip,
+            floating_network_id=self.ext_net_id, port_id=self.port['id'],
+            fixed_ip_address=self.port['fixed_ips'][0]
+                                      ['ip_address'])
 
     @test.attr(type=['negative'])
     @test.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
     def test_create_floatingip_in_private_network(self):
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.create_floatingip,
+                          self.floating_ips_client.create_floatingip,
                           floating_network_id=self.network['id'],
                           port_id=self.port['id'],
                           fixed_ip_address=self.port['fixed_ips'][0]
@@ -73,12 +73,13 @@
     @test.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
     def test_associate_floatingip_port_ext_net_unreachable(self):
         # Create floating ip
-        body = self.client.create_floatingip(
+        body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
         floating_ip = body['floatingip']
-        self.addCleanup(self.client.delete_floatingip, floating_ip['id'])
+        self.addCleanup(
+            self.floating_ips_client.delete_floatingip, floating_ip['id'])
         # Associate floating IP to the other port
-        self.assertRaises(lib_exc.NotFound, self.client.update_floatingip,
-                          floating_ip['id'], port_id=self.port['id'],
-                          fixed_ip_address=self.port['fixed_ips'][0]
-                          ['ip_address'])
+        self.assertRaises(
+            lib_exc.NotFound, self.floating_ips_client.update_floatingip,
+            floating_ip['id'], port_id=self.port['id'],
+            fixed_ip_address=self.port['fixed_ips'][0]['ip_address'])
diff --git a/tempest/api_schema/response/compute/v2_1/servers.py b/tempest/api_schema/response/compute/v2_1/servers.py
index 9593f3c..38f7c82 100644
--- a/tempest/api_schema/response/compute/v2_1/servers.py
+++ b/tempest/api_schema/response/compute/v2_1/servers.py
@@ -291,8 +291,8 @@
     'status_code': [202]
 }
 
-get_volume_attachment = copy.deepcopy(attach_volume)
-get_volume_attachment['response_body']['properties'][
+show_volume_attachment = copy.deepcopy(attach_volume)
+show_volume_attachment['response_body']['properties'][
     'volumeAttachment']['properties'].update({'serverId': {'type': 'string'}})
 
 list_volume_attachments = {
@@ -436,7 +436,7 @@
 # 'events' does not come in response body always so it is not
 # defined as 'required'
 
-get_instance_action = {
+show_instance_action = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
@@ -448,7 +448,7 @@
     }
 }
 
-get_password = {
+show_password = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
@@ -520,7 +520,7 @@
     'status_code': [204]
 }
 
-set_get_server_metadata_item = {
+set_show_server_metadata_item = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
diff --git a/tempest/clients.py b/tempest/clients.py
index d0152bd..48366a5 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -94,6 +94,7 @@
     CredentialsClient
 from tempest.services.identity.v3.json.endpoints_client import \
     EndPointClient
+from tempest.services.identity.v3.json.groups_client import GroupsClient
 from tempest.services.identity.v3.json.identity_client import \
     IdentityV3Client
 from tempest.services.identity.v3.json.policy_client import PolicyClient
@@ -104,6 +105,7 @@
 from tempest.services.image.v2.json.image_client import ImageClientV2
 from tempest.services.messaging.json.messaging_client import \
     MessagingClient
+from tempest.services.network.json.floating_ips_client import FloatingIPsClient
 from tempest.services.network.json.network_client import NetworkClient
 from tempest.services.network.json.networks_client import NetworksClient
 from tempest.services.network.json.ports_client import PortsClient
@@ -218,6 +220,14 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **self.default_params)
+        self.floating_ips_client = FloatingIPsClient(
+            self.auth_provider,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout,
+            **self.default_params)
         self.messaging_client = MessagingClient(
             self.auth_provider,
             CONF.messaging.catalog_type,
@@ -399,6 +409,7 @@
         self.region_client = RegionClient(self.auth_provider, **params)
         self.credentials_client = CredentialsClient(self.auth_provider,
                                                     **params)
+        self.groups_client = GroupsClient(self.auth_provider, **params_v3)
         # Token clients do not use the catalog. They only need default_params.
         # They read auth_url, so they should only be set if the corresponding
         # API version is marked as enabled
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index a90b0ce..613fb26 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -89,6 +89,7 @@
 from oslo_log import log as logging
 import yaml
 
+from tempest.common import identity
 from tempest import config
 from tempest import exceptions as exc
 from tempest.services.identity.v2.json import identity_client
@@ -188,13 +189,14 @@
     LOG.info('Tenants created')
     for u in resources['users']:
         try:
-            tenant = identity_admin.get_tenant_by_name(u['tenant'])
+            tenant = identity.get_tenant_by_name(identity_admin, u['tenant'])
         except tempest_lib.exceptions.NotFound:
             LOG.error("Tenant: %s - not found" % u['tenant'])
             continue
         while True:
             try:
-                identity_admin.get_user_by_username(tenant['id'], u['name'])
+                identity.get_user_by_username(identity_admin,
+                                              tenant['id'], u['name'])
             except tempest_lib.exceptions.NotFound:
                 identity_admin.create_user(
                     u['name'], u['pass'], tenant['id'],
@@ -209,7 +211,7 @@
     LOG.info('Users created')
     if neutron_iso_networks:
         for u in resources['users']:
-            tenant = identity_admin.get_tenant_by_name(u['tenant'])
+            tenant = identity.get_tenant_by_name(identity_admin, u['tenant'])
             network_name, router_name = create_network_resources(
                 network_admin, networks_admin, subnets_admin, tenant['id'],
                 u['name'])
@@ -218,13 +220,13 @@
         LOG.info('Networks created')
     for u in resources['users']:
         try:
-            tenant = identity_admin.get_tenant_by_name(u['tenant'])
+            tenant = identity.get_tenant_by_name(identity_admin, u['tenant'])
         except tempest_lib.exceptions.NotFound:
             LOG.error("Tenant: %s - not found" % u['tenant'])
             continue
         try:
-            user = identity_admin.get_user_by_username(tenant['id'],
-                                                       u['name'])
+            user = identity.get_user_by_username(identity_admin,
+                                                 tenant['id'], u['name'])
         except tempest_lib.exceptions.NotFound:
             LOG.error("User: %s - not found" % u['user'])
             continue
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 239b4e9..9c852c5 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -59,6 +59,7 @@
 from tempest import clients
 from tempest.cmd import cleanup_service
 from tempest.common import credentials_factory as credentials
+from tempest.common import identity
 from tempest import config
 
 SAVED_STATE_JSON = "saved_state.json"
@@ -177,11 +178,12 @@
     def _init_admin_ids(self):
         id_cl = self.admin_mgr.identity_client
 
-        tenant = id_cl.get_tenant_by_name(CONF.auth.admin_tenant_name)
+        tenant = identity.get_tenant_by_name(id_cl,
+                                             CONF.auth.admin_tenant_name)
         self.admin_tenant_id = tenant['id']
 
-        user = id_cl.get_user_by_username(self.admin_tenant_id,
-                                          CONF.auth.admin_username)
+        user = identity.get_user_by_username(id_cl, self.admin_tenant_id,
+                                             CONF.auth.admin_username)
         self.admin_id = user['id']
 
         roles = id_cl.list_roles()['roles']
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index d2f6c03..ba6bf6c 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -17,6 +17,7 @@
 from oslo_log import log as logging
 
 from tempest.common import credentials_factory as credentials
+from tempest.common import identity
 from tempest import config
 from tempest import test
 
@@ -87,7 +88,7 @@
     id_cl = am.identity_client
 
     networks = net_cl.list_networks()
-    tenant = id_cl.get_tenant_by_name(tenant_name)
+    tenant = identity.get_tenant_by_name(id_cl, tenant_name)
     t_id = tenant['id']
     n_id = None
     for net in networks['networks']:
@@ -385,6 +386,7 @@
         self.networks_client = manager.networks_client
         self.subnets_client = manager.subnets_client
         self.ports_client = manager.ports_client
+        self.floating_ips_client = manager.floating_ips_client
 
     def _filter_by_conf_networks(self, item_list):
         if not item_list or not all(('network_id' in i for i in item_list)):
@@ -421,7 +423,7 @@
 class NetworkFloatingIpService(NetworkService):
 
     def list(self):
-        client = self.client
+        client = self.floating_ips_client
         flips = client.list_floatingips(**self.tenant_filter)
         flips = flips['floatingips']
         LOG.debug("List count, %s Network Floating IPs" % len(flips))
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 97d431a..cbaf756 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -120,6 +120,7 @@
 from tempest_lib.services.compute import flavors_client
 import yaml
 
+from tempest.common import identity
 from tempest.common import waiters
 from tempest import config
 from tempest.services.compute.json import floating_ips_client
@@ -295,7 +296,7 @@
 def destroy_tenants(tenants):
     admin = keystone_admin()
     for tenant in tenants:
-        tenant_id = admin.identity.get_tenant_by_name(tenant)['id']
+        tenant_id = identity.get_tenant_by_name(admin.identity, tenant)['id']
         admin.identity.delete_tenant(tenant_id)
 
 ##############
@@ -347,12 +348,13 @@
     admin = keystone_admin()
     for u in users:
         try:
-            tenant = admin.identity.get_tenant_by_name(u['tenant'])
+            tenant = identity.get_tenant_by_name(admin.identity, u['tenant'])
         except lib_exc.NotFound:
             LOG.error("Tenant: %s - not found" % u['tenant'])
             continue
         try:
-            admin.identity.get_user_by_username(tenant['id'], u['name'])
+            identity.get_user_by_username(admin.identity,
+                                          tenant['id'], u['name'])
             LOG.warn("User '%s' already exists in this environment"
                      % u['name'])
         except lib_exc.NotFound:
@@ -365,9 +367,10 @@
 def destroy_users(users):
     admin = keystone_admin()
     for user in users:
-        tenant_id = admin.identity.get_tenant_by_name(user['tenant'])['id']
-        user_id = admin.identity.get_user_by_username(tenant_id,
-                                                      user['name'])['id']
+        tenant_id = identity.get_tenant_by_name(admin.identity,
+                                                user['tenant'])['id']
+        user_id = identity.get_user_by_username(admin.identity,
+                                                tenant_id, user['name'])['id']
         admin.identity.delete_user(user_id)
 
 
@@ -376,10 +379,11 @@
     LOG.info("Collecting users")
     admin = keystone_admin()
     for u in users:
-        tenant = admin.identity.get_tenant_by_name(u['tenant'])
+        tenant = identity.get_tenant_by_name(admin.identity, u['tenant'])
         u['tenant_id'] = tenant['id']
         USERS[u['name']] = u
-        body = admin.identity.get_user_by_username(tenant['id'], u['name'])
+        body = identity.get_user_by_username(admin.identity,
+                                             tenant['id'], u['name'])
         USERS[u['name']]['id'] = body['id']
 
 
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 75639b2..38bde2e 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -118,11 +118,11 @@
         raise exceptions.InvalidConfiguration(msg)
 
     def is_role_available(self, role):
-        msg = "Credentials being specified through the config file can not be"\
-              " used with tests that specify using credentials by roles. "\
-              "Either exclude/skip the tests doing this or use either an "\
-              "test_accounts_file or dynamic credentials."
-        raise exceptions.InvalidConfiguration(msg)
+        # NOTE(andreaf) LegacyCredentialProvider does not support credentials
+        # by role, so returning always False.
+        # Test that rely on credentials by role should use this to skip
+        # when this is credential provider is used
+        return False
 
 
 # Return the right implementation of CredentialProvider based on config
diff --git a/tempest/common/identity.py b/tempest/common/identity.py
new file mode 100644
index 0000000..2179363
--- /dev/null
+++ b/tempest/common/identity.py
@@ -0,0 +1,32 @@
+# Copyright 2015 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_lib import exceptions as lib_exc
+
+
+def get_tenant_by_name(client, tenant_name):
+    tenants = client.list_tenants()['tenants']
+    for tenant in tenants:
+        if tenant['name'] == tenant_name:
+            return tenant
+    raise lib_exc.NotFound('No such tenant(%s) in %s' % (tenant_name, tenants))
+
+
+def get_user_by_username(client, tenant_id, username):
+    users = client.list_tenant_users(tenant_id)['users']
+    for user in users:
+        if user['name'] == username:
+            return user
+    raise lib_exc.NotFound('No such user(%s) in %s' % (username, users))
diff --git a/tempest/config.py b/tempest/config.py
index 26823de..695c15a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -237,10 +237,6 @@
     cfg.StrOpt('image_ssh_password',
                default="password",
                help="Password used to authenticate to an instance."),
-    cfg.StrOpt('image_alt_ssh_user',
-               default="root",
-               help="User name used to authenticate to an instance using "
-                    "the alternate image."),
     cfg.IntOpt('build_interval',
                default=1,
                help="Time in seconds between build status checks."),
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 7c3e830..ee27800 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -1,6 +1,6 @@
-./tempest/services/compute/json/servers_client.py
 ./tempest/services/database/json/flavors_client.py
 ./tempest/services/identity/v3/json/credentials_client.py
+./tempest/services/identity/v3/json/groups_client.py
 ./tempest/services/identity/v3/json/identity_client.py
 ./tempest/services/identity/v3/json/policy_client.py
 ./tempest/services/identity/v3/json/region_client.py
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 9f283c5..147c0ba 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -65,6 +65,7 @@
         cls.networks_client = cls.manager.networks_client
         cls.ports_client = cls.manager.ports_client
         cls.subnets_client = cls.manager.subnets_client
+        cls.floating_ips_client = cls.manager.floating_ips_client
         # Heat client
         cls.orchestration_client = cls.manager.orchestration_client
 
@@ -786,7 +787,7 @@
         if not external_network_id:
             external_network_id = CONF.network.public_network_id
         if not client:
-            client = self.network_client
+            client = self.floating_ips_client
         if not port_id:
             port_id, ip4 = self._get_server_port_id_and_ip4(thing)
         else:
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index fa05577..e629f0a 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -63,15 +63,6 @@
             server_id=self.instance['id'],
             status='ACTIVE')
 
-    def create_remote_file(self, client, filename):
-        """Create a file on the remote client connection.
-
-        After creating the file, force a filesystem sync. Otherwise,
-        if we issue a rebuild too quickly, the file may not exist.
-        """
-        client.exec_command('sudo touch ' + filename)
-        client.exec_command('sync')
-
     def verify_partition(self, client, label, mount, gib_size):
         """Verify a labeled partition's mount point and size."""
         LOG.info("Looking for partition %s mounted on %s" % (label, mount))
@@ -118,7 +109,6 @@
     @test.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
     @test.services('baremetal', 'compute', 'image', 'network')
     def test_baremetal_server_ops(self):
-        test_filename = '/mnt/rebuild_test.txt'
         self.add_keypair()
         self.boot_instance()
         self.validate_ports()
@@ -132,12 +122,13 @@
         # We expect the ephemeral partition to be mounted on /mnt and to have
         # the same size as our flavor definition.
         eph_size = self.get_flavor_ephemeral_size()
-        if eph_size > 0:
+        if eph_size:
             preserve_ephemeral = True
 
             self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
             # Create the test file
-            self.create_remote_file(vm_client, test_filename)
+            timestamp = self.create_timestamp(
+                floating_ip, private_key=self.keypair['private_key'])
         else:
             preserve_ephemeral = False
 
@@ -146,9 +137,9 @@
         self.verify_connectivity()
 
         # Check that we maintained our data
-        if eph_size > 0:
-            vm_client = self.get_remote_client(self.instance)
+        if eph_size:
             self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
-            vm_client.exec_command('ls ' + test_filename)
-
+            timestamp2 = self.get_timestamp(
+                floating_ip, private_key=self.keypair['private_key'])
+            self.assertEqual(timestamp, timestamp2)
         self.terminate_instance()
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index c3f3c78..a5b5a1b 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -37,6 +37,18 @@
     * with and without optional parameters
     * check command outputs
 
+    Steps:
+    1. Create image
+    2. Create keypair
+    3. Boot instance with keypair and get list of instances
+    4. Create volume and show list of volumes
+    5. Attach volume to instance and getlist of volumes
+    6. Add IP to instance
+    7. Create and add security group to instance
+    8. Check SSH connection to instance
+    9. Reboot instance
+    10. Check SSH connection to instance after reboot
+
     """
 
     def _wait_for_server_status(self, server, status):
@@ -130,10 +142,15 @@
         floating_ip = self.create_floating_ip(server)
         self.create_and_add_security_group_to_server(server)
 
+        # check that we can SSH to the server before reboot
         self.linux_client = self.get_remote_client(
             floating_ip['ip'], private_key=keypair['private_key'])
+
         self.nova_reboot(server)
 
+        # check that we can SSH to the server after reboot
+        # (both connections are part of the scenario)
         self.linux_client = self.get_remote_client(
             floating_ip['ip'], private_key=keypair['private_key'])
+
         self.check_partitions()
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 51188d5..6a23c4b 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -283,7 +283,7 @@
         public_network_id = CONF.network.public_network_id
         floating_ip = self.create_floating_ip(
             server, public_network_id,
-            client=tenant.manager.network_client)
+            client=tenant.manager.floating_ips_client)
         self.floating_ips.setdefault(server['id'], floating_ip)
 
     def _create_tenant_network(self, tenant):
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 90b7a2d..49c6da9 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -152,11 +152,11 @@
         return self.action(server_id, 'changePassword',
                            adminPass=adminPass)
 
-    def get_password(self, server_id):
+    def show_password(self, server_id):
         resp, body = self.get("servers/%s/os-server-password" %
                               server_id)
         body = json.loads(body)
-        self.validate_response(schema.get_password, resp, body)
+        self.validate_response(schema.show_password, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def delete_password(self, server_id):
@@ -240,10 +240,10 @@
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
-    def get_server_metadata_item(self, server_id, key):
+    def show_server_metadata_item(self, server_id, key):
         resp, body = self.get("servers/%s/metadata/%s" % (server_id, key))
         body = json.loads(body)
-        self.validate_response(schema.set_get_server_metadata_item,
+        self.validate_response(schema.set_show_server_metadata_item,
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -252,7 +252,7 @@
         resp, body = self.put('servers/%s/metadata/%s' % (server_id, key),
                               post_body)
         body = json.loads(body)
-        self.validate_response(schema.set_get_server_metadata_item,
+        self.validate_response(schema.set_show_server_metadata_item,
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -285,12 +285,12 @@
         self.validate_response(schema.detach_volume, resp, body)
         return service_client.ResponseBody(resp, body)
 
-    def get_volume_attachment(self, server_id, attach_id):
+    def show_volume_attachment(self, server_id, attach_id):
         """Return details about the given volume attachment."""
         resp, body = self.get('servers/%s/os-volume_attachments/%s' % (
             server_id, attach_id))
         body = json.loads(body)
-        self.validate_response(schema.get_volume_attachment, resp, body)
+        self.validate_response(schema.show_volume_attachment, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def list_volume_attachments(self, server_id):
@@ -387,7 +387,7 @@
         """Unrescue the provided server."""
         return self.action(server_id, 'unrescue')
 
-    def get_server_diagnostics(self, server_id):
+    def show_server_diagnostics(self, server_id):
         """Get the usage data for a server."""
         resp, body = self.get("servers/%s/diagnostics" % server_id)
         return service_client.ResponseBody(resp, json.loads(body))
@@ -400,12 +400,12 @@
         self.validate_response(schema.list_instance_actions, resp, body)
         return service_client.ResponseBody(resp, body)
 
-    def get_instance_action(self, server_id, request_id):
+    def show_instance_action(self, server_id, request_id):
         """Returns the action details of the provided server."""
         resp, body = self.get("servers/%s/os-instance-actions/%s" %
                               (server_id, request_id))
         body = json.loads(body)
-        self.validate_response(schema.get_instance_action, resp, body)
+        self.validate_response(schema.show_instance_action, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def force_delete_server(self, server_id, **kwargs):
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index b27f036..dad47b6 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -11,7 +11,6 @@
 #    under the License.
 
 from oslo_serialization import jsonutils as json
-from tempest_lib import exceptions as lib_exc
 
 from tempest.common import service_client
 
@@ -119,13 +118,6 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_tenant_by_name(self, tenant_name):
-        tenants = self.list_tenants()['tenants']
-        for tenant in tenants:
-            if tenant['name'] == tenant_name:
-                return tenant
-        raise lib_exc.NotFound('No such tenant')
-
     def update_tenant(self, tenant_id, **kwargs):
         """Updates a tenant."""
         body = self.show_tenant(tenant_id)['tenant']
@@ -220,13 +212,6 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_user_by_username(self, tenant_id, username):
-        users = self.list_tenant_users(tenant_id)['users']
-        for user in users:
-            if user['name'] == username:
-                return user
-        raise lib_exc.NotFound('No such user')
-
     def create_service(self, name, type, **kwargs):
         """Create a service."""
         post_body = {
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/services/identity/v3/json/groups_client.py
new file mode 100644
index 0000000..5bd610d
--- /dev/null
+++ b/tempest/services/identity/v3/json/groups_client.py
@@ -0,0 +1,94 @@
+# 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.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class GroupsClient(service_client.ServiceClient):
+    api_version = "v3"
+
+    def create_group(self, name, **kwargs):
+        """Creates a group."""
+        description = kwargs.get('description', None)
+        domain_id = kwargs.get('domain_id', 'default')
+        project_id = kwargs.get('project_id', None)
+        post_body = {
+            'description': description,
+            'domain_id': domain_id,
+            'project_id': project_id,
+            'name': name
+        }
+        post_body = json.dumps({'group': post_body})
+        resp, body = self.post('groups', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def get_group(self, group_id):
+        """Get group details."""
+        resp, body = self.get('groups/%s' % group_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_groups(self):
+        """Lists the groups."""
+        resp, body = self.get('groups')
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def update_group(self, group_id, **kwargs):
+        """Updates a group."""
+        body = self.get_group(group_id)['group']
+        name = kwargs.get('name', body['name'])
+        description = kwargs.get('description', body['description'])
+        post_body = {
+            'name': name,
+            'description': description
+        }
+        post_body = json.dumps({'group': post_body})
+        resp, body = self.patch('groups/%s' % group_id, post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_group(self, group_id):
+        """Delete a group."""
+        resp, body = self.delete('groups/%s' % str(group_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def add_group_user(self, group_id, user_id):
+        """Add user into group."""
+        resp, body = self.put('groups/%s/users/%s' % (group_id, user_id),
+                              None)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def list_group_users(self, group_id):
+        """List users in group."""
+        resp, body = self.get('groups/%s/users' % group_id)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_group_user(self, group_id, user_id):
+        """Delete user in group."""
+        resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index f7913d0..a26544e 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -299,72 +299,6 @@
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def create_group(self, name, **kwargs):
-        """Creates a group."""
-        description = kwargs.get('description', None)
-        domain_id = kwargs.get('domain_id', 'default')
-        project_id = kwargs.get('project_id', None)
-        post_body = {
-            'description': description,
-            'domain_id': domain_id,
-            'project_id': project_id,
-            'name': name
-        }
-        post_body = json.dumps({'group': post_body})
-        resp, body = self.post('groups', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def get_group(self, group_id):
-        """Get group details."""
-        resp, body = self.get('groups/%s' % group_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_groups(self):
-        """Lists the groups."""
-        resp, body = self.get('groups')
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def update_group(self, group_id, **kwargs):
-        """Updates a group."""
-        body = self.get_group(group_id)['group']
-        name = kwargs.get('name', body['name'])
-        description = kwargs.get('description', body['description'])
-        post_body = {
-            'name': name,
-            'description': description
-        }
-        post_body = json.dumps({'group': post_body})
-        resp, body = self.patch('groups/%s' % group_id, post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_group(self, group_id):
-        """Delete a group."""
-        resp, body = self.delete('groups/%s' % str(group_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def add_group_user(self, group_id, user_id):
-        """Add user into group."""
-        resp, body = self.put('groups/%s/users/%s' % (group_id, user_id),
-                              None)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def list_group_users(self, group_id):
-        """List users in group."""
-        resp, body = self.get('groups/%s/users' % group_id)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
     def list_user_groups(self, user_id):
         """Lists groups which a user belongs to."""
         resp, body = self.get('users/%s/groups' % user_id)
@@ -372,12 +306,6 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def delete_group_user(self, group_id, user_id):
-        """Delete user in group."""
-        resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
     def assign_user_role_on_project(self, project_id, user_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/users/%s/roles/%s' %
diff --git a/tempest/services/network/json/floating_ips_client.py b/tempest/services/network/json/floating_ips_client.py
new file mode 100644
index 0000000..5c490ed
--- /dev/null
+++ b/tempest/services/network/json/floating_ips_client.py
@@ -0,0 +1,38 @@
+#    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.services.network.json import base
+
+
+class FloatingIPsClient(base.BaseNetworkClient):
+
+    def create_floatingip(self, **kwargs):
+        uri = '/floatingips'
+        post_data = {'floatingip': kwargs}
+        return self.create_resource(uri, post_data)
+
+    def update_floatingip(self, floatingip_id, **kwargs):
+        uri = '/floatingips/%s' % floatingip_id
+        post_data = {'floatingip': kwargs}
+        return self.update_resource(uri, post_data)
+
+    def show_floatingip(self, floatingip_id, **fields):
+        uri = '/floatingips/%s' % floatingip_id
+        return self.show_resource(uri, **fields)
+
+    def delete_floatingip(self, floatingip_id):
+        uri = '/floatingips/%s' % floatingip_id
+        return self.delete_resource(uri)
+
+    def list_floatingips(self, **filters):
+        uri = '/floatingips'
+        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 50a5d5e..5a4229c 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -35,28 +35,6 @@
     quotas
     """
 
-    def create_floatingip(self, **kwargs):
-        uri = '/floatingips'
-        post_data = {'floatingip': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_floatingip(self, floatingip_id, **kwargs):
-        uri = '/floatingips/%s' % floatingip_id
-        post_data = {'floatingip': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_floatingip(self, floatingip_id, **fields):
-        uri = '/floatingips/%s' % floatingip_id
-        return self.show_resource(uri, **fields)
-
-    def delete_floatingip(self, floatingip_id):
-        uri = '/floatingips/%s' % floatingip_id
-        return self.delete_resource(uri)
-
-    def list_floatingips(self, **filters):
-        uri = '/floatingips'
-        return self.list_resources(uri, **filters)
-
     def create_metering_label(self, **kwargs):
         uri = '/metering/metering-labels'
         post_data = {'metering_label': kwargs}
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index fc3d984..d328d56 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -106,10 +106,12 @@
         self.assertFalse(mocked_function.called)
 
     def test_create_users(self):
-        self.fake_client.identity.get_tenant_by_name.return_value = \
-            self.fake_object['tenant']
-        self.fake_client.identity.get_user_by_username.side_effect = \
-            lib_exc.NotFound("user is not found")
+        self.useFixture(mockpatch.Patch(
+                        'tempest.common.identity.get_tenant_by_name',
+                        return_value=self.fake_object['tenant']))
+        self.useFixture(mockpatch.Patch(
+                        'tempest.common.identity.get_user_by_username',
+                        side_effect=lib_exc.NotFound("user is not found")))
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=self.fake_client))
 
@@ -125,8 +127,9 @@
                                                 enabled=True)
 
     def test_create_user_missing_tenant(self):
-        self.fake_client.identity.get_tenant_by_name.side_effect = \
-            lib_exc.NotFound("tenant is not found")
+        self.useFixture(mockpatch.Patch(
+                        'tempest.common.identity.get_tenant_by_name',
+                        side_effect=lib_exc.NotFound("tenant is not found")))
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=self.fake_client))
 
@@ -289,8 +292,9 @@
 
         fake_tenant = self.fake_object['tenant']
         fake_auth = self.fake_client
-        fake_auth.identity.get_tenant_by_name.return_value = fake_tenant
-
+        self.useFixture(mockpatch.Patch(
+                        'tempest.common.identity.get_tenant_by_name',
+                        return_value=fake_tenant))
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=fake_auth))
         javelin.destroy_tenants([fake_tenant])
@@ -304,9 +308,13 @@
         fake_tenant = self.fake_object['tenant']
 
         fake_auth = self.fake_client
-        fake_auth.identity.get_tenant_by_name.return_value = fake_tenant
-        fake_auth.identity.get_user_by_username.return_value = fake_user
+        fake_auth.identity.list_tenants.return_value = \
+            {'tenants': [fake_tenant]}
+        fake_auth.identity.list_users.return_value = {'users': [fake_user]}
 
+        self.useFixture(mockpatch.Patch(
+                        'tempest.common.identity.get_user_by_username',
+                        return_value=fake_user))
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=fake_auth))
 
diff --git a/test-requirements.txt b/test-requirements.txt
index db2b2ce..5b01ea9 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,7 +5,7 @@
 # needed for doc build
 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
 python-subunit>=0.0.18
-oslosphinx>=2.5.0 # Apache-2.0
+oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
 mox>=0.5.3
 mock>=1.2
 coverage>=3.6