Merge "scenario cross_tenant_connectivity"
diff --git a/HACKING.rst b/HACKING.rst
index 1083075..3fa1ff5 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -39,7 +39,7 @@
 when the additional operations leads to another exception.
 
 Just letting an exception to propagate, is not bad idea in a test case,
- at all.
+at all.
 
 Try to avoid using any exception handling construct which can hide the errors
 origin.
@@ -53,10 +53,10 @@
 test fails part way through.
 
 Use the ``self.assert*`` methods provided by the unit test framework
- the signal failures early.
+the signal failures early.
 
 Avoid using the ``self.fail`` alone, it's stack trace will signal
- the ``self.fail`` line as the origin of the error.
+the ``self.fail`` line as the origin of the error.
 
 Avoid constructing complex boolean expressions for assertion.
 The ``self.assertTrue`` or ``self.assertFalse`` without a ``msg`` argument,
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index d6488c4..e1a1a5d 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -16,21 +16,20 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest.test import attr
 
 
-class AvailabilityZoneAdminTestJSON(base.BaseV2ComputeAdminTest):
+class AZAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
-    Tests Availability Zone API List that require admin privileges
+    Tests Availability Zone API List
     """
 
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(AvailabilityZoneAdminTestJSON, cls).setUpClass()
+        super(AZAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.availability_zone_client
         cls.non_adm_client = cls.availability_zone_client
 
@@ -57,14 +56,6 @@
         self.assertEqual(200, resp.status)
         self.assertTrue(len(availability_zone) > 0)
 
-    @attr(type=['negative', 'gate'])
-    def test_get_availability_zone_list_detail_with_non_admin_user(self):
-        # List of availability zones and available services with
-        # non-administrator user
-        self.assertRaises(
-            exceptions.Unauthorized,
-            self.non_adm_client.get_availability_zone_list_detail)
 
-
-class AvailabilityZoneAdminTestXML(AvailabilityZoneAdminTestJSON):
+class AZAdminTestXML(AZAdminTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
new file mode 100644
index 0000000..6ba8d58
--- /dev/null
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -0,0 +1,45 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 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.api.compute import base
+from tempest import exceptions
+from tempest.test import attr
+
+
+class AZAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
+
+    """
+    Tests Availability Zone API List
+    """
+
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(AZAdminNegativeTestJSON, cls).setUpClass()
+        cls.non_adm_client = cls.availability_zone_client
+
+    @attr(type=['negative', 'gate'])
+    def test_get_availability_zone_list_detail_with_non_admin_user(self):
+        # List of availability zones and available services with
+        # non-administrator user
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_availability_zone_list_detail)
+
+
+class AZAdminNegativeTestXML(AZAdminNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index 81e4f87..0b20e90 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -18,7 +18,6 @@
 import uuid
 
 from tempest.api.compute import base
-from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
@@ -31,14 +30,6 @@
         super(FlavorsNegativeTestJSON, cls).setUpClass()
         cls.client = cls.flavors_client
 
-        # Generating a nonexistent flavor id
-        resp, flavors = cls.client.list_flavors()
-        flavor_ids = [flavor['id'] for flavor in flavors]
-        while True:
-            cls.nonexistent_flavor_id = data_utils.rand_int_id(start=999)
-            if cls.nonexistent_flavor_id not in flavor_ids:
-                break
-
     @attr(type=['negative', 'gate'])
     def test_invalid_minRam_filter(self):
         self.assertRaises(exceptions.BadRequest,
@@ -52,17 +43,11 @@
                           {'minDisk': 'invalid'})
 
     @attr(type=['negative', 'gate'])
-    def test_get_flavor_details_for_invalid_flavor_id(self):
-        # Ensure 404 returned for invalid flavor ID
-        invalid_flavor_id = str(uuid.uuid4())
-        self.assertRaises(exceptions.NotFound, self.client.get_flavor_details,
-                          invalid_flavor_id)
-
-    @attr(type=['negative', 'gate'])
     def test_non_existent_flavor_id(self):
         # flavor details are not returned for non-existent flavors
+        nonexistent_flavor_id = str(uuid.uuid4())
         self.assertRaises(exceptions.NotFound, self.client.get_flavor_details,
-                          self.nonexistent_flavor_id)
+                          nonexistent_flavor_id)
 
 
 class FlavorsNegativeTestXML(FlavorsNegativeTestJSON):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 24ade96..cbd0eb1 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -93,13 +93,6 @@
 
     @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
     @attr(type='gate')
-    def test_can_log_into_created_server(self):
-        # Check that the user can authenticate with the generated password
-        linux_client = RemoteClient(self.server, self.ssh_user, self.password)
-        self.assertTrue(linux_client.can_authenticate())
-
-    @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
-    @attr(type='gate')
     def test_verify_created_server_vcpus(self):
         # Verify that the number of vcpus reported by the instance matches
         # the amount stated by the flavor
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 5552d0b..e009888 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -67,7 +67,7 @@
             # Verify that the user can authenticate with the new password
             resp, server = self.client.get_server(self.server_id)
             linux_client = RemoteClient(server, self.ssh_user, new_password)
-            self.assertTrue(linux_client.can_authenticate())
+            linux_client.validate_authentication()
 
     @attr(type='smoke')
     def test_reboot_server_hard(self):
@@ -141,7 +141,7 @@
         if self.run_ssh:
             # Verify that the user can authenticate with the provided password
             linux_client = RemoteClient(server, self.ssh_user, password)
-            self.assertTrue(linux_client.can_authenticate())
+            linux_client.validate_authentication()
 
     @attr(type='gate')
     def test_rebuild_server_in_stop_state(self):
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 8f1e446..b0bffc4 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -17,18 +17,31 @@
 
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
+import testtools
 
 
 class ExtensionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
-    @attr(type='gate')
+    @testtools.skipIf(not test.is_extension_enabled('os-consoles', 'compute'),
+                      'os-consoles extension not enabled.')
+    @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
         resp, extensions = self.extensions_client.list_extensions()
         self.assertIn("extensions", extensions)
         self.assertEqual(200, resp.status)
+        self.assertTrue(self.extensions_client.is_enabled("Consoles"))
+
+    @testtools.skipIf(not test.is_extension_enabled('os-consoles', 'compute'),
+                      'os-consoles extension not enabled.')
+    @test.attr(type='gate')
+    def test_get_extension(self):
+        # get the specified extensions
+        resp, extension = self.extensions_client.get_extension('os-consoles')
+        self.assertEqual(200, resp.status)
+        self.assertEqual('os-consoles', extension['alias'])
 
 
 class ExtensionsTestXML(ExtensionsTestJSON):
diff --git a/tempest/api/compute/v3/admin/test_availability_zone.py b/tempest/api/compute/v3/admin/test_availability_zone.py
index ff2765c..dca556f 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone.py
@@ -16,21 +16,20 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest.test import attr
 
 
-class AvailabilityZoneAdminV3TestJSON(base.BaseV3ComputeAdminTest):
+class AZAdminV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
-    Tests Availability Zone API List that require admin privileges
+    Tests Availability Zone API List
     """
 
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(AvailabilityZoneAdminV3TestJSON, cls).setUpClass()
+        super(AZAdminV3TestJSON, cls).setUpClass()
         cls.client = cls.availability_zone_admin_client
         cls.non_adm_client = cls.availability_zone_client
 
@@ -57,14 +56,6 @@
         self.assertEqual(200, resp.status)
         self.assertTrue(len(availability_zone) > 0)
 
-    @attr(type=['negative', 'gate'])
-    def test_get_availability_zone_list_detail_with_non_admin_user(self):
-        # List of availability zones and available services with
-        # non-administrator user
-        self.assertRaises(
-            exceptions.Unauthorized,
-            self.non_adm_client.get_availability_zone_list_detail)
 
-
-class AvailabilityZoneAdminV3TestXML(AvailabilityZoneAdminV3TestJSON):
+class AZAdminV3TestXML(AZAdminV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_availability_zone_negative.py b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
new file mode 100644
index 0000000..93a57e3
--- /dev/null
+++ b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
@@ -0,0 +1,47 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 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.api.compute import base
+from tempest import exceptions
+from tempest.test import attr
+
+
+class AZAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
+
+    """
+    Tests Availability Zone API List
+    """
+
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(AZAdminNegativeV3TestJSON, cls).setUpClass()
+        cls.client = cls.availability_zone_admin_client
+        cls.non_adm_client = cls.availability_zone_client
+
+    @attr(type=['negative', 'gate'])
+    def test_get_availability_zone_list_detail_with_non_admin_user(self):
+        # List of availability zones and available services with
+        # non-administrator user
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_availability_zone_list_detail)
+
+
+class AZAdminNegativeV3TestXML(AZAdminNegativeV3TestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 090f4dd..ee37502 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -67,7 +67,7 @@
             # Verify that the user can authenticate with the new password
             resp, server = self.client.get_server(self.server_id)
             linux_client = RemoteClient(server, self.ssh_user, new_password)
-            self.assertTrue(linux_client.can_authenticate())
+            linux_client.validate_authentication()
 
     @attr(type='smoke')
     def test_reboot_server_hard(self):
@@ -140,7 +140,7 @@
         if self.run_ssh:
             # Verify that the user can authenticate with the provided password
             linux_client = RemoteClient(server, self.ssh_user, password)
-            self.assertTrue(linux_client.can_authenticate())
+            linux_client.validate_authentication()
 
     def _detect_server_image_flavor(self, server_id):
         # Detects the current server image flavor ref.
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
index d7269d1..2affd86 100644
--- a/tempest/api/compute/v3/test_extensions.py
+++ b/tempest/api/compute/v3/test_extensions.py
@@ -17,18 +17,26 @@
 
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class ExtensionsV3TestJSON(base.BaseV3ComputeTest):
     _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
         resp, extensions = self.extensions_client.list_extensions()
         self.assertIn("extensions", extensions)
         self.assertEqual(200, resp.status)
+        self.assertTrue(self.extensions_client.is_enabled("Consoles"))
+
+    @test.attr(type='gate')
+    def test_get_extension(self):
+        # get the specified extensions
+        resp, extension = self.extensions_client.get_extension('servers')
+        self.assertEqual(200, resp.status)
+        self.assertEqual('servers', extension['alias'])
 
 
 class ExtensionsV3TestXML(ExtensionsV3TestJSON):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 61af91f..064eaff 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -71,10 +71,10 @@
     def tearDownClass(cls):
         # Clean up ike policies
         for ikepolicy in cls.ikepolicies:
-            cls.client.delete_ike_policy(ikepolicy['id'])
+            cls.client.delete_ikepolicy(ikepolicy['id'])
         # Clean up vpn services
         for vpnservice in cls.vpnservices:
-            cls.client.delete_vpn_service(vpnservice['id'])
+            cls.client.delete_vpnservice(vpnservice['id'])
         # Clean up routers
         for router in cls.routers:
             resp, body = cls.client.list_router_interfaces(router['id'])
@@ -213,7 +213,7 @@
     @classmethod
     def create_vpnservice(cls, subnet_id, router_id):
         """Wrapper utility that returns a test vpn service."""
-        resp, body = cls.client.create_vpn_service(
+        resp, body = cls.client.create_vpnservice(
             subnet_id, router_id, admin_state_up=True,
             name=data_utils.rand_name("vpnservice-"))
         vpnservice = body['vpnservice']
@@ -221,9 +221,9 @@
         return vpnservice
 
     @classmethod
-    def create_ike_policy(cls, name):
+    def create_ikepolicy(cls, name):
         """Wrapper utility that returns a test ike policy."""
-        resp, body = cls.client.create_ike_policy(name)
+        resp, body = cls.client.create_ikepolicy(name)
         ikepolicy = body['ikepolicy']
         cls.ikepolicies.append(ikepolicy)
         return ikepolicy
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index 1b27d1b..7acd940 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -55,7 +55,7 @@
             ext_name = ext['name']
             ext_alias = ext['alias']
             actual_alias.append(ext['alias'])
-            resp, ext_details = self.client.show_extension_details(ext_alias)
+            resp, ext_details = self.client.show_extension(ext_alias)
             self.assertEqual('200', resp['status'])
             ext_details = ext_details['extension']
 
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 35d4fa8..3a41f4f 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -68,10 +68,10 @@
 
     def _delete_floating_ip(self, floating_ip_id):
         # Deletes a floating IP and verifies if it is deleted or not
-        resp, _ = self.client.delete_floating_ip(floating_ip_id)
+        resp, _ = self.client.delete_floatingip(floating_ip_id)
         self.assertEqual(204, resp.status)
         # Asserting that the floating_ip is not found in list after deletion
-        resp, floating_ips = self.client.list_floating_ips()
+        resp, floating_ips = self.client.list_floatingips()
         floatingip_id_list = list()
         for f in floating_ips['floatingips']:
             floatingip_id_list.append(f['id'])
@@ -106,7 +106,7 @@
         self.assertEqual(show_floating_ip['port_id'], self.port[0]['id'])
 
         # Verify the floating ip exists in the list of all floating_ips
-        resp, floating_ips = self.client.list_floating_ips()
+        resp, floating_ips = self.client.list_floatingips()
         self.assertEqual('200', resp['status'])
         floatingip_id_list = list()
         for f in floating_ips['floatingips']:
diff --git a/tempest/api/network/test_quotas.py b/tempest/api/network/test_quotas.py
index f7ba3cb..8b77637 100644
--- a/tempest/api/network/test_quotas.py
+++ b/tempest/api/network/test_quotas.py
@@ -74,12 +74,13 @@
         resp, non_default_quotas = self.admin_client.list_quotas()
         self.assertEqual('200', resp['status'])
         found = False
-        for qs in non_default_quotas:
+        for qs in non_default_quotas['quotas']:
             if qs['tenant_id'] == tenant_id:
                 found = True
         self.assertTrue(found)
         # Confirm from APi quotas were changed as requested for tenant
         resp, quota_set = self.admin_client.show_quotas(tenant_id)
+        quota_set = quota_set['quota']
         self.assertEqual('200', resp['status'])
         self.assertEqual(0, quota_set['network'])
         self.assertEqual(0, quota_set['security_group'])
@@ -88,5 +89,5 @@
         self.assertEqual('204', resp['status'])
         resp, non_default_quotas = self.admin_client.list_quotas()
         self.assertEqual('200', resp['status'])
-        for q in non_default_quotas:
+        for q in non_default_quotas['quotas']:
             self.assertNotEqual(tenant_id, q['tenant_id'])
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index 63a8e24..fc3b1d9 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -46,20 +46,20 @@
         cls.create_router_interface(cls.router['id'], cls.subnet['id'])
         cls.vpnservice = cls.create_vpnservice(cls.subnet['id'],
                                                cls.router['id'])
-        cls.ikepolicy = cls.create_ike_policy(data_utils.rand_name(
-                                              "ike-policy-"))
+        cls.ikepolicy = cls.create_ikepolicy(
+            data_utils.rand_name("ike-policy-"))
 
     def _delete_ike_policy(self, ike_policy_id):
         # Deletes a ike policy and verifies if it is deleted or not
         ike_list = list()
-        resp, all_ike = self.client.list_ike_policies()
+        resp, all_ike = self.client.list_ikepolicies()
         for ike in all_ike['ikepolicies']:
             ike_list.append(ike['id'])
         if ike_policy_id in ike_list:
-            resp, _ = self.client.delete_ike_policy(ike_policy_id)
+            resp, _ = self.client.delete_ikepolicy(ike_policy_id)
             self.assertEqual(204, resp.status)
             # Asserting that the policy is not found in list after deletion
-            resp, ikepolicies = self.client.list_ike_policies()
+            resp, ikepolicies = self.client.list_ikepolicies()
             ike_id_list = list()
             for i in ikepolicies['ikepolicies']:
                 ike_id_list.append(i['id'])
@@ -68,7 +68,7 @@
     @attr(type='smoke')
     def test_list_vpn_services(self):
         # Verify the VPN service exists in the list of all VPN services
-        resp, body = self.client.list_vpn_services()
+        resp, body = self.client.list_vpnservices()
         self.assertEqual('200', resp['status'])
         vpnservices = body['vpnservices']
         self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
@@ -77,14 +77,14 @@
     def test_create_update_delete_vpn_service(self):
         # Creates a VPN service
         name = data_utils.rand_name('vpn-service-')
-        resp, body = self.client.create_vpn_service(self.subnet['id'],
-                                                    self.router['id'],
-                                                    name=name,
-                                                    admin_state_up=True)
+        resp, body = self.client.create_vpnservice(self.subnet['id'],
+                                                   self.router['id'],
+                                                   name=name,
+                                                   admin_state_up=True)
         self.assertEqual('201', resp['status'])
         vpnservice = body['vpnservice']
         # Assert if created vpnservices are not found in vpnservices list
-        resp, body = self.client.list_vpn_services()
+        resp, body = self.client.list_vpnservices()
         vpn_services = [vs['id'] for vs in body['vpnservices']]
         self.assertIsNotNone(vpnservice['id'])
         self.assertIn(vpnservice['id'], vpn_services)
@@ -95,17 +95,17 @@
         # should be "ACTIVE" not "PENDING*"
 
         # Verification of vpn service delete
-        resp, body = self.client.delete_vpn_service(vpnservice['id'])
+        resp, body = self.client.delete_vpnservice(vpnservice['id'])
         self.assertEqual('204', resp['status'])
         # Asserting if vpn service is found in the list after deletion
-        resp, body = self.client.list_vpn_services()
+        resp, body = self.client.list_vpnservices()
         vpn_services = [vs['id'] for vs in body['vpnservices']]
         self.assertNotIn(vpnservice['id'], vpn_services)
 
     @attr(type='smoke')
     def test_show_vpn_service(self):
         # Verifies the details of a vpn service
-        resp, body = self.client.show_vpn_service(self.vpnservice['id'])
+        resp, body = self.client.show_vpnservice(self.vpnservice['id'])
         self.assertEqual('200', resp['status'])
         vpnservice = body['vpnservice']
         self.assertEqual(self.vpnservice['id'], vpnservice['id'])
@@ -119,7 +119,7 @@
     @attr(type='smoke')
     def test_list_ike_policies(self):
         # Verify the ike policy exists in the list of all IKE policies
-        resp, body = self.client.list_ike_policies()
+        resp, body = self.client.list_ikepolicies()
         self.assertEqual('200', resp['status'])
         ikepolicies = body['ikepolicies']
         self.assertIn(self.ikepolicy['id'], [i['id'] for i in ikepolicies])
@@ -128,7 +128,7 @@
     def test_create_update_delete_ike_policy(self):
         # Creates a IKE policy
         name = data_utils.rand_name('ike-policy-')
-        resp, body = (self.client.create_ike_policy(
+        resp, body = (self.client.create_ikepolicy(
                       name,
                       ike_version="v1",
                       encryption_algorithm="aes-128",
@@ -140,19 +140,19 @@
         description = "Updated ike policy"
         new_ike = {'description': description, 'pfs': 'group5',
                    'name': data_utils.rand_name("New-IKE-")}
-        resp, body = self.client.update_ike_policy(ikepolicy['id'],
-                                                   **new_ike)
+        resp, body = self.client.update_ikepolicy(ikepolicy['id'],
+                                                  **new_ike)
         self.assertEqual('200', resp['status'])
         updated_ike_policy = body['ikepolicy']
         self.assertEqual(updated_ike_policy['description'], description)
         # Verification of ike policy delete
-        resp, body = self.client.delete_ike_policy(ikepolicy['id'])
+        resp, body = self.client.delete_ikepolicy(ikepolicy['id'])
         self.assertEqual('204', resp['status'])
 
     @attr(type='smoke')
     def test_show_ike_policy(self):
         # Verifies the details of a ike policy
-        resp, body = self.client.show_ike_policy(self.ikepolicy['id'])
+        resp, body = self.client.show_ikepolicy(self.ikepolicy['id'])
         self.assertEqual('200', resp['status'])
         ikepolicy = body['ikepolicy']
         self.assertEqual(self.ikepolicy['id'], ikepolicy['id'])
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index 35a7326..b19344d 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -28,75 +28,57 @@
     template = """
 HeatTemplateFormatVersion: '2012-12-12'
 Description: |
-  Template which creates single EC2 instance
+  Template which creates some simple resources
 Parameters:
-  KeyName:
+  trigger:
     Type: String
-  InstanceType:
-    Type: String
-  ImageId:
-    Type: String
-  Subnet:
-    Type: String
+    Default: not_yet
 Resources:
-  SmokeServer:
-    Type: AWS::EC2::Instance
+  fluffy:
+    Type: AWS::AutoScaling::LaunchConfiguration
     Metadata:
-      Name: SmokeServer
+      kittens:
+      - Tom
+      - Stinky
     Properties:
-      ImageId: {Ref: ImageId}
-      InstanceType: {Ref: InstanceType}
-      KeyName: {Ref: KeyName}
-      SubnetId: {Ref: Subnet}
+      ImageId: not_used
+      InstanceType: not_used
       UserData:
-        Fn::Base64:
-          Fn::Join:
-          - ''
-          - - '#!/bin/bash -v
-
-              '
-            - /opt/aws/bin/cfn-signal -e 0 -r "SmokeServer created" '
-            - {Ref: WaitHandle}
-            - '''
-
-              '
-  WaitHandle:
-    Type: AWS::CloudFormation::WaitConditionHandle
-  WaitCondition:
-    Type: AWS::CloudFormation::WaitCondition
-    DependsOn: SmokeServer
-    Properties:
-      Handle: {Ref: WaitHandle}
-      Timeout: '600'
+        Fn::Replace:
+        - variable_a: {Ref: trigger}
+          variable_b: bee
+        - |
+          A == variable_a
+          B == variable_b
+Outputs:
+  fluffy:
+    Description: "fluffies irc nick"
+    Value:
+      Fn::Replace:
+      - nick: {Ref: fluffy}
+      - |
+        #nick
 """
 
     @classmethod
     def setUpClass(cls):
         super(StacksTestJSON, cls).setUpClass()
-        if not cls.orchestration_cfg.image_ref:
-            raise cls.skipException("No image available to test")
         cls.client = cls.orchestration_client
         cls.stack_name = data_utils.rand_name('heat')
-        keypair_name = (cls.orchestration_cfg.keypair_name or
-                        cls._create_keypair()['name'])
 
         # create the stack
-        subnet = cls._get_default_network()['subnets'][0]
         cls.stack_identifier = cls.create_stack(
             cls.stack_name,
             cls.template,
             parameters={
-                'KeyName': keypair_name,
-                'InstanceType': cls.orchestration_cfg.instance_type,
-                'ImageId': cls.orchestration_cfg.image_ref,
-                'Subnet': subnet
+                'trigger': 'start'
             })
         cls.stack_id = cls.stack_identifier.split('/')[1]
-        cls.resource_name = 'SmokeServer'
-        cls.resource_type = 'AWS::EC2::Instance'
+        cls.resource_name = 'fluffy'
+        cls.resource_type = 'AWS::AutoScaling::LaunchConfiguration'
         cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_stack_list(self):
         """Created stack should be on the list of existing stacks."""
         resp, stacks = self.client.list_stacks()
@@ -105,7 +87,7 @@
         stacks_names = map(lambda stack: stack['stack_name'], stacks)
         self.assertIn(self.stack_name, stacks_names)
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_stack_show(self):
         """Getting details about created stack should be possible."""
         resp, stack = self.client.get_stack(self.stack_name)
@@ -114,7 +96,7 @@
         self.assertEqual(self.stack_name, stack['stack_name'])
         self.assertEqual(self.stack_id, stack['id'])
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_list_resources(self):
         """Getting list of created resources for the stack should be possible.
         """
@@ -128,7 +110,7 @@
                               resources)
         self.assertIn(self.resource_type, resources_types)
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_show_resource(self):
         """Getting details about created resource should be possible."""
         resp, resource = self.client.get_resource(self.stack_identifier,
@@ -137,7 +119,7 @@
         self.assertEqual(self.resource_name, resource['logical_resource_id'])
         self.assertEqual(self.resource_type, resource['resource_type'])
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_resource_metadata(self):
         """Getting metadata for created resource should be possible."""
         resp, metadata = self.client.show_resource_metadata(
@@ -145,9 +127,9 @@
             self.resource_name)
         self.assertEqual('200', resp['status'])
         self.assertIsInstance(metadata, dict)
-        self.assertEqual(self.resource_name, metadata.get('Name', None))
+        self.assertEqual(['Tom', 'Stinky'], metadata.get('kittens', None))
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_list_events(self):
         """Getting list of created events for the stack should be possible."""
         resp, events = self.client.list_events(self.stack_identifier)
@@ -157,7 +139,7 @@
         self.assertIn('CREATE_IN_PROGRESS', resource_statuses)
         self.assertIn('CREATE_COMPLETE', resource_statuses)
 
-    @attr(type='slow')
+    @attr(type='gate')
     def test_show_event(self):
         """Getting details about existing event should be possible."""
         resp, events = self.client.list_resource_events(self.stack_identifier,
@@ -168,7 +150,7 @@
         resp, event = self.client.show_event(self.stack_identifier,
                                              self.resource_name, event_id)
         self.assertEqual('200', resp['status'])
-        self.assertEqual('CREATE_IN_PROGRESS', event['resource_status'])
+        self.assertIsInstance(event, dict)
+        self.assertEqual(self.resource_name, event['resource_name'])
         self.assertEqual('state changed', event['resource_status_reason'])
         self.assertEqual(self.resource_name, event['logical_resource_id'])
-        self.assertIsInstance(event, dict)
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index 3c2a2d2..0480570 100644
--- a/tempest/api/orchestration/stacks/test_server_cfn_init.py
+++ b/tempest/api/orchestration/stacks/test_server_cfn_init.py
@@ -169,9 +169,9 @@
             body['physical_resource_id'])
 
         # Check that the user can authenticate with the generated password
-        linux_client = RemoteClient(
-            server, 'ec2-user', pkey=self.keypair['private_key'])
-        self.assertTrue(linux_client.can_authenticate())
+        linux_client = RemoteClient(server, 'ec2-user',
+                                    pkey=self.keypair['private_key'])
+        linux_client.validate_authentication()
 
     @attr(type='slow')
     def test_stack_wait_condition_data(self):
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index c397b7c..bca2f9e 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -23,6 +23,7 @@
 import warnings
 
 from tempest import exceptions
+from tempest.openstack.common import log as logging
 
 
 with warnings.catch_warnings():
@@ -30,6 +31,9 @@
     import paramiko
 
 
+LOG = logging.getLogger(__name__)
+
+
 class Client(object):
 
     def __init__(self, host, username, password=None, timeout=300, pkey=None,
@@ -49,33 +53,44 @@
 
     def _get_ssh_connection(self, sleep=1.5, backoff=1.01):
         """Returns an ssh connection to the specified host."""
-        _timeout = True
         bsleep = sleep
         ssh = paramiko.SSHClient()
         ssh.set_missing_host_key_policy(
             paramiko.AutoAddPolicy())
         _start_time = time.time()
-
-        while not self._is_timed_out(_start_time):
+        if self.pkey is not None:
+            LOG.info("Creating ssh connection to '%s' as '%s'"
+                     " with public key authentication",
+                     self.host, self.username)
+        else:
+            LOG.info("Creating ssh connection to '%s' as '%s'"
+                     " with password %s",
+                     self.host, self.username, str(self.password))
+        attempts = 0
+        while True:
             try:
                 ssh.connect(self.host, username=self.username,
                             password=self.password,
                             look_for_keys=self.look_for_keys,
                             key_filename=self.key_filename,
                             timeout=self.channel_timeout, pkey=self.pkey)
-                _timeout = False
-                break
+                LOG.info("ssh connection to %s@%s sucessfuly created",
+                         self.username, self.host)
+                return ssh
             except (socket.error,
-                    paramiko.AuthenticationException,
                     paramiko.SSHException):
+                attempts += 1
                 time.sleep(bsleep)
                 bsleep *= backoff
-                continue
-        if _timeout:
-            raise exceptions.SSHTimeout(host=self.host,
-                                        user=self.username,
-                                        password=self.password)
-        return ssh
+                if not self._is_timed_out(_start_time):
+                    continue
+                else:
+                    LOG.exception("Failed to establish authenticated ssh"
+                                  " connection to %s@%s after %d attempts",
+                                  self.username, self.host, attempts)
+                    raise exceptions.SSHTimeout(host=self.host,
+                                                user=self.username,
+                                                password=self.password)
 
     def _is_timed_out(self, start_time):
         return (time.time() - self.timeout) > start_time
@@ -144,11 +159,6 @@
         return ''.join(out_data)
 
     def test_connection_auth(self):
-        """Returns true if ssh can connect to server."""
-        try:
-            connection = self._get_ssh_connection()
-            connection.close()
-        except paramiko.AuthenticationException:
-            return False
-
-        return True
+        """Raises an exception when we can not connect to server via ssh."""
+        connection = self._get_ssh_connection()
+        connection.close()
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 3cae80f..144536a 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -19,7 +19,6 @@
 from tempest.common import utils
 from tempest.config import TempestConfig
 from tempest.exceptions import ServerUnreachable
-from tempest.exceptions import SSHTimeout
 
 
 class RemoteClient():
@@ -40,16 +39,15 @@
                     break
             else:
                 raise ServerUnreachable()
-
         self.ssh_client = Client(ip_address, username, password, ssh_timeout,
                                  pkey=pkey,
                                  channel_timeout=ssh_channel_timeout)
-        if not self.ssh_client.test_connection_auth():
-            raise SSHTimeout()
 
-    def can_authenticate(self):
-        # Re-authenticate
-        return self.ssh_client.test_connection_auth()
+    def validate_authentication(self):
+        """Validate ssh connection and authentication
+           This method raises an Exception when the validation fails.
+        """
+        self.ssh_client.test_connection_auth()
 
     def hostname_equals_servername(self, expected_hostname):
         # Get host name using command "hostname"
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 44198f0..d2b40c9 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -88,3 +88,34 @@
             raise exceptions.TimeoutException(message)
         old_status = server_status
         old_task_state = task_state
+
+
+def wait_for_image_status(client, image_id, status):
+    """Waits for an image to reach a given status.
+
+    The client should have a get_image(image_id) method to get the image.
+    The client should also have build_interval and build_timeout attributes.
+    """
+    resp, image = client.get_image(image_id)
+    start = int(time.time())
+
+    while image['status'] != status:
+        time.sleep(client.build_interval)
+        resp, image = client.get_image(image_id)
+        if image['status'] == 'ERROR':
+            raise exceptions.AddImageException(image_id=image_id)
+
+        # check the status again to avoid a false negative where we hit
+        # the timeout at the same time that the image reached the expected
+        # status
+        if image['status'] == status:
+            return
+
+        if int(time.time()) - start >= client.build_timeout:
+            message = ('Image %(image_id)s failed to reach %(status)s '
+                       'status within the required time (%(timeout)s s).' %
+                       {'image_id': image_id,
+                        'status': status,
+                        'timeout': client.build_timeout})
+            message += ' Current status: %s.' % image['status']
+            raise exceptions.TimeoutException(message)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 1cb907a..9f97964 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -33,7 +33,6 @@
 
 from tempest.api.network import common as net_common
 from tempest.common import isolated_creds
-from tempest.common import ssh
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux.remote_client import RemoteClient
 from tempest import exceptions
@@ -650,13 +649,6 @@
         return tempest.test.call_until_true(
             ping, self.config.compute.ping_timeout, 1)
 
-    def _is_reachable_via_ssh(self, ip_address, username, private_key,
-                              timeout):
-        ssh_client = ssh.Client(ip_address, username,
-                                pkey=private_key,
-                                timeout=timeout)
-        return ssh_client.test_connection_auth()
-
     def _check_vm_connectivity(self, ip_address,
                                username=None,
                                private_key=None,
@@ -681,13 +673,9 @@
                         msg=msg)
         if should_connect:
             # no need to check ssh for negative connectivity
-            self.assertTrue(self._is_reachable_via_ssh(
-                ip_address,
-                username,
-                private_key,
-                timeout=self.config.compute.ssh_timeout),
-                'Auth failure in connecting to %s@%s via ssh' %
-                (username, ip_address))
+            linux_client = self.get_remote_client(ip_address, username,
+                                                  private_key)
+            linux_client.validate_authentication()
 
     def _create_security_group_nova(self, client=None,
                                     namestart='secgroup-smoke-',
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index ce46a9b..ad5354c 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -37,3 +37,8 @@
         _, extensions = self.list_extensions()
         exts = extensions['extensions']
         return any([e for e in exts if e['name'] == extension])
+
+    def get_extension(self, extension_alias):
+        resp, body = self.get('extensions/%s' % extension_alias)
+        body = json.loads(body)
+        return resp, body['extension']
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 5f17894..c05571a 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -16,10 +16,10 @@
 #    under the License.
 
 import json
-import time
 import urllib
 
 from tempest.common.rest_client import RestClient
+from tempest.common import waiters
 from tempest import exceptions
 
 
@@ -82,18 +82,7 @@
 
     def wait_for_image_status(self, image_id, status):
         """Waits for an image to reach a given status."""
-        resp, image = self.get_image(image_id)
-        start = int(time.time())
-
-        while image['status'] != status:
-            time.sleep(self.build_interval)
-            resp, image = self.get_image(image_id)
-
-            if image['status'] == 'ERROR':
-                raise exceptions.AddImageException(image_id=image_id)
-
-            if int(time.time()) - start >= self.build_timeout:
-                raise exceptions.TimeoutException
+        waiters.wait_for_image_status(self, image_id, status)
 
     def list_image_metadata(self, image_id):
         """Lists all metadata items for an image."""
diff --git a/tempest/services/compute/v3/json/extensions_client.py b/tempest/services/compute/v3/json/extensions_client.py
index 60c0217..6e0dc9d 100644
--- a/tempest/services/compute/v3/json/extensions_client.py
+++ b/tempest/services/compute/v3/json/extensions_client.py
@@ -38,3 +38,8 @@
         _, extensions = self.list_extensions()
         exts = extensions['extensions']
         return any([e for e in exts if e['name'] == extension])
+
+    def get_extension(self, extension_alias):
+        resp, body = self.get('extensions/%s' % extension_alias)
+        body = json.loads(body)
+        return resp, body['extension']
diff --git a/tempest/services/compute/v3/xml/extensions_client.py b/tempest/services/compute/v3/xml/extensions_client.py
index e03251c..8f97692 100644
--- a/tempest/services/compute/v3/xml/extensions_client.py
+++ b/tempest/services/compute/v3/xml/extensions_client.py
@@ -43,3 +43,8 @@
         _, extensions = self.list_extensions()
         exts = extensions['extensions']
         return any([e for e in exts if e['name'] == extension])
+
+    def get_extension(self, extension_alias):
+        resp, body = self.get('extensions/%s' % extension_alias, self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
diff --git a/tempest/services/compute/xml/extensions_client.py b/tempest/services/compute/xml/extensions_client.py
index 1395b5a..b17fc4f 100644
--- a/tempest/services/compute/xml/extensions_client.py
+++ b/tempest/services/compute/xml/extensions_client.py
@@ -43,3 +43,8 @@
         _, extensions = self.list_extensions()
         exts = extensions['extensions']
         return any([e for e in exts if e['name'] == extension])
+
+    def get_extension(self, extension_alias):
+        resp, body = self.get('extensions/%s' % extension_alias, self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
diff --git a/tempest/services/compute/xml/images_client.py b/tempest/services/compute/xml/images_client.py
index b17ae78..20fcc9b 100644
--- a/tempest/services/compute/xml/images_client.py
+++ b/tempest/services/compute/xml/images_client.py
@@ -15,12 +15,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import time
 import urllib
 
 from lxml import etree
 
 from tempest.common.rest_client import RestClientXML
+from tempest.common import waiters
 from tempest import exceptions
 from tempest.services.compute.xml.common import Document
 from tempest.services.compute.xml.common import Element
@@ -140,17 +140,7 @@
 
     def wait_for_image_status(self, image_id, status):
         """Waits for an image to reach a given status."""
-        resp, image = self.get_image(image_id)
-        start = int(time.time())
-
-        while image['status'] != status:
-            time.sleep(self.build_interval)
-            resp, image = self.get_image(image_id)
-            if image['status'] == 'ERROR':
-                raise exceptions.AddImageException(image_id=image_id)
-
-            if int(time.time()) - start >= self.build_timeout:
-                raise exceptions.TimeoutException
+        waiters.wait_for_image_status(self, image_id, status)
 
     def _metadata_body(self, meta):
         post_body = Element('metadata')
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 3199537..b323dc6 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -15,9 +15,10 @@
 import json
 
 from tempest.common.rest_client import RestClient
+from tempest.services.network import network_client_base
 
 
-class NetworkClientJSON(RestClient):
+class NetworkClientJSON(network_client_base.NetworkClientBase):
 
     """
     Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
@@ -32,25 +33,25 @@
     quotas
     """
 
-    def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(NetworkClientJSON, self).__init__(config, username, password,
-                                                auth_url, tenant_name)
-        self.service = self.config.network.catalog_type
-        self.version = '2.0'
-        self.uri_prefix = "v%s" % (self.version)
+    def get_rest_client(self, config, username,
+                        password, auth_url, tenant_name=None):
+        return RestClient(config, username, password, auth_url, tenant_name)
 
-    def list_networks(self):
-        uri = '%s/networks' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
+    def deserialize_single(self, body):
+        return json.loads(body)
+
+    def deserialize_list(self, body):
+        res = json.loads(body)
+        # expecting response in form
+        # {'resources': [ res1, res2] }
+        return res[res.keys()[0]]
 
     def create_network(self, name, **kwargs):
         post_body = {'network': kwargs}
         post_body['network']['name'] = name
         body = json.dumps(post_body)
         uri = '%s/networks' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -61,21 +62,10 @@
         post_body = {'networks': network_list}
         body = json.dumps(post_body)
         uri = '%s/networks' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_network(self, uuid):
-        uri = '%s/networks/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_network(self, uuid):
-        uri = '%s/networks/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def create_subnet(self, net_uuid, cidr, ip_version=4, **kwargs):
         post_body = {'subnet': kwargs}
         post_body['subnet']['ip_version'] = ip_version
@@ -83,24 +73,7 @@
         post_body['subnet']['cidr'] = cidr
         body = json.dumps(post_body)
         uri = '%s/subnets' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_subnet(self, uuid):
-        uri = '%s/subnets/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def list_subnets(self):
-        uri = '%s/subnets' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def show_subnet(self, uuid):
-        uri = '%s/subnets/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -114,28 +87,7 @@
             post_body['port'][key] = val
         body = json.dumps(post_body)
         uri = '%s/ports' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_port(self, port_id):
-        uri = '%s/ports/%s' % (self.uri_prefix, port_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def list_ports(self, **filters):
-        uri = '%s/ports' % (self.uri_prefix)
-        filter_items = ["%s=%s" % (k, v) for (k, v) in filters.iteritems()]
-        querystring = "&".join(filter_items)
-        if querystring:
-            uri = "%s?%s" % (uri, querystring)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def show_port(self, port_id):
-        uri = '%s/ports/%s' % (self.uri_prefix, port_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -143,27 +95,15 @@
         put_body = {'quota': kwargs}
         body = json.dumps(put_body)
         uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
-        resp, body = self.put(uri, body, self.headers)
-        body = json.loads(body)
-        return resp, body['quota']
-
-    def show_quotas(self, tenant_id):
-        uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body['quota']
 
     def reset_quotas(self, tenant_id):
         uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
-        resp, body = self.delete(uri, self.headers)
+        resp, body = self.delete(uri)
         return resp, body
 
-    def list_quotas(self):
-        uri = '%s/quotas' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body['quotas']
-
     def update_subnet(self, subnet_id, new_name):
         put_body = {
             'subnet': {
@@ -172,7 +112,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/subnets/%s' % (self.uri_prefix, subnet_id)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -184,7 +124,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/ports/%s' % (self.uri_prefix, port_id)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -196,13 +136,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/networks/%s' % (self.uri_prefix, network_id)
-        resp, body = self.put(uri, body=body, headers=self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_routers(self):
-        uri = '%s/routers' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -212,24 +146,13 @@
         post_body['router']['admin_state_up'] = admin_state_up
         body = json.dumps(post_body)
         uri = '%s/routers' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_router(self, router_id):
-        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def show_router(self, router_id):
-        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
     def _update_router(self, router_id, set_enable_snat, **kwargs):
         uri = '%s/routers/%s' % (self.uri_prefix, router_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = json.loads(body)
         update_body = {}
         update_body['name'] = kwargs.get('name', body['router']['name'])
@@ -242,7 +165,7 @@
             'external_gateway_info', body['router']['external_gateway_info'])
         update_body = dict(router=update_body)
         update_body = json.dumps(update_body)
-        resp, body = self.put(uri, update_body, self.headers)
+        resp, body = self.put(uri, update_body)
         body = json.loads(body)
         return resp, body
 
@@ -268,7 +191,7 @@
               router_id)
         update_body = {"subnet_id": subnet_id}
         update_body = json.dumps(update_body)
-        resp, body = self.put(uri, update_body, self.headers)
+        resp, body = self.put(uri, update_body)
         body = json.loads(body)
         return resp, body
 
@@ -277,7 +200,7 @@
               router_id)
         update_body = {"port_id": port_id}
         update_body = json.dumps(update_body)
-        resp, body = self.put(uri, update_body, self.headers)
+        resp, body = self.put(uri, update_body)
         body = json.loads(body)
         return resp, body
 
@@ -286,7 +209,7 @@
               router_id)
         update_body = {"subnet_id": subnet_id}
         update_body = json.dumps(update_body)
-        resp, body = self.put(uri, update_body, self.headers)
+        resp, body = self.put(uri, update_body)
         body = json.loads(body)
         return resp, body
 
@@ -295,7 +218,7 @@
               router_id)
         update_body = {"port_id": port_id}
         update_body = json.dumps(update_body)
-        resp, body = self.put(uri, update_body, self.headers)
+        resp, body = self.put(uri, update_body)
         body = json.loads(body)
         return resp, body
 
@@ -305,21 +228,10 @@
         post_body['floatingip']['floating_network_id'] = ext_network_id
         body = json.dumps(post_body)
         uri = '%s/floatingips' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body=body)
         body = json.loads(body)
         return resp, body
 
-    def list_security_groups(self):
-        uri = '%s/security-groups' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_security_group(self, secgroup_id):
-        uri = '%s/security-groups/%s' % (self.uri_prefix, secgroup_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def create_security_group(self, name, **kwargs):
         post_body = {
             'security_group': {
@@ -330,45 +242,16 @@
             post_body['security_group'][str(key)] = value
         body = json.dumps(post_body)
         uri = '%s/security-groups' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_floating_ip(self, floating_ip_id):
-        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def show_security_group(self, secgroup_id):
-        uri = '%s/security-groups/%s' % (self.uri_prefix, secgroup_id)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_floating_ips(self):
-        uri = '%s/floatingips' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_security_group_rules(self):
-        uri = '%s/security-group-rules' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_floating_ip(self, floating_ip_id):
-        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def update_floating_ip(self, floating_ip_id, **kwargs):
         post_body = {
             'floatingip': kwargs}
         body = json.dumps(post_body)
         uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
-        resp, body = self.put(uri, headers=self.headers, body=body)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -384,7 +267,7 @@
             post_body['security_group_rule'][str(key)] = value
         body = json.dumps(post_body)
         uri = '%s/security-group-rules' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -392,18 +275,7 @@
         post_body = {'subnets': subnet_list}
         body = json.dumps(post_body)
         uri = '%s/subnets' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_security_group_rule(self, rule_id):
-        uri = '%s/security-group-rules/%s' % (self.uri_prefix, rule_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def show_security_group_rule(self, rule_id):
-        uri = '%s/security-group-rules/%s' % (self.uri_prefix, rule_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -411,13 +283,7 @@
         post_body = {'ports': port_list}
         body = json.dumps(post_body)
         uri = '%s/ports' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
-        body = json.loads(body)
-        return resp, body
-
-    def list_vips(self):
-        uri = '%s/lb/vips' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -433,7 +299,7 @@
         }
         body = json.dumps(post_body)
         uri = '%s/lb/vips' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -448,26 +314,10 @@
         }
         body = json.dumps(post_body)
         uri = '%s/lb/pools' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_vip(self, uuid):
-        uri = '%s/lb/vips/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_vip(self, uuid):
-        uri = '%s/lb/vips/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def delete_pool(self, uuid):
-        uri = '%s/lb/pools/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def update_vip(self, vip_id, new_name):
         put_body = {
             "vip": {
@@ -476,7 +326,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/lb/vips/%s' % (self.uri_prefix, vip_id)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -488,25 +338,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/lb/pools/%s' % (self.uri_prefix, pool_id)
-        resp, body = self.put(uri, body=body, headers=self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_pools(self):
-        uri = '%s/lb/pools' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def show_pool(self, uuid):
-        uri = '%s/lb/pools/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_members(self):
-        uri = '%s/lb/members' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -520,21 +352,10 @@
         }
         body = json.dumps(post_body)
         uri = '%s/lb/members' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_member(self, uuid):
-        uri = '%s/lb/members/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_member(self, uuid):
-        uri = '%s/lb/members/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def update_member(self, admin_state_up, member_id):
         put_body = {
             "member": {
@@ -543,13 +364,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/lb/members/%s' % (self.uri_prefix, member_id)
-        resp, body = self.put(uri, body=body, headers=self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_health_monitors(self):
-        uri = '%s/lb/health_monitors' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -564,21 +379,10 @@
         }
         body = json.dumps(post_body)
         uri = '%s/lb/health_monitors' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_health_monitor(self, uuid):
-        uri = '%s/lb/health_monitors/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_health_monitor(self, uuid):
-        uri = '%s/lb/health_monitors/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def update_health_monitor(self, admin_state_up, uuid):
         put_body = {
             "health_monitor": {
@@ -587,7 +391,7 @@
         }
         body = json.dumps(put_body)
         uri = '%s/lb/health_monitors/%s' % (self.uri_prefix, uuid)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -601,7 +405,7 @@
         body = json.dumps(post_body)
         uri = '%s/lb/pools/%s/health_monitors' % (self.uri_prefix,
                                                   pool_id)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -609,28 +413,10 @@
                                               pool_id):
         uri = '%s/lb/pools/%s/health_monitors/%s' % (self.uri_prefix, pool_id,
                                                      health_monitor_id)
-        resp, body = self.delete(uri, headers=self.headers)
+        resp, body = self.delete(uri)
         return resp, body
 
-    def list_extensions(self):
-        uri = '%s/extensions' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def show_extension_details(self, ext_alias):
-        uri = '%s/extensions/%s' % (self.uri_prefix, ext_alias)
-        resp, body = self.get(uri, headers=self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_vpn_services(self):
-        uri = '%s/vpn/vpnservices' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def create_vpn_service(self, subnet_id, router_id, **kwargs):
+    def create_vpnservice(self, subnet_id, router_id, **kwargs):
         post_body = {
             "vpnservice": {
                 "subnet_id": subnet_id,
@@ -641,22 +427,11 @@
             post_body['vpnservice'][key] = val
         body = json.dumps(post_body)
         uri = '%s/vpn/vpnservices' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_vpn_service(self, uuid):
-        uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_vpn_service(self, uuid):
-        uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def update_vpn_service(self, uuid, description):
+    def update_vpnservice(self, uuid, description):
         put_body = {
             "vpnservice": {
                 "description": description
@@ -664,25 +439,13 @@
         }
         body = json.dumps(put_body)
         uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
     def list_router_interfaces(self, uuid):
         uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_agents(self):
-        uri = '%s/agents' % self.uri_prefix
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def show_agent(self, agent_id):
-        uri = '%s/agents/%s' % (self.uri_prefix, agent_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = json.loads(body)
         return resp, body
 
@@ -694,53 +457,41 @@
         uri = '%s/agents/%s' % (self.uri_prefix, agent_id)
         agent = {"agent": agent_info}
         body = json.dumps(agent)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
     def list_routers_on_l3_agent(self, agent_id):
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = json.loads(body)
         return resp, body
 
     def list_l3_agents_hosting_router(self, router_id):
         uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def list_service_providers(self):
-        uri = '%s/service-providers' % self.uri_prefix
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = json.loads(body)
         return resp, body
 
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = json.loads(body)
         return resp, body
 
     def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = json.loads(body)
         return resp, body
 
     def remove_network_from_dhcp_agent(self, agent_id, network_id):
         uri = '%s/agents/%s/dhcp-networks/%s' % (self.uri_prefix, agent_id,
                                                  network_id)
-        resp, body = self.delete(uri, self.headers)
+        resp, body = self.delete(uri)
         return resp, body
 
-    def list_ike_policies(self):
-        uri = '%s/vpn/ikepolicies' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def create_ike_policy(self, name, **kwargs):
+    def create_ikepolicy(self, name, **kwargs):
         post_body = {
             "ikepolicy": {
                 "name": name,
@@ -750,26 +501,15 @@
             post_body['ikepolicy'][key] = val
         body = json.dumps(post_body)
         uri = '%s/vpn/ikepolicies' % (self.uri_prefix)
-        resp, body = self.post(uri, headers=self.headers, body=body)
+        resp, body = self.post(uri, body)
         body = json.loads(body)
         return resp, body
 
-    def show_ike_policy(self, uuid):
-        uri = '%s/vpn/ikepolicies/%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
-        body = json.loads(body)
-        return resp, body
-
-    def delete_ike_policy(self, uuid):
-        uri = '%s/vpn/ikepolicies/%s' % (self.uri_prefix, uuid)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def update_ike_policy(self, uuid, **kwargs):
+    def update_ikepolicy(self, uuid, **kwargs):
         put_body = {'ikepolicy': kwargs}
         body = json.dumps(put_body)
         uri = '%s/vpn/ikepolicies/%s' % (self.uri_prefix, uuid)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -782,7 +522,7 @@
             }
         }
         body = json.dumps(put_body)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
 
@@ -795,6 +535,6 @@
             }
         }
         body = json.dumps(put_body)
-        resp, body = self.put(uri, body=body, headers=self.headers)
+        resp, body = self.put(uri, body)
         body = json.loads(body)
         return resp, body
diff --git a/tempest/services/network/network_client_base.py b/tempest/services/network/network_client_base.py
new file mode 100644
index 0000000..b48dd34
--- /dev/null
+++ b/tempest/services/network/network_client_base.py
@@ -0,0 +1,136 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import urllib
+
+# the folliwing map is used to construct proper URI
+# for the given neutron resource
+service_resource_prefix_map = {
+    'networks': '',
+    'subnets': '',
+    'ports': '',
+    'pools': 'lb',
+    'vips': 'lb',
+    'health_monitors': 'lb',
+    'members': 'lb',
+    'vpnservices': 'vpn',
+    'ikepolicies': 'vpn'
+}
+
+# The following list represents resource names that do not require
+# changing underscore to a hyphen
+hyphen_exceptions = ["health_monitors"]
+
+# map from resource name to a plural name
+# needed only for those which can't be constructed as name + 's'
+resource_plural_map = {
+    'security_groups': 'security_groups',
+    'security_group_rules': 'security_group_rules',
+    'ikepolicy': 'ikepolicies',
+    'floating_ip': 'floatingips',
+    'quotas': 'quotas'
+}
+
+
+class NetworkClientBase(object):
+    def __init__(self, config, username, password,
+                 auth_url, tenant_name=None):
+        self.rest_client = self.get_rest_client(
+            config, username, password, auth_url, tenant_name)
+        self.rest_client.service = self.rest_client.config.network.catalog_type
+        self.version = '2.0'
+        self.uri_prefix = "v%s" % (self.version)
+
+    def get_rest_client(self, config, username, password,
+                        auth_url, tenant_name):
+        raise NotImplementedError
+
+    def post(self, uri, body, headers=None):
+        headers = headers or self.rest_client.headers
+        return self.rest_client.post(uri, body, headers)
+
+    def put(self, uri, body, headers=None):
+        headers = headers or self.rest_client.headers
+        return self.rest_client.put(uri, body, headers)
+
+    def get(self, uri, headers=None):
+        headers = headers or self.rest_client.headers
+        return self.rest_client.get(uri, headers)
+
+    def delete(self, uri, headers=None):
+        headers = headers or self.rest_client.headers
+        return self.rest_client.delete(uri, headers)
+
+    def deserialize_list(self, body):
+        raise NotImplementedError
+
+    def deserialize_single(self, body):
+        raise NotImplementedError
+
+    def get_uri(self, plural_name):
+        # get service prefix from resource name
+        service_prefix = service_resource_prefix_map.get(
+            plural_name)
+        if plural_name not in hyphen_exceptions:
+            plural_name = plural_name.replace("_", "-")
+        if service_prefix:
+            uri = '%s/%s/%s' % (self.uri_prefix, service_prefix,
+                                plural_name)
+        else:
+            uri = '%s/%s' % (self.uri_prefix, plural_name)
+        return uri
+
+    def pluralize(self, resource_name):
+        # get plural from map or just add 's'
+        return resource_plural_map.get(resource_name, resource_name + 's')
+
+    def _lister(self, plural_name):
+        def _list(**filters):
+            uri = self.get_uri(plural_name)
+            if filters:
+                uri += '?' + urllib.urlencode(filters)
+            resp, body = self.get(uri)
+            result = {plural_name: self.deserialize_list(body)}
+            return resp, result
+
+        return _list
+
+    def _deleter(self, resource_name):
+        def _delete(resource_id):
+            plural = self.pluralize(resource_name)
+            uri = '%s/%s' % (self.get_uri(plural), resource_id)
+            return self.delete(uri)
+
+        return _delete
+
+    def _shower(self, resource_name):
+        def _show(resource_id):
+            plural = self.pluralize(resource_name)
+            uri = '%s/%s' % (self.get_uri(plural), resource_id)
+            resp, body = self.get(uri)
+            body = self.deserialize_single(body)
+            return resp, body
+
+        return _show
+
+    def __getattr__(self, name):
+        method_prefixes = ["list_", "delete_", "show_"]
+        method_functors = [self._lister,
+                           self._deleter,
+                           self._shower]
+        for index, prefix in enumerate(method_prefixes):
+            prefix_len = len(prefix)
+            if name[:prefix_len] == prefix:
+                return method_functors[index](name[prefix_len:])
+        raise AttributeError(name)
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
old mode 100755
new mode 100644
index c46a523..a999e31
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -20,30 +20,28 @@
 from tempest.services.compute.xml.common import Document
 from tempest.services.compute.xml.common import Element
 from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.network import network_client_base as client_base
 
 
-class NetworkClientXML(RestClientXML):
+class NetworkClientXML(client_base.NetworkClientBase):
 
-    def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(NetworkClientXML, self).__init__(config, username, password,
-                                               auth_url, tenant_name)
-        self.service = self.config.network.catalog_type
-        self.version = '2.0'
-        self.uri_prefix = "v%s" % (self.version)
+    def get_rest_client(self, config, username, password,
+                        auth_url, tenant_name=None):
+        return RestClientXML(config, username, password,
+                             auth_url, tenant_name)
 
-    def list_networks(self):
-        uri = '%s/networks' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        networks = self._parse_array(etree.fromstring(body))
-        networks = {"networks": networks}
-        return resp, networks
+    def deserialize_list(self, body):
+        return self._parse_array(etree.fromstring(body))
+
+    def deserialize_single(self, body):
+        return _root_tag_fetcher_and_xml_to_json_parse(body)
 
     def create_network(self, name):
         uri = '%s/networks' % (self.uri_prefix)
         post_body = Element("network")
         p2 = Element("name", name)
         post_body.append(p2)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -55,21 +53,11 @@
                 p2 = Element("name", names[i])
                 p1.append(p2)
                 post_body.append(p1)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         networks = self._parse_array(etree.fromstring(body))
         networks = {"networks": networks}
         return resp, networks
 
-    def delete_network(self, uuid):
-        uri = '%s/networks/%s' % (self.uri_prefix, str(uuid))
-        return self.delete(uri, self.headers)
-
-    def show_network(self, uuid):
-        uri = '%s/networks/%s' % (self.uri_prefix, str(uuid))
-        resp, body = self.get(uri, self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
     def create_subnet(self, net_uuid, cidr):
         uri = '%s/subnets' % (self.uri_prefix)
         subnet = Element("subnet")
@@ -79,24 +67,7 @@
         subnet.append(p2)
         subnet.append(p3)
         subnet.append(p4)
-        resp, body = self.post(uri, str(Document(subnet)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_subnet(self, subnet_id):
-        uri = '%s/subnets/%s' % (self.uri_prefix, str(subnet_id))
-        return self.delete(uri, self.headers)
-
-    def list_subnets(self):
-        uri = '%s/subnets' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        subnets = self._parse_array(etree.fromstring(body))
-        subnets = {"subnets": subnets}
-        return resp, subnets
-
-    def show_subnet(self, uuid):
-        uri = '%s/subnets/%s' % (self.uri_prefix, str(uuid))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(subnet)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -108,39 +79,22 @@
         for key, val in kwargs.items():
             key = Element(key, val)
             port.append(key)
-        resp, body = self.post(uri, str(Document(port)), self.headers)
+        resp, body = self.post(uri, str(Document(port)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def delete_port(self, port_id):
-        uri = '%s/ports/%s' % (self.uri_prefix, str(port_id))
-        return self.delete(uri, self.headers)
-
     def _parse_array(self, node):
         array = []
         for child in node.getchildren():
             array.append(xml_to_json(child))
         return array
 
-    def list_ports(self):
-        url = '%s/ports' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        ports = self._parse_array(etree.fromstring(body))
-        ports = {"ports": ports}
-        return resp, ports
-
-    def show_port(self, port_id):
-        uri = '%s/ports/%s' % (self.uri_prefix, str(port_id))
-        resp, body = self.get(uri, self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
     def update_port(self, port_id, name):
         uri = '%s/ports/%s' % (self.uri_prefix, str(port_id))
         port = Element("port")
         p2 = Element("name", name)
         port.append(p2)
-        resp, body = self.put(uri, str(Document(port)), self.headers)
+        resp, body = self.put(uri, str(Document(port)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -149,7 +103,7 @@
         subnet = Element("subnet")
         p2 = Element("name", name)
         subnet.append(p2)
-        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        resp, body = self.put(uri, str(Document(subnet)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -158,7 +112,7 @@
         network = Element("network")
         p2 = Element("name", name)
         network.append(p2)
-        resp, body = self.put(uri, str(Document(network)), self.headers)
+        resp, body = self.put(uri, str(Document(network)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -167,34 +121,10 @@
         post_body = Element("security_group")
         p2 = Element("name", name)
         post_body.append(p2)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def list_security_groups(self):
-        url = '%s/security-groups' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        secgroups = self._parse_array(etree.fromstring(body))
-        secgroups = {"security_groups": secgroups}
-        return resp, secgroups
-
-    def delete_security_group(self, secgroup_id):
-        uri = '%s/security-groups/%s' % (self.uri_prefix, str(secgroup_id))
-        return self.delete(uri, self.headers)
-
-    def show_security_group(self, secgroup_id):
-        uri = '%s/security-groups/%s' % (self.uri_prefix, str(secgroup_id))
-        resp, body = self.get(uri, self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def list_security_group_rules(self):
-        url = '%s/security-group-rules' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        rules = self._parse_array(etree.fromstring(body))
-        rules = {"security_group_rules": rules}
-        return resp, rules
-
     def create_security_group_rule(self, secgroup_id,
                                    direction='ingress', **kwargs):
         uri = '%s/security-group-rules' % (self.uri_prefix)
@@ -206,17 +136,7 @@
         for key, val in kwargs.items():
             key = Element(key, val)
             rule.append(key)
-        resp, body = self.post(uri, str(Document(rule)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_security_group_rule(self, rule_id):
-        uri = '%s/security-group-rules/%s' % (self.uri_prefix, str(rule_id))
-        return self.delete(uri, self.headers)
-
-    def show_security_group_rule(self, rule_id):
-        uri = '%s/security-group-rules/%s' % (self.uri_prefix, str(rule_id))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(rule)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -230,7 +150,7 @@
                 p2 = Element(k, kv)
                 p1.append(p2)
             post_body.append(p1)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         subnets = self._parse_array(etree.fromstring(body))
         subnets = {"subnets": subnets}
         return resp, subnets
@@ -245,18 +165,11 @@
                 p2 = Element(k, kv)
                 p1.append(p2)
             post_body.append(p1)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         ports = self._parse_array(etree.fromstring(body))
         ports = {"ports": ports}
         return resp, ports
 
-    def list_vips(self):
-        url = '%s/lb/vips' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        vips = self._parse_array(etree.fromstring(body))
-        vips = {"vips": vips}
-        return resp, vips
-
     def create_vip(self, name, protocol, protocol_port, subnet_id, pool_id):
         uri = '%s/lb/vips' % (self.uri_prefix)
         post_body = Element("vip")
@@ -270,17 +183,7 @@
         post_body.append(p3)
         post_body.append(p4)
         post_body.append(p5)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_vip(self, vip_id):
-        uri = '%s/lb/vips/%s' % (self.uri_prefix, str(vip_id))
-        return self.delete(uri, self.headers)
-
-    def show_vip(self, vip_id):
-        uri = '%s/lb/vips/%s' % (self.uri_prefix, str(vip_id))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -289,17 +192,10 @@
         put_body = Element("vip")
         p2 = Element("name", new_name)
         put_body.append(p2)
-        resp, body = self.put(uri, str(Document(put_body)), self.headers)
+        resp, body = self.put(uri, str(Document(put_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def list_pools(self):
-        url = '%s/lb/pools' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        pools = self._parse_array(etree.fromstring(body))
-        pools = {"pools": pools}
-        return resp, pools
-
     def create_pool(self, name, lb_method, protocol, subnet_id):
         uri = '%s/lb/pools' % (self.uri_prefix)
         post_body = Element("pool")
@@ -309,17 +205,7 @@
         post_body.append(p1)
         post_body.append(p2)
         post_body.append(p3)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_pool(self, pool_id):
-        uri = '%s/lb/pools/%s' % (self.uri_prefix, str(pool_id))
-        return self.delete(uri, self.headers)
-
-    def show_pool(self, pool_id):
-        uri = '%s/lb/pools/%s' % (self.uri_prefix, str(pool_id))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -328,17 +214,10 @@
         put_body = Element("pool")
         p2 = Element("name", new_name)
         put_body.append(p2)
-        resp, body = self.put(uri, str(Document(put_body)), self.headers)
+        resp, body = self.put(uri, str(Document(put_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def list_members(self):
-        url = '%s/lb/members' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        members = self._parse_array(etree.fromstring(body))
-        members = {"members": members}
-        return resp, members
-
     def create_member(self, address, protocol_port, pool_id):
         uri = '%s/lb/members' % (self.uri_prefix)
         post_body = Element("member")
@@ -348,17 +227,7 @@
         post_body.append(p1)
         post_body.append(p2)
         post_body.append(p3)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_member(self, member_id):
-        uri = '%s/lb/members/%s' % (self.uri_prefix, str(member_id))
-        return self.delete(uri, self.headers)
-
-    def show_member(self, member_id):
-        uri = '%s/lb/members/%s' % (self.uri_prefix, str(member_id))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -367,17 +236,10 @@
         put_body = Element("member")
         p2 = Element("admin_state_up", admin_state_up)
         put_body.append(p2)
-        resp, body = self.put(uri, str(Document(put_body)), self.headers)
+        resp, body = self.put(uri, str(Document(put_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def list_health_monitors(self):
-        uri = '%s/lb/health_monitors' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        body = self._parse_array(etree.fromstring(body))
-        body = {"health_monitors": body}
-        return resp, body
-
     def create_health_monitor(self, delay, max_retries, Type, timeout):
         uri = '%s/lb/health_monitors' % (self.uri_prefix)
         post_body = Element("health_monitor")
@@ -389,17 +251,7 @@
         post_body.append(p2)
         post_body.append(p3)
         post_body.append(p4)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_health_monitor(self, uuid):
-        uri = '%s/lb/health_monitors/%s' % (self.uri_prefix, str(uuid))
-        return self.delete(uri, self.headers)
-
-    def show_health_monitor(self, uuid):
-        uri = '%s/lb/health_monitors/%s' % (self.uri_prefix, str(uuid))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -408,7 +260,7 @@
         put_body = Element("health_monitor")
         p2 = Element("admin_state_up", admin_state_up)
         put_body.append(p2)
-        resp, body = self.put(uri, str(Document(put_body)), self.headers)
+        resp, body = self.put(uri, str(Document(put_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -419,7 +271,7 @@
         post_body = Element("health_monitor")
         p1 = Element("id", health_monitor_id,)
         post_body.append(p1)
-        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        resp, body = self.post(uri, str(Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -427,18 +279,11 @@
                                               pool_id):
         uri = '%s/lb/pools/%s/health_monitors/%s' % (self.uri_prefix, pool_id,
                                                      health_monitor_id)
-        return self.delete(uri, self.headers)
-
-    def list_extensions(self):
-        url = '%s/extensions' % (self.uri_prefix)
-        resp, body = self.get(url, self.headers)
-        extensions = self._parse_array(etree.fromstring(body))
-        extensions = {"extensions": extensions}
-        return resp, extensions
+        return self.delete(uri)
 
     def show_extension_details(self, ext_alias):
         uri = '%s/extensions/%s' % (self.uri_prefix, str(ext_alias))
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -447,18 +292,7 @@
         router = Element("router")
         router.append(Element("name", name))
         deep_dict_to_xml(router, kwargs)
-        resp, body = self.post(uri, str(Document(router)), self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def delete_router(self, router_id):
-        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
-    def show_router(self, router_id):
-        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.post(uri, str(Document(router)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -467,7 +301,7 @@
         router = Element("router")
         for element, content in kwargs.iteritems():
             router.append(Element(element, content))
-        resp, body = self.put(uri, str(Document(router)), self.headers)
+        resp, body = self.put(uri, str(Document(router)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -475,7 +309,7 @@
         uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
               router_id)
         subnet = Element("subnet_id", subnet_id)
-        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        resp, body = self.put(uri, str(Document(subnet)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -483,7 +317,7 @@
         uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
               router_id)
         port = Element("port_id", port_id)
-        resp, body = self.put(uri, str(Document(port)), self.headers)
+        resp, body = self.put(uri, str(Document(port)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -491,7 +325,7 @@
         uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
               router_id)
         subnet = Element("subnet_id", subnet_id)
-        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        resp, body = self.put(uri, str(Document(subnet)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -499,7 +333,7 @@
         uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
               router_id)
         port = Element("port_id", port_id)
-        resp, body = self.put(uri, str(Document(port)), self.headers)
+        resp, body = self.put(uri, str(Document(port)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -509,28 +343,10 @@
         floatingip.append(Element("floating_network_id", ext_network_id))
         for element, content in kwargs.iteritems():
             floatingip.append(Element(element, content))
-        resp, body = self.post(uri, str(Document(floatingip)), self.headers)
+        resp, body = self.post(uri, str(Document(floatingip)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def show_floating_ip(self, floating_ip_id):
-        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
-        resp, body = self.get(uri, self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def list_floating_ips(self):
-        uri = '%s/floatingips' % (self.uri_prefix)
-        resp, body = self.get(uri, self.headers)
-        floatingips = self._parse_array(etree.fromstring(body))
-        floatingips = {"floatingips": floatingips}
-        return resp, floatingips
-
-    def delete_floating_ip(self, floating_ip_id):
-        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
-        resp, body = self.delete(uri, self.headers)
-        return resp, body
-
     def update_floating_ip(self, floating_ip_id, **kwargs):
         uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
         floatingip = Element('floatingip')
@@ -543,70 +359,49 @@
                 floatingip.append(xml_elem)
             else:
                 floatingip.append(Element(element, content))
-        resp, body = self.put(uri, str(Document(floatingip)), self.headers)
+        resp, body = self.put(uri, str(Document(floatingip)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def list_router_interfaces(self, uuid):
         uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         ports = self._parse_array(etree.fromstring(body))
         ports = {"ports": ports}
         return resp, ports
 
-    def list_agents(self):
-        uri = '%s/agents' % self.uri_prefix
-        resp, body = self.get(uri, self.headers)
-        agents = self._parse_array(etree.fromstring(body))
-        agents = {'agents': agents}
-        return resp, agents
-
-    def show_agent(self, agent_id):
-        uri = '%s/agents/%s' % (self.uri_prefix, agent_id)
-        resp, body = self.get(uri, self.headers)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
     def update_agent(self, agent_id, agent_info):
         uri = '%s/agents/%s' % (self.uri_prefix, agent_id)
         agent = Element('agent')
         for (key, value) in agent_info.items():
             p = Element(key, value)
             agent.append(p)
-        resp, body = self.put(uri, body=str(Document(agent)),
-                              headers=self.headers)
+        resp, body = self.put(uri, str(Document(agent)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def list_routers_on_l3_agent(self, agent_id):
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def list_l3_agents_hosting_router(self, router_id):
         uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
-    def list_service_providers(self):
-        uri = '%s/service-providers' % self.uri_prefix
-        resp, body = self.get(uri, self.headers)
-        providers = self._parse_array(etree.fromstring(body))
-        body = {'service_providers': providers}
-        return resp, body
-
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         agents = self._parse_array(etree.fromstring(body))
         body = {'agents': agents}
         return resp, body
 
     def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
-        resp, body = self.get(uri, self.headers)
+        resp, body = self.get(uri)
         networks = self._parse_array(etree.fromstring(body))
         body = {'networks': networks}
         return resp, body
@@ -614,7 +409,7 @@
     def remove_network_from_dhcp_agent(self, agent_id, network_id):
         uri = '%s/agents/%s/dhcp-networks/%s' % (self.uri_prefix, agent_id,
                                                  network_id)
-        resp, body = self.delete(uri, self.headers)
+        resp, body = self.delete(uri)
         return resp, body