Merge "Fix AttributeError in multinode jobs"
diff --git a/HACKING.rst b/HACKING.rst
index 3799046..9f7487d 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -17,6 +17,7 @@
 - [T108] Check no hyphen at the end of rand_name() argument
 - [T109] Cannot use testtools.skip decorator; instead use
          decorators.skip_because from tempest-lib
+- [T110] Check that service client names of GET should be consistent
 - [N322] Method's default argument shouldn't be mutable
 
 Test Data/Configuration
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 1b36ff2..5b02761 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -17,11 +17,10 @@
 from tempest import test
 
 
-class AZAdminV2TestJSON(base.BaseComputeAdminTest):
+class AZAdminV2TestJSON(base.BaseV2ComputeAdminTest):
     """
     Tests Availability Zone API List
     """
-    _api_version = 2
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 1da3f6e..c4aa81b 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -20,8 +20,7 @@
 CONF = config.CONF
 
 
-class NetworksTest(base.BaseComputeAdminTest):
-    _api_version = 2
+class NetworksTest(base.BaseV2ComputeAdminTest):
 
     """
     Tests Nova Networks API that usually requires admin privileges.
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index b3f69c1..b006fc0 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -22,7 +22,6 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
-from tempest import exceptions
 import tempest.test
 
 CONF = config.CONF
@@ -30,10 +29,9 @@
 LOG = logging.getLogger(__name__)
 
 
-class BaseComputeTest(tempest.test.BaseTestCase):
+class BaseV2ComputeTest(tempest.test.BaseTestCase):
     """Base test case class for all Compute API tests."""
 
-    _api_version = 2
     force_tenant_isolation = False
 
     # TODO(andreaf) We should care also for the alt_manager here
@@ -42,29 +40,25 @@
 
     @classmethod
     def skip_checks(cls):
-        super(BaseComputeTest, cls).skip_checks()
+        super(BaseV2ComputeTest, cls).skip_checks()
         if not CONF.service_available.nova:
             raise cls.skipException("Nova is not available")
-        if cls._api_version != 2:
-            msg = ("Unexpected API version is specified (%s)" %
-                   cls._api_version)
-            raise exceptions.InvalidConfiguration(message=msg)
 
     @classmethod
     def setup_credentials(cls):
         cls.set_network_resources()
-        super(BaseComputeTest, cls).setup_credentials()
+        super(BaseV2ComputeTest, cls).setup_credentials()
 
     @classmethod
     def setup_clients(cls):
-        super(BaseComputeTest, cls).setup_clients()
+        super(BaseV2ComputeTest, cls).setup_clients()
         cls.servers_client = cls.os.servers_client
         cls.server_groups_client = cls.os.server_groups_client
         cls.flavors_client = cls.os.flavors_client
         cls.images_client = cls.os.images_client
         cls.extensions_client = cls.os.extensions_client
         cls.floating_ip_pools_client = cls.os.floating_ip_pools_client
-        cls.floating_ips_client = cls.os.floating_ips_client
+        cls.floating_ips_client = cls.os.compute_floating_ips_client
         cls.keypairs_client = cls.os.keypairs_client
         cls.security_group_rules_client = cls.os.security_group_rules_client
         cls.security_groups_client = cls.os.security_groups_client
@@ -96,7 +90,7 @@
 
     @classmethod
     def resource_setup(cls):
-        super(BaseComputeTest, cls).resource_setup()
+        super(BaseV2ComputeTest, cls).resource_setup()
         cls.build_interval = CONF.compute.build_interval
         cls.build_timeout = CONF.compute.build_timeout
         cls.ssh_user = CONF.compute.ssh_user
@@ -117,7 +111,7 @@
         cls.clear_servers()
         cls.clear_security_groups()
         cls.clear_server_groups()
-        super(BaseComputeTest, cls).resource_cleanup()
+        super(BaseV2ComputeTest, cls).resource_cleanup()
 
     @classmethod
     def clear_servers(cls):
@@ -356,22 +350,13 @@
         return ip_or_server
 
 
-class BaseV2ComputeTest(BaseComputeTest):
-    _api_version = 2
-
-
-class BaseComputeAdminTest(BaseComputeTest):
+class BaseV2ComputeAdminTest(BaseV2ComputeTest):
     """Base test case class for Compute Admin API tests."""
 
     credentials = ['primary', 'admin']
 
     @classmethod
     def setup_clients(cls):
-        super(BaseComputeAdminTest, cls).setup_clients()
+        super(BaseV2ComputeAdminTest, cls).setup_clients()
         cls.availability_zone_admin_client = (
             cls.os_adm.availability_zone_client)
-
-
-class BaseV2ComputeAdminTest(BaseComputeAdminTest):
-    """Base test case class for Compute Admin V2 API tests."""
-    _api_version = 2
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 0096fc2..d5c7302 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -20,9 +20,7 @@
 CONF = config.CONF
 
 
-class CertificatesV2TestJSON(base.BaseComputeTest):
-
-    _api_version = 2
+class CertificatesV2TestJSON(base.BaseV2ComputeTest):
 
     @classmethod
     def skip_checks(cls):
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index e114c80..7e01296 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -17,9 +17,7 @@
 from tempest import test
 
 
-class FlavorsV2TestJSON(base.BaseComputeTest):
-
-    _api_version = 2
+class FlavorsV2TestJSON(base.BaseV2ComputeTest):
     _min_disk = 'minDisk'
     _min_ram = 'minRam'
 
diff --git a/tempest/api/compute/keypairs/base.py b/tempest/api/compute/keypairs/base.py
index 76e5573..15f231b 100644
--- a/tempest/api/compute/keypairs/base.py
+++ b/tempest/api/compute/keypairs/base.py
@@ -16,11 +16,9 @@
 from tempest.api.compute import base
 
 
-class BaseKeypairTest(base.BaseComputeTest):
+class BaseKeypairTest(base.BaseV2ComputeTest):
     """Base test case class for all keypair API tests."""
 
-    _api_version = 2
-
     @classmethod
     def setup_clients(cls):
         super(BaseKeypairTest, cls).setup_clients()
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 080441a..8f1f360 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -17,11 +17,10 @@
 from tempest import test
 
 
-class AZV2TestJSON(base.BaseComputeTest):
+class AZV2TestJSON(base.BaseV2ComputeTest):
     """
     Tests Availability Zone API List
     """
-    _api_version = 2
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 902b72c..f51c2db 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -150,7 +150,7 @@
                                          wait_until='ACTIVE')
 
         # Check a server is in the group
-        server_group = (self.server_groups_client.get_server_group(group_id)
+        server_group = (self.server_groups_client.show_server_group(group_id)
                         ['server_group'])
         self.assertIn(server['id'], server_group['members'])
 
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index 0da7912..9a04556 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -104,9 +104,9 @@
             self._delete_server_group(server_groups[i])
 
     @test.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
-    def test_get_server_group(self):
+    def test_show_server_group(self):
         # Get the server-group
-        body = self.client.get_server_group(
+        body = self.client.show_server_group(
             self.created_server_group['id'])['server_group']
         self.assertEqual(self.created_server_group, body)
 
diff --git a/tempest/api/compute/test_versions.py b/tempest/api/compute/test_versions.py
index f94cee6..8b84a21 100644
--- a/tempest/api/compute/test_versions.py
+++ b/tempest/api/compute/test_versions.py
@@ -16,7 +16,7 @@
 from tempest import test
 
 
-class TestVersions(base.BaseComputeTest):
+class TestVersions(base.BaseV2ComputeTest):
 
     @test.idempotent_id('6c0a0990-43b6-4529-9b61-5fd8daf7c55c')
     def test_list_api_versions(self):
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index d22b27f..048c53a 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -53,11 +53,11 @@
     @test.attr(type='smoke')
     @test.idempotent_id('7cd59bf9-bda4-4c72-9467-d21cab278355')
     def test_credentials_create_get_update_delete(self):
-        keys = [data_utils.rand_name('Access'),
-                data_utils.rand_name('Secret')]
+        blob = '{"access": "%s", "secret": "%s"}' % (
+            data_utils.rand_name('Access'), data_utils.rand_name('Secret'))
         cred = self.creds_client.create_credential(
-            keys[0], keys[1], self.user_body['id'],
-            self.projects[0])['credential']
+            user_id=self.user_body['id'], project_id=self.projects[0],
+            blob=blob, type='ec2')['credential']
         self.addCleanup(self._delete_credential, cred['id'])
         for value1 in self.creds_list[0]:
             self.assertIn(value1, cred)
@@ -66,9 +66,10 @@
 
         new_keys = [data_utils.rand_name('NewAccess'),
                     data_utils.rand_name('NewSecret')]
+        blob = '{"access": "%s", "secret": "%s"}' % (new_keys[0], new_keys[1])
         update_body = self.creds_client.update_credential(
-            cred['id'], access_key=new_keys[0], secret_key=new_keys[1],
-            project_id=self.projects[1])['credential']
+            cred['id'], blob=blob, project_id=self.projects[1],
+            type='ec2')['credential']
         self.assertEqual(cred['id'], update_body['id'])
         self.assertEqual(self.projects[1], update_body['project_id'])
         self.assertEqual(self.user_body['id'], update_body['user_id'])
@@ -89,10 +90,11 @@
         fetched_cred_ids = list()
 
         for i in range(2):
+            blob = '{"access": "%s", "secret": "%s"}' % (
+                data_utils.rand_name('Access'), data_utils.rand_name('Secret'))
             cred = self.creds_client.create_credential(
-                data_utils.rand_name('Access'),
-                data_utils.rand_name('Secret'),
-                self.user_body['id'], self.projects[0])['credential']
+                user_id=self.user_body['id'], project_id=self.projects[0],
+                blob=blob, type='ec2')['credential']
             created_cred_ids.append(cred['id'])
             self.addCleanup(self._delete_credential, cred['id'])
 
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index e44a96b..2fd7369 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -45,8 +45,10 @@
             region = data_utils.rand_name('region')
             url = data_utils.rand_url()
             interface = 'public'
-            endpoint = (cls.client.create_endpoint(cls.service_id, interface,
-                        url, region=region, enabled=True))['endpoint']
+            endpoint = cls.client.create_endpoint(service_id=cls.service_id,
+                                                  interface=interface,
+                                                  url=url, region=region,
+                                                  enabled=True)['endpoint']
             cls.setup_endpoints.append(endpoint)
 
     @classmethod
@@ -73,8 +75,10 @@
         region = data_utils.rand_name('region')
         url = data_utils.rand_url()
         interface = 'public'
-        endpoint = (self.client.create_endpoint(self.service_id, interface,
-                    url, region=region, enabled=True)['endpoint'])
+        endpoint = self.client.create_endpoint(service_id=self.service_id,
+                                               interface=interface,
+                                               url=url, region=region,
+                                               enabled=True)['endpoint']
         # Asserting Create Endpoint response body
         self.assertIn('id', endpoint)
         self.assertEqual(region, endpoint['region'])
@@ -98,10 +102,11 @@
         region1 = data_utils.rand_name('region')
         url1 = data_utils.rand_url()
         interface1 = 'public'
-        endpoint_for_update =\
-            self.client.create_endpoint(self.service_id, interface1,
-                                        url1, region=region1,
-                                        enabled=True)['endpoint']
+        endpoint_for_update = (
+            self.client.create_endpoint(service_id=self.service_id,
+                                        interface=interface1,
+                                        url=url1, region=region1,
+                                        enabled=True)['endpoint'])
         self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
         # Creating service so as update endpoint with new service ID
         s_name = data_utils.rand_name('service')
@@ -116,12 +121,11 @@
         region2 = data_utils.rand_name('region')
         url2 = data_utils.rand_url()
         interface2 = 'internal'
-        endpoint = \
-            self.client.update_endpoint(endpoint_for_update['id'],
-                                        service_id=service2['id'],
-                                        interface=interface2, url=url2,
-                                        region=region2,
-                                        enabled=False)['endpoint']
+        endpoint = self.client.update_endpoint(endpoint_for_update['id'],
+                                               service_id=service2['id'],
+                                               interface=interface2,
+                                               url=url2, region=region2,
+                                               enabled=False)['endpoint']
         # Asserting if the attributes of endpoint are updated
         self.assertEqual(service2['id'], endpoint['service_id'])
         self.assertEqual(interface2, endpoint['interface'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 8cf853b..5aa90a5 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -57,8 +57,8 @@
         url = data_utils.rand_url()
         region = data_utils.rand_name('region')
         self.assertRaises(lib_exc.BadRequest, self.client.create_endpoint,
-                          self.service_id, interface, url, region=region,
-                          force_enabled='False')
+                          service_id=self.service_id, interface=interface,
+                          url=url, region=region, enabled='False')
 
     @test.attr(type=['negative'])
     @test.idempotent_id('9c43181e-0627-484a-8c79-923e8a59598b')
@@ -68,8 +68,8 @@
         url = data_utils.rand_url()
         region = data_utils.rand_name('region')
         self.assertRaises(lib_exc.BadRequest, self.client.create_endpoint,
-                          self.service_id, interface, url, region=region,
-                          force_enabled='True')
+                          service_id=self.service_id, interface=interface,
+                          url=url, region=region, enabled='True')
 
     def _assert_update_raises_bad_request(self, enabled):
 
@@ -78,13 +78,14 @@
         url1 = data_utils.rand_url()
         interface1 = 'public'
         endpoint_for_update = (
-            self.client.create_endpoint(self.service_id, interface1,
-                                        url1, region=region1,
-                                        enabled=True))['endpoint']
+            self.client.create_endpoint(service_id=self.service_id,
+                                        interface=interface1,
+                                        url=url1, region=region1,
+                                        enabled=True)['endpoint'])
         self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
 
         self.assertRaises(lib_exc.BadRequest, self.client.update_endpoint,
-                          endpoint_for_update['id'], force_enabled=enabled)
+                          endpoint_for_update['id'], enabled=enabled)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('65e41f32-5eb7-498f-a92a-a6ccacf7439a')
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index d079fec..44e5c7b 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -31,8 +31,8 @@
         for _ in range(3):
             blob = data_utils.rand_name('BlobName')
             policy_type = data_utils.rand_name('PolicyType')
-            policy = self.policy_client.create_policy(blob,
-                                                      policy_type)['policy']
+            policy = self.policy_client.create_policy(
+                blob=blob, type=policy_type)['policy']
             # Delete the Policy at the end of this method
             self.addCleanup(self._delete_policy, policy['id'])
             policy_ids.append(policy['id'])
@@ -49,7 +49,8 @@
         # Test to update policy
         blob = data_utils.rand_name('BlobName')
         policy_type = data_utils.rand_name('PolicyType')
-        policy = self.policy_client.create_policy(blob, policy_type)['policy']
+        policy = self.policy_client.create_policy(blob=blob,
+                                                  type=policy_type)['policy']
         self.addCleanup(self._delete_policy, policy['id'])
         self.assertIn('id', policy)
         self.assertIn('type', policy)
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index e96e0f5..0dbbae0 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -33,7 +33,8 @@
         cls.setup_regions = list()
         for i in range(2):
             r_description = data_utils.rand_name('description')
-            region = cls.client.create_region(r_description)['region']
+            region = cls.client.create_region(
+                description=r_description)['region']
             cls.setup_regions.append(region)
 
     @classmethod
@@ -51,7 +52,7 @@
     def test_create_update_get_delete_region(self):
         r_description = data_utils.rand_name('description')
         region = self.client.create_region(
-            r_description,
+            description=r_description,
             parent_region_id=self.setup_regions[0]['id'])['region']
         self.addCleanup(self._delete_region, region['id'])
         self.assertEqual(r_description, region['description'])
@@ -79,7 +80,7 @@
         r_region_id = data_utils.rand_uuid()
         r_description = data_utils.rand_name('description')
         region = self.client.create_region(
-            r_description, unique_region_id=r_region_id)['region']
+            region_id=r_region_id, description=r_description)['region']
         self.addCleanup(self._delete_region, region['id'])
         # Asserting Create Region with specific id response body
         self.assertEqual(r_region_id, region['id'])
diff --git a/tempest/api_schema/response/compute/v2_1/servers.py b/tempest/api_schema/response/compute/v2_1/servers.py
index 44ab9e9..9593f3c 100644
--- a/tempest/api_schema/response/compute/v2_1/servers.py
+++ b/tempest/api_schema/response/compute/v2_1/servers.py
@@ -351,7 +351,7 @@
     'required': ['id', 'name', 'policies', 'members', 'metadata']
 }
 
-create_get_server_group = {
+create_show_server_group = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
diff --git a/tempest/clients.py b/tempest/clients.py
index e8a9fd5..6d25369 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -47,7 +47,7 @@
     BaremetalClient
 from tempest.services import botoclients
 from tempest.services.compute.json.floating_ips_client import \
-    FloatingIPsClient
+    FloatingIPsClient as ComputeFloatingIPsClient
 from tempest.services.compute.json.images_client import ImagesClient
 from tempest.services.compute.json.instance_usage_audit_log_client import \
     InstanceUsagesAuditLogClient
@@ -316,8 +316,8 @@
             self.auth_provider, **params)
         self.floating_ips_bulk_client = FloatingIPsBulkClient(
             self.auth_provider, **params)
-        self.floating_ips_client = FloatingIPsClient(self.auth_provider,
-                                                     **params)
+        self.compute_floating_ips_client = ComputeFloatingIPsClient(
+            self.auth_provider, **params)
         self.security_group_rules_client = SecurityGroupRulesClient(
             self.auth_provider, **params)
         self.security_groups_client = SecurityGroupsClient(
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 8b1e550..40a079c 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -294,7 +294,7 @@
 class FloatingIpService(BaseService):
     def __init__(self, manager, **kwargs):
         super(FloatingIpService, self).__init__(kwargs)
-        self.client = manager.floating_ips_client
+        self.client = manager.compute_floating_ips_client
 
     def list(self):
         client = self.client
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 41b0529..6fc3843 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -127,7 +127,7 @@
 
     # The name of the method to associate a floating IP to as server is too
     # long for PEP8 compliance so:
-    assoc = clients.floating_ips_client.associate_floating_ip_to_server
+    assoc = clients.compute_floating_ips_client.associate_floating_ip_to_server
 
     if wait_until:
         for server in servers:
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
index debc200..1908b68 100644
--- a/tempest/common/validation_resources.py
+++ b/tempest/common/validation_resources.py
@@ -58,7 +58,7 @@
             validation_data['security_group'] = \
                 create_ssh_security_group(os, add_rule)
         if validation_resources['floating_ip']:
-            floating_client = os.floating_ips_client
+            floating_client = os.compute_floating_ips_client
             validation_data.update(floating_client.create_floating_ip())
     return validation_data
 
@@ -100,7 +100,7 @@
                 if not has_exception:
                     has_exception = exc
         if 'floating_ip' in validation_data:
-            floating_client = os.floating_ips_client
+            floating_client = os.compute_floating_ips_client
             fip_id = validation_data['floating_ip']['id']
             try:
                 floating_client.delete_floating_ip(fip_id)
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 06ca09b..936fbe8 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -30,6 +30,9 @@
 RAND_NAME_HYPHEN_RE = re.compile(r".*rand_name\(.+[\-\_][\"\']\)")
 mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
 TESTTOOLS_SKIP_DECORATOR = re.compile(r'\s*@testtools\.skip\((.*)\)')
+METHOD = re.compile(r"^    def .+")
+METHOD_GET_RESOURCE = re.compile(r"^\s*def (list|show)\_.+")
+CLASS = re.compile(r"^class .+")
 
 
 def import_no_clients_in_api_and_scenario_tests(physical_line, filename):
@@ -143,6 +146,45 @@
                "decorators.skip_because from tempest-lib")
 
 
+def get_resources_on_service_clients(logical_line, physical_line, filename,
+                                     line_number, lines):
+    """Check that service client names of GET should be consistent
+
+    T110
+    """
+    if 'tempest/services/' not in filename:
+        return
+
+    ignored_list = []
+    with open('tempest/hacking/ignored_list_T110.txt') as f:
+        for line in f:
+            ignored_list.append(line.strip())
+
+    if filename in ignored_list:
+        return
+
+    if not METHOD.match(physical_line):
+        return
+
+    if pep8.noqa(physical_line):
+        return
+
+    for line in lines[line_number:]:
+        if METHOD.match(line) or CLASS.match(line):
+            # the end of a method
+            return
+
+        if 'self.get(' not in line:
+            continue
+
+        if METHOD_GET_RESOURCE.match(logical_line):
+            return
+
+        msg = ("T110: [GET /resources] methods should be list_<resource name>s"
+               " or show_<resource name>")
+        yield (0, msg)
+
+
 def factory(register):
     register(import_no_clients_in_api_and_scenario_tests)
     register(scenario_tests_need_service_tags)
@@ -152,3 +194,4 @@
     register(no_hyphen_at_end_of_rand_name)
     register(no_mutable_default_args)
     register(no_testtools_skip_decorator)
+    register(get_resources_on_service_clients)
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
new file mode 100644
index 0000000..987861f
--- /dev/null
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -0,0 +1,14 @@
+./tempest/services/compute/json/server_groups_client.py
+./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/identity_client.py
+./tempest/services/identity/v3/json/policy_client.py
+./tempest/services/identity/v3/json/region_client.py
+./tempest/services/messaging/json/messaging_client.py
+./tempest/services/object_storage/object_client.py
+./tempest/services/telemetry/json/telemetry_client.py
+./tempest/services/volume/json/qos_client.py
+./tempest/services/volume/json/backups_client.py
+./tempest/services/image/v2/json/image_client.py
+./tempest/services/baremetal/base.py
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 6548d28..ffeda1b 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -47,7 +47,8 @@
         super(ScenarioTest, cls).setup_clients()
         # Clients (in alphabetical order)
         cls.flavors_client = cls.manager.flavors_client
-        cls.floating_ips_client = cls.manager.floating_ips_client
+        cls.compute_floating_ips_client = (
+            cls.manager.compute_floating_ips_client)
         # Glance image client v1
         cls.image_client = cls.manager.image_client
         # Compute image client
@@ -565,12 +566,12 @@
         Nova clients
         """
 
-        floating_ip = (self.floating_ips_client.create_floating_ip(pool_name)
-                       ['floating_ip'])
+        floating_ip = (self.compute_floating_ips_client.
+                       create_floating_ip(pool_name)['floating_ip'])
         self.addCleanup(self.delete_wrapper,
-                        self.floating_ips_client.delete_floating_ip,
+                        self.compute_floating_ips_client.delete_floating_ip,
                         floating_ip['id'])
-        self.floating_ips_client.associate_floating_ip_to_server(
+        self.compute_floating_ips_client.associate_floating_ip_to_server(
             floating_ip['ip'], thing['id'])
         return floating_ip
 
diff --git a/tempest/services/compute/json/server_groups_client.py b/tempest/services/compute/json/server_groups_client.py
index 62258d3..7284e02 100644
--- a/tempest/services/compute/json/server_groups_client.py
+++ b/tempest/services/compute/json/server_groups_client.py
@@ -32,7 +32,7 @@
         resp, body = self.post('os-server-groups', post_body)
 
         body = json.loads(body)
-        self.validate_response(schema.create_get_server_group, resp, body)
+        self.validate_response(schema.create_show_server_group, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def delete_server_group(self, server_group_id):
@@ -48,9 +48,9 @@
         self.validate_response(schema.list_server_groups, resp, body)
         return service_client.ResponseBody(resp, body)
 
-    def get_server_group(self, server_group_id):
+    def show_server_group(self, server_group_id):
         """Get the details of given server_group."""
         resp, body = self.get("os-server-groups/%s" % server_group_id)
         body = json.loads(body)
-        self.validate_response(schema.create_get_server_group, resp, body)
+        self.validate_response(schema.create_show_server_group, resp, body)
         return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/services/identity/v3/json/credentials_client.py
index decf3a8..7d4cf9a 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/services/identity/v3/json/credentials_client.py
@@ -13,6 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+"""
+http://developer.openstack.org/api-ref-identity-v3.html#credentials-v3
+"""
+
 from oslo_serialization import jsonutils as json
 
 from tempest.common import service_client
@@ -21,17 +25,13 @@
 class CredentialsClient(service_client.ServiceClient):
     api_version = "v3"
 
-    def create_credential(self, access_key, secret_key, user_id, project_id):
-        """Creates a credential."""
-        blob = "{\"access\": \"%s\", \"secret\": \"%s\"}" % (
-            access_key, secret_key)
-        post_body = {
-            "blob": blob,
-            "project_id": project_id,
-            "type": "ec2",
-            "user_id": user_id
-        }
-        post_body = json.dumps({'credential': post_body})
+    def create_credential(self, **kwargs):
+        """Creates a credential.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#createCredential
+        """
+        post_body = json.dumps({'credential': kwargs})
         resp, body = self.post('credentials', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
@@ -39,22 +39,12 @@
         return service_client.ResponseBody(resp, body)
 
     def update_credential(self, credential_id, **kwargs):
-        """Updates a credential."""
-        body = self.get_credential(credential_id)['credential']
-        cred_type = kwargs.get('type', body['type'])
-        access_key = kwargs.get('access_key', body['blob']['access'])
-        secret_key = kwargs.get('secret_key', body['blob']['secret'])
-        project_id = kwargs.get('project_id', body['project_id'])
-        user_id = kwargs.get('user_id', body['user_id'])
-        blob = "{\"access\": \"%s\", \"secret\": \"%s\"}" % (
-            access_key, secret_key)
-        post_body = {
-            "blob": blob,
-            "project_id": project_id,
-            "type": cred_type,
-            "user_id": user_id
-        }
-        post_body = json.dumps({'credential': post_body})
+        """Updates a credential.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#updateCredential
+        """
+        post_body = json.dumps({'credential': kwargs})
         resp, body = self.patch('credentials/%s' % credential_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index 6bdf8b3..ede5edb 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -13,6 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+"""
+http://developer.openstack.org/api-ref-identity-v3.html#endpoints-v3
+"""
+
 from oslo_serialization import jsonutils as json
 
 from tempest.common import service_client
@@ -28,53 +32,25 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def create_endpoint(self, service_id, interface, url, **kwargs):
+    def create_endpoint(self, **kwargs):
         """Create endpoint.
 
-        Normally this function wouldn't allow setting values that are not
-        allowed for 'enabled'. Use `force_enabled` to set a non-boolean.
-
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#createEndpoint
         """
-        region = kwargs.get('region', None)
-        if 'force_enabled' in kwargs:
-            enabled = kwargs.get('force_enabled', None)
-        else:
-            enabled = kwargs.get('enabled', None)
-        post_body = {
-            'service_id': service_id,
-            'interface': interface,
-            'url': url,
-            'region': region,
-            'enabled': enabled
-        }
-        post_body = json.dumps({'endpoint': post_body})
+        post_body = json.dumps({'endpoint': kwargs})
         resp, body = self.post('endpoints', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def update_endpoint(self, endpoint_id, service_id=None, interface=None,
-                        url=None, region=None, enabled=None, **kwargs):
+    def update_endpoint(self, endpoint_id, **kwargs):
         """Updates an endpoint with given parameters.
 
-        Normally this function wouldn't allow setting values that are not
-        allowed for 'enabled'. Use `force_enabled` to set a non-boolean.
-
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#updateEndpoint
         """
-        post_body = {}
-        if service_id is not None:
-            post_body['service_id'] = service_id
-        if interface is not None:
-            post_body['interface'] = interface
-        if url is not None:
-            post_body['url'] = url
-        if region is not None:
-            post_body['region'] = region
-        if 'force_enabled' in kwargs:
-            post_body['enabled'] = kwargs['force_enabled']
-        elif enabled is not None:
-            post_body['enabled'] = enabled
-        post_body = json.dumps({'endpoint': post_body})
+        post_body = json.dumps({'endpoint': kwargs})
         resp, body = self.patch('endpoints/%s' % endpoint_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
diff --git a/tempest/services/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index 3231bb0..ecc9df7 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -13,6 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+"""
+http://developer.openstack.org/api-ref-identity-v3.html#policies-v3
+"""
+
 from oslo_serialization import jsonutils as json
 
 from tempest.common import service_client
@@ -21,13 +25,13 @@
 class PolicyClient(service_client.ServiceClient):
     api_version = "v3"
 
-    def create_policy(self, blob, type):
-        """Creates a Policy."""
-        post_body = {
-            "blob": blob,
-            "type": type
-        }
-        post_body = json.dumps({'policy': post_body})
+    def create_policy(self, **kwargs):
+        """Creates a Policy.
+
+        Available params: see http://developer.openstack.org/
+                          api-ref-identity-v3.html#createPolicy
+        """
+        post_body = json.dumps({'policy': kwargs})
         resp, body = self.post('policies', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
@@ -49,12 +53,12 @@
         return service_client.ResponseBody(resp, body)
 
     def update_policy(self, policy_id, **kwargs):
-        """Updates a policy."""
-        type = kwargs.get('type')
-        post_body = {
-            'type': type
-        }
-        post_body = json.dumps({'policy': post_body})
+        """Updates a policy.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#updatePolicy
+        """
+        post_body = json.dumps({'policy': kwargs})
         url = 'policies/%s' % policy_id
         resp, body = self.patch(url, post_body)
         self.expected_success(200, resp.status)
diff --git a/tempest/services/identity/v3/json/region_client.py b/tempest/services/identity/v3/json/region_client.py
index 24c6f33..6ccdc31 100644
--- a/tempest/services/identity/v3/json/region_client.py
+++ b/tempest/services/identity/v3/json/region_client.py
@@ -13,6 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+"""
+http://developer.openstack.org/api-ref-identity-v3.html#regions-v3
+"""
+
 from oslo_serialization import jsonutils as json
 from six.moves.urllib import parse as urllib
 
@@ -22,31 +26,34 @@
 class RegionClient(service_client.ServiceClient):
     api_version = "v3"
 
-    def create_region(self, description, **kwargs):
-        """Create region."""
-        req_body = {
-            'description': description,
-        }
-        if kwargs.get('parent_region_id'):
-            req_body['parent_region_id'] = kwargs.get('parent_region_id')
-        req_body = json.dumps({'region': req_body})
-        if kwargs.get('unique_region_id'):
-            resp, body = self.put(
-                'regions/%s' % kwargs.get('unique_region_id'), req_body)
+    def create_region(self, region_id=None, **kwargs):
+        """Create region.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#createRegion
+
+                          see http://developer.openstack.org/
+                              api-ref-identity-v3.html#createRegionWithID
+        """
+        if region_id is not None:
+            method = self.put
+            url = 'regions/%s' % region_id
         else:
-            resp, body = self.post('regions', req_body)
+            method = self.post
+            url = 'regions'
+        req_body = json.dumps({'region': kwargs})
+        resp, body = method(url, req_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
     def update_region(self, region_id, **kwargs):
-        """Updates a region."""
-        post_body = {}
-        if 'description' in kwargs:
-            post_body['description'] = kwargs.get('description')
-        if 'parent_region_id' in kwargs:
-            post_body['parent_region_id'] = kwargs.get('parent_region_id')
-        post_body = json.dumps({'region': post_body})
+        """Updates a region.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#updateRegion
+        """
+        post_body = json.dumps({'region': kwargs})
         resp, body = self.patch('regions/%s' % region_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index d912b25..6bac570 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -107,12 +107,12 @@
         sec_grp_cli.delete_security_group(self.sec_grp['id'])
 
     def _create_floating_ip(self):
-        floating_cli = self.manager.floating_ips_client
+        floating_cli = self.manager.compute_floating_ips_client
         self.floating = (floating_cli.create_floating_ip(self.floating_pool)
                          ['floating_ip'])
 
     def _destroy_floating_ip(self):
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
         cli.delete_floating_ip(self.floating['id'])
         cli.wait_for_resource_deletion(self.floating['id'])
         self.logger.info("Deleted Floating IP %s", str(self.floating['ip']))
@@ -146,7 +146,7 @@
             self._create_vm()
 
     def wait_disassociate(self):
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
 
         def func():
             floating = (cli.show_floating_ip(self.floating['id'])
@@ -158,7 +158,7 @@
             raise RuntimeError("IP disassociate timeout!")
 
     def run_core(self):
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
         cli.associate_floating_ip_to_server(self.floating['ip'],
                                             self.server_id)
         for method in self.verify:
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 95841a9..4840383 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -70,12 +70,12 @@
         sec_grp_cli.delete_security_group(self.sec_grp['id'])
 
     def _create_floating_ip(self):
-        floating_cli = self.manager.floating_ips_client
+        floating_cli = self.manager.compute_floating_ips_client
         self.floating = (floating_cli.create_floating_ip(self.floating_pool)
                          ['floating_ip'])
 
     def _destroy_floating_ip(self):
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
         cli.delete_floating_ip(self.floating['id'])
         cli.wait_for_resource_deletion(self.floating['id'])
         self.logger.info("Deleted Floating IP %s", str(self.floating['ip']))
@@ -98,7 +98,7 @@
         self.logger.info("deleted volume: %s" % self.volume['id'])
 
     def _wait_disassociate(self):
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
 
         def func():
             floating = (cli.show_floating_ip(self.floating['id'])
@@ -111,7 +111,7 @@
 
     def new_server_ops(self):
         self._create_vm()
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
         cli.associate_floating_ip_to_server(self.floating['ip'],
                                             self.server_id)
         if self.ssh_test_before_attach and self.enable_ssh_verify:
@@ -218,7 +218,7 @@
             self._destroy_vm()
 
     def tearDown(self):
-        cli = self.manager.floating_ips_client
+        cli = self.manager.compute_floating_ips_client
         cli.disassociate_floating_ip_from_server(self.floating['ip'],
                                                  self.server_id)
         self._wait_disassociate()
diff --git a/tempest/stress/cleanup.py b/tempest/stress/cleanup.py
index bac1984..66d2b36 100644
--- a/tempest/stress/cleanup.py
+++ b/tempest/stress/cleanup.py
@@ -59,12 +59,13 @@
         except Exception:
             pass
 
-    floating_ips = (admin_manager.floating_ips_client.list_floating_ips()
+    admin_floating_ips_client = admin_manager.compute_floating_ips_client
+    floating_ips = (admin_floating_ips_client.list_floating_ips()
                     ['floating_ips'])
     LOG.info("Cleanup::remove %s floating ips" % len(floating_ips))
     for f in floating_ips:
         try:
-            admin_manager.floating_ips_client.delete_floating_ip(f['id'])
+            admin_floating_ips_client.delete_floating_ip(f['id'])
         except Exception:
             pass
 
diff --git a/tempest/tests/services/compute/test_server_groups_client.py b/tempest/tests/services/compute/test_server_groups_client.py
index 5e058d6..e531e2f 100644
--- a/tempest/tests/services/compute/test_server_groups_client.py
+++ b/tempest/tests/services/compute/test_server_groups_client.py
@@ -69,16 +69,16 @@
     def test_list_server_groups_byte_body(self):
         self._test_list_server_groups(bytes_body=True)
 
-    def _test_get_server_group(self, bytes_body=False):
+    def _test_show_server_group(self, bytes_body=False):
         expected = {"server_group": TestServerGroupsClient.server_group}
         self.check_service_client_function(
-            self.client.get_server_group,
+            self.client.show_server_group,
             'tempest.common.service_client.ServiceClient.get',
             expected, bytes_body,
             server_group_id='5bbcc3c4-1da2-4437-a48a-66f15b1b13f9')
 
-    def test_get_server_group_str_body(self):
-        self._test_get_server_group(bytes_body=False)
+    def test_show_server_group_str_body(self):
+        self._test_show_server_group(bytes_body=False)
 
-    def test_get_server_group_byte_body(self):
-        self._test_get_server_group(bytes_body=True)
+    def test_show_server_group_byte_body(self):
+        self._test_show_server_group(bytes_body=True)