Split out Neutron subnets client

Splitting out a subnets client for Neutron.

Partially implements blueprint consistent-service-method-names

Change-Id: I52c9d099b97540440fa98343c736b894d130a07e
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 2fd7520..50b3d78 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -42,6 +42,7 @@
         cls.client = cls.servers_client
         cls.network_client = cls.os.network_client
         cls.networks_client = cls.os.networks_client
+        cls.subnets_client = cls.os.subnets_client
 
     @classmethod
     def resource_setup(cls):
@@ -74,11 +75,11 @@
         self.addCleanup(self.networks_client.delete_network,
                         net['network']['id'])
 
-        subnet = self.network_client.create_subnet(
+        subnet = self.subnets_client.create_subnet(
             network_id=net['network']['id'],
             cidr=cidr,
             ip_version=4)
-        self.addCleanup(self.network_client.delete_subnet,
+        self.addCleanup(self.subnets_client.delete_subnet,
                         subnet['subnet']['id'])
         return net
 
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 62aa18e..ac53587 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -103,8 +103,9 @@
         self.addCleanup(self._try_delete_resource,
                         self.admin_networks_client.delete_network,
                         external_network['id'])
-        subnet = self.create_subnet(external_network, client=client,
-                                    enable_dhcp=False)
+        subnet = self.create_subnet(
+            external_network, client=self.admin_subnets_client,
+            enable_dhcp=False)
         body = client.create_floatingip(
             floating_network_id=external_network['id'])
         created_floating_ip = body['floatingip']
@@ -121,7 +122,7 @@
         self.assertNotIn(created_floating_ip['id'],
                          (f['id'] for f in floatingip_list['floatingips']))
         # Verifies subnet is deleted
-        subnet_list = client.list_subnets()
+        subnet_list = self.admin_subnets_client.list_subnets()
         self.assertNotIn(subnet['id'],
                          (s['id'] for s in subnet_list))
         # Removes subnet from the cleanup list
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 39bdcff..26cf180 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -74,6 +74,7 @@
         super(BaseNetworkTest, cls).setup_clients()
         cls.client = cls.os.network_client
         cls.networks_client = cls.os.networks_client
+        cls.subnets_client = cls.os.subnets_client
 
     @classmethod
     def resource_setup(cls):
@@ -115,7 +116,7 @@
                                          router)
             # Clean up subnets
             for subnet in cls.subnets:
-                cls._try_delete_resource(cls.client.delete_subnet,
+                cls._try_delete_resource(cls.subnets_client.delete_subnet,
                                          subnet['id'])
             # Clean up networks
             for network in cls.networks:
@@ -160,7 +161,7 @@
 
         # allow tests to use admin client
         if not client:
-            client = cls.client
+            client = cls.subnets_client
 
         # The cidr and mask_bits depend on the ip version.
         ip_version = ip_version if ip_version is not None else cls._ip_version
@@ -267,6 +268,7 @@
         super(BaseAdminNetworkTest, cls).setup_clients()
         cls.admin_client = cls.os_adm.network_client
         cls.admin_networks_client = cls.os_adm.networks_client
+        cls.admin_subnets_client = cls.os_adm.subnets_client
 
     @classmethod
     def create_metering_label(cls, name, description):
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index f362f85..631a38b 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -75,11 +75,11 @@
                 if port['id'] in [p['id'] for p in self.ports]:
                     self.client.delete_port(port['id'])
                     self._remove_from_list_by_index(self.ports, port)
-        body = self.client.list_subnets()
+        body = self.subnets_client.list_subnets()
         subnets = body['subnets']
         for subnet in subnets:
             if subnet['id'] in [s['id'] for s in self.subnets]:
-                self.client.delete_subnet(subnet['id'])
+                self.subnets_client.delete_subnet(subnet['id'])
                 self._remove_from_list_by_index(self.subnets, subnet)
         body = self.client.list_routers()
         routers = body['routers']
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index a4ab43a..c5b2080 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -194,7 +194,7 @@
         subnet_id = subnet['id']
         # Verify subnet update
         new_name = "New_subnet"
-        body = self.client.update_subnet(subnet_id, name=new_name)
+        body = self.subnets_client.update_subnet(subnet_id, name=new_name)
         updated_subnet = body['subnet']
         self.assertEqual(updated_subnet['name'], new_name)
 
@@ -241,7 +241,7 @@
     @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
     def test_show_subnet(self):
         # Verify the details of a subnet
-        body = self.client.show_subnet(self.subnet['id'])
+        body = self.subnets_client.show_subnet(self.subnet['id'])
         subnet = body['subnet']
         self.assertNotEmpty(subnet, "Subnet returned has no fields")
         for key in ['id', 'cidr']:
@@ -252,8 +252,8 @@
     def test_show_subnet_fields(self):
         # Verify specific fields of a subnet
         fields = ['id', 'network_id']
-        body = self.client.show_subnet(self.subnet['id'],
-                                       fields=fields)
+        body = self.subnets_client.show_subnet(self.subnet['id'],
+                                               fields=fields)
         subnet = body['subnet']
         self.assertEqual(sorted(subnet.keys()), sorted(fields))
         for field_name in fields:
@@ -263,7 +263,7 @@
     @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
     def test_list_subnets(self):
         # Verify the subnet exists in the list of all subnets
-        body = self.client.list_subnets()
+        body = self.subnets_client.list_subnets()
         subnets = [subnet['id'] for subnet in body['subnets']
                    if subnet['id'] == self.subnet['id']]
         self.assertNotEmpty(subnets, "Created subnet not found in the list")
@@ -272,7 +272,7 @@
     def test_list_subnets_fields(self):
         # Verify specific fields of subnets
         fields = ['id', 'network_id']
-        body = self.client.list_subnets(fields=fields)
+        body = self.subnets_client.list_subnets(fields=fields)
         subnets = body['subnets']
         self.assertNotEmpty(subnets, "Subnet list returned is empty")
         for subnet in subnets:
@@ -303,7 +303,7 @@
         body = self.networks_client.delete_network(net_id)
 
         # Verify that the subnet got automatically deleted.
-        self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
+        self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
                           subnet_id)
 
         # Since create_subnet adds the subnet to the delete list, and it is
@@ -362,8 +362,8 @@
                   'gateway_ip': new_gateway, 'enable_dhcp': True}
 
         new_name = "New_subnet"
-        body = self.client.update_subnet(subnet_id, name=new_name,
-                                         **kwargs)
+        body = self.subnets_client.update_subnet(subnet_id, name=new_name,
+                                                 **kwargs)
         updated_subnet = body['subnet']
         kwargs['name'] = new_name
         self.assertEqual(sorted(updated_subnet['dns_nameservers']),
@@ -398,7 +398,7 @@
         # subnets_iter is a list (iterator) of lists. This flattens it to a
         # list of UUIDs
         public_subnets_iter = itertools.chain(*subnets_iter)
-        body = self.client.list_subnets()
+        body = self.subnets_client.list_subnets()
         subnets = [sub['id'] for sub in body['subnets']
                    if sub['id'] in public_subnets_iter]
         self.assertEmpty(subnets, "Public subnets visible")
@@ -435,9 +435,9 @@
 
     def _delete_subnets(self, created_subnets):
         for n in created_subnets:
-            self.client.delete_subnet(n['id'])
+            self.subnets_client.delete_subnet(n['id'])
         # Asserting that the subnets are not found in the list after deletion
-        body = self.client.list_subnets()
+        body = self.subnets_client.list_subnets()
         subnets_list = [subnet['id'] for subnet in body['subnets']]
         for n in created_subnets:
             self.assertNotIn(n['id'], subnets_list)
@@ -496,7 +496,7 @@
         created_subnets = body['subnets']
         self.addCleanup(self._delete_subnets, created_subnets)
         # Asserting that the subnets are found in the list after creation
-        body = self.client.list_subnets()
+        body = self.subnets_client.list_subnets()
         subnets_list = [subnet['id'] for subnet in body['subnets']]
         for n in created_subnets:
             self.assertIsNotNone(n['id'])
@@ -576,7 +576,7 @@
         # Verifies Subnet GW is None in IPv4
         self.assertEqual(subnet2['gateway_ip'], None)
         # Verifies all 2 subnets in the same network
-        body = self.client.list_subnets()
+        body = self.subnets_client.list_subnets()
         subnets = [sub['id'] for sub in body['subnets']
                    if sub['network_id'] == network['id']]
         test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
@@ -621,9 +621,9 @@
                                              'ipv6_address_mode': mode})
         port = self.create_port(slaac_network)
         self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
-        self.client.delete_subnet(subnet_slaac['id'])
+        self.subnets_client.delete_subnet(subnet_slaac['id'])
         self.subnets.pop()
-        subnets = self.client.list_subnets()
+        subnets = self.subnets_client.list_subnets()
         subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
         self.assertNotIn(subnet_slaac['id'], subnet_ids,
                          "Subnet wasn't deleted")
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 4d1971f..4fe31cf 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -34,7 +34,7 @@
     @test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
     def test_show_non_existent_subnet(self):
         non_exist_id = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
+        self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
                           non_exist_id)
 
     @test.attr(type=['negative'])
@@ -64,7 +64,7 @@
     @test.idempotent_id('1cc47884-ac52-4415-a31c-e7ce5474a868')
     def test_update_non_existent_subnet(self):
         non_exist_id = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.update_subnet,
+        self.assertRaises(lib_exc.NotFound, self.subnets_client.update_subnet,
                           non_exist_id, name='new_name')
 
     @test.attr(type=['negative'])
@@ -72,7 +72,7 @@
     def test_delete_non_existent_subnet(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.delete_subnet, non_exist_id)
+                          self.subnets_client.delete_subnet, non_exist_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('13d3b106-47e6-4b9b-8d53-dae947f092fe')
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 321473c..6f58075 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -106,7 +106,7 @@
         allocation_pools = {'allocation_pools': [{'start': str(address + 4),
                                                   'end': str(address + 6)}]}
         subnet = self.create_subnet(network, **allocation_pools)
-        self.addCleanup(self.client.delete_subnet, subnet['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
         body = self.client.create_port(network_id=net_id)
         self.addCleanup(self.client.delete_port, body['port']['id'])
         port = body['port']
@@ -155,7 +155,7 @@
         # Create network and subnet
         network = self.create_network()
         subnet = self.create_subnet(network)
-        self.addCleanup(self.client.delete_subnet, subnet['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
         # Create two ports
         port_1 = self.client.create_port(network_id=network['id'])
         self.addCleanup(self.client.delete_port, port_1['port']['id'])
@@ -187,7 +187,7 @@
         network = self.create_network()
         self.addCleanup(self.networks_client.delete_network, network['id'])
         subnet = self.create_subnet(network)
-        self.addCleanup(self.client.delete_subnet, subnet['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
         router = self.create_router(data_utils.rand_name('router-'))
         self.addCleanup(self.client.delete_router, router['id'])
         port = self.client.create_port(network_id=network['id'])
@@ -220,9 +220,9 @@
         network = self.create_network()
         self.addCleanup(self.networks_client.delete_network, network['id'])
         subnet_1 = self.create_subnet(network)
-        self.addCleanup(self.client.delete_subnet, subnet_1['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet_1['id'])
         subnet_2 = self.create_subnet(network)
-        self.addCleanup(self.client.delete_subnet, subnet_2['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet_2['id'])
         fixed_ip_1 = [{'subnet_id': subnet_1['id']}]
         fixed_ip_2 = [{'subnet_id': subnet_2['id']}]
 
@@ -247,7 +247,7 @@
 
     def _update_port_with_security_groups(self, security_groups_names):
         subnet_1 = self.create_subnet(self.network)
-        self.addCleanup(self.client.delete_subnet, subnet_1['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet_1['id'])
         fixed_ip_1 = [{'subnet_id': subnet_1['id']}]
 
         security_groups_list = list()
@@ -328,7 +328,7 @@
         network = self.create_network()
         self.addCleanup(self.networks_client.delete_network, network['id'])
         subnet = self.create_subnet(network)
-        self.addCleanup(self.client.delete_subnet, subnet['id'])
+        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
         port = self.create_port(network, security_groups=[])
         self.addCleanup(self.client.delete_port, port['id'])
         self.assertIsNotNone(port['security_groups'])
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 99c2a97..070150d 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -44,6 +44,7 @@
     def setup_clients(cls):
         super(NeutronResourcesTestJSON, cls).setup_clients()
         cls.network_client = cls.os.network_client
+        cls.subnets_client = cls.os.subnets_client
 
     @classmethod
     def resource_setup(cls):
@@ -130,7 +131,7 @@
     def test_created_subnet(self):
         """Verifies created subnet."""
         subnet_id = self.test_resources.get('Subnet')['physical_resource_id']
-        body = self.network_client.show_subnet(subnet_id)
+        body = self.subnets_client.show_subnet(subnet_id)
         subnet = body['subnet']
         network_id = self.test_resources.get('Network')['physical_resource_id']
         self.assertEqual(subnet_id, subnet['id'])
diff --git a/tempest/clients.py b/tempest/clients.py
index cffdc3f..efb6fea 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -108,6 +108,7 @@
     MessagingClient
 from tempest.services.network.json.network_client import NetworkClient
 from tempest.services.network.json.networks_client import NetworksClient
+from tempest.services.network.json.subnets_client import SubnetsClient
 from tempest.services.object_storage.account_client import AccountClient
 from tempest.services.object_storage.container_client import ContainerClient
 from tempest.services.object_storage.object_client import ObjectClient
@@ -205,6 +206,14 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **self.default_params)
+        self.subnets_client = SubnetsClient(
+            self.auth_provider,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout,
+            **self.default_params)
         self.messaging_client = MessagingClient(
             self.auth_provider,
             CONF.messaging.catalog_type,
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 02c6e7f..a90b0ce 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -94,6 +94,7 @@
 from tempest.services.identity.v2.json import identity_client
 from tempest.services.network.json import network_client
 from tempest.services.network.json import networks_client
+from tempest.services.network.json import subnets_client
 import tempest_lib.auth
 from tempest_lib.common.utils import data_utils
 import tempest_lib.exceptions
@@ -138,6 +139,7 @@
     )
     network_admin = None
     networks_admin = None
+    subnets_admin = None
     neutron_iso_networks = False
     if (CONF.service_available.neutron and
         CONF.auth.create_isolated_networks):
@@ -154,12 +156,19 @@
             CONF.network.region or CONF.identity.region,
             endpoint_type='adminURL',
             **params)
-    return identity_admin, neutron_iso_networks, network_admin, networks_admin
+        subnets_admin = subnets_client.SubnetsClient(
+            _auth,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type='adminURL',
+            **params)
+    return (identity_admin, neutron_iso_networks, network_admin,
+            networks_admin, subnets_admin)
 
 
 def create_resources(opts, resources):
     (identity_admin, neutron_iso_networks,
-     network_admin, networks_admin) = get_admin_clients(opts)
+     network_admin, networks_admin, subnets_admin) = get_admin_clients(opts)
     roles = identity_admin.list_roles()['roles']
     for u in resources['users']:
         u['role_ids'] = []
@@ -202,7 +211,8 @@
         for u in resources['users']:
             tenant = identity_admin.get_tenant_by_name(u['tenant'])
             network_name, router_name = create_network_resources(
-                network_admin, networks_admin, tenant['id'], u['name'])
+                network_admin, networks_admin, subnets_admin, tenant['id'],
+                u['name'])
             u['network'] = network_name
             u['router'] = router_name
         LOG.info('Networks created')
@@ -229,7 +239,7 @@
 
 
 def create_network_resources(network_admin_client, networks_admin_client,
-                             tenant_id, name):
+                             subnets_admin_client, tenant_id, name):
 
     def _create_network(name):
         resp_body = networks_admin_client.create_network(
@@ -241,7 +251,7 @@
         mask_bits = CONF.network.tenant_network_mask_bits
         for subnet_cidr in base_cidr.subnet(mask_bits):
             try:
-                resp_body = network_admin_client.\
+                resp_body = subnets_admin_client.\
                     create_subnet(
                         network_id=network_id, cidr=str(subnet_cidr),
                         name=subnet_name,
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 6c79abc..64e1303 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -382,6 +382,7 @@
         super(NetworkService, self).__init__(kwargs)
         self.client = manager.network_client
         self.networks_client = manager.networks_client
+        self.subnets_client = manager.subnets_client
 
     def _filter_by_conf_networks(self, item_list):
         if not item_list or not all(('network_id' in i for i in item_list)):
@@ -676,7 +677,7 @@
 class NetworkSubnetService(NetworkService):
 
     def list(self):
-        client = self.client
+        client = self.subnets_client
         subnets = client.list_subnets(**self.tenant_filter)
         subnets = subnets['subnets']
         if self.is_preserve:
@@ -685,7 +686,7 @@
         return subnets
 
     def delete(self):
-        client = self.client
+        client = self.subnets_client
         subnets = self.list()
         for subnet in subnets:
             try:
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 2dbcd98..d9588b3 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -129,6 +129,7 @@
 from tempest.services.identity.v2.json import identity_client
 from tempest.services.image.v2.json import image_client
 from tempest.services.network.json import network_client
+from tempest.services.network.json import subnets_client
 from tempest.services.object_storage import container_client
 from tempest.services.object_storage import object_client
 from tempest.services.telemetry.json import telemetry_client
@@ -240,6 +241,14 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **default_params)
+        self.subnets = subnets_client.SubnetsClient(
+            _auth,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout,
+            **default_params)
 
 
 def load_resources(fname):
@@ -769,9 +778,9 @@
     LOG.info("Destroying subnets")
     for subnet in subnets:
         client = client_for_user(subnet['owner'])
-        subnet_id = _get_resource_by_name(client.networks,
+        subnet_id = _get_resource_by_name(client.subnets,
                                           'subnets', subnet['name'])['id']
-        client.networks.delete_subnet(subnet_id)
+        client.subnets.delete_subnet(subnet_id)
 
 
 def create_routers(routers):
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index f0b6625..8ff189a 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -41,8 +41,9 @@
             'identity_admin', fill_in=True,
             identity_version=self.identity_version)
         (self.identity_admin_client, self.network_admin_client,
-         self.networks_admin_client) = self._get_admin_clients()
-        # Domain where dynamic credentials are provisioned (v3 only).
+         self.networks_admin_client,
+         self.subnets_admin_client) = self._get_admin_clients()
+        # Domain where isolated credentials are provisioned (v3 only).
         # Use that of the admin account is None is configured.
         self.creds_domain_name = None
         if self.identity_version == 'v3':
@@ -61,9 +62,11 @@
         """
         os = clients.Manager(self.default_admin_creds)
         if self.identity_version == 'v2':
-            return os.identity_client, os.network_client, os.networks_client
+            return (os.identity_client, os.network_client, os.networks_client,
+                    os.subnets_client)
         else:
-            return os.identity_v3_client, os.network_client, os.networks_client
+            return (os.identity_v3_client, os.network_client,
+                    os.networks_client, os.subnets_client)
 
     def _create_creds(self, suffix="", admin=False, roles=None):
         """Create random credentials under the following schema.
@@ -168,7 +171,7 @@
         for subnet_cidr in base_cidr.subnet(mask_bits):
             try:
                 if self.network_resources:
-                    resp_body = self.network_admin_client.\
+                    resp_body = self.subnets_admin_client.\
                         create_subnet(
                             network_id=network_id, cidr=str(subnet_cidr),
                             name=subnet_name,
@@ -176,7 +179,7 @@
                             enable_dhcp=self.network_resources['dhcp'],
                             ip_version=4)
                 else:
-                    resp_body = self.network_admin_client.\
+                    resp_body = self.subnets_admin_client.\
                         create_subnet(network_id=network_id,
                                       cidr=str(subnet_cidr),
                                       name=subnet_name,
@@ -260,9 +263,9 @@
                      router_name)
 
     def _clear_isolated_subnet(self, subnet_id, subnet_name):
-        net_client = self.network_admin_client
+        client = self.subnets_admin_client
         try:
-            net_client.delete_subnet(subnet_id)
+            client.delete_subnet(subnet_id)
         except lib_exc.NotFound:
             LOG.warn('subnet with name: %s not found for delete' %
                      subnet_name)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index fd84570..df46ff4 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -62,6 +62,7 @@
         # Neutron network client
         cls.network_client = cls.manager.network_client
         cls.networks_client = cls.manager.networks_client
+        cls.subnets_client = cls.manager.subnets_client
         # Heat client
         cls.orchestration_client = cls.manager.orchestration_client
 
@@ -630,7 +631,7 @@
 
     def _list_subnets(self, *args, **kwargs):
         """List subnets using admin creds """
-        subnets_list = self.admin_manager.network_client.list_subnets(
+        subnets_list = self.admin_manager.subnets_client.list_subnets(
             *args, **kwargs)
         return subnets_list['subnets']
 
@@ -652,14 +653,16 @@
             *args, **kwargs)
         return agents_list['agents']
 
-    def _create_subnet(self, network, client=None, namestart='subnet-smoke',
-                       **kwargs):
+    def _create_subnet(self, network, client=None, subnets_client=None,
+                       namestart='subnet-smoke', **kwargs):
         """
         Create a subnet for the given network within the cidr block
         configured for tenant networks.
         """
         if not client:
             client = self.network_client
+        if not subnets_client:
+            subnets_client = self.subnets_client
 
         def cidr_in_use(cidr, tenant_id):
             """
@@ -697,15 +700,16 @@
                 **kwargs
             )
             try:
-                result = client.create_subnet(**subnet)
+                result = subnets_client.create_subnet(**subnet)
                 break
             except lib_exc.Conflict as e:
                 is_overlapping_cidr = 'overlaps with another subnet' in str(e)
                 if not is_overlapping_cidr:
                     raise
         self.assertIsNotNone(result, 'Unable to allocate tenant network')
-        subnet = net_resources.DeletableSubnet(client=client,
-                                               **result['subnet'])
+        subnet = net_resources.DeletableSubnet(
+            network_client=client, subnets_client=subnets_client,
+            **result['subnet'])
         self.assertEqual(subnet.cidr, str_cidr)
         self.addCleanup(self.delete_wrapper, subnet.delete)
         return subnet
@@ -1062,7 +1066,8 @@
         self.assertEqual(admin_state_up, router.admin_state_up)
 
     def create_networks(self, client=None, networks_client=None,
-                        tenant_id=None, dns_nameservers=None):
+                        subnets_client=None, tenant_id=None,
+                        dns_nameservers=None):
         """Create a network with a subnet connected to a router.
 
         The baremetal driver is a special case since all nodes are
@@ -1092,7 +1097,8 @@
                 tenant_id=tenant_id)
             router = self._get_router(client=client, tenant_id=tenant_id)
 
-            subnet_kwargs = dict(network=network, client=client)
+            subnet_kwargs = dict(network=network, client=client,
+                                 subnets_client=subnets_client)
             # use explicit check because empty list is a valid option
             if dns_nameservers is not None:
                 subnet_kwargs['dns_nameservers'] = dns_nameservers
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index a35c0b2..3c11c22 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -291,7 +291,8 @@
     def _create_tenant_network(self, tenant):
         network, subnet, router = self.create_networks(
             client=tenant.manager.network_client,
-            networks_client=tenant.manager.networks_client)
+            networks_client=tenant.manager.networks_client,
+            subnets_client=tenant.manager.subnets_client)
         tenant.set_network(network, subnet, router)
 
     def _set_compute_context(self, tenant):
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index d766aa5..7821f37 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -34,28 +34,6 @@
     quotas
     """
 
-    def create_subnet(self, **kwargs):
-        uri = '/subnets'
-        post_data = {'subnet': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_subnet(self, subnet_id, **kwargs):
-        uri = '/subnets/%s' % subnet_id
-        post_data = {'subnet': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_subnet(self, subnet_id, **fields):
-        uri = '/subnets/%s' % subnet_id
-        return self.show_resource(uri, **fields)
-
-    def delete_subnet(self, subnet_id):
-        uri = '/subnets/%s' % subnet_id
-        return self.delete_resource(uri)
-
-    def list_subnets(self, **filters):
-        uri = '/subnets'
-        return self.list_resources(uri, **filters)
-
     def create_port(self, **kwargs):
         uri = '/ports'
         post_data = {'port': kwargs}
diff --git a/tempest/services/network/json/subnets_client.py b/tempest/services/network/json/subnets_client.py
new file mode 100644
index 0000000..957b606
--- /dev/null
+++ b/tempest/services/network/json/subnets_client.py
@@ -0,0 +1,38 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.services.network.json import base
+
+
+class SubnetsClient(base.BaseNetworkClient):
+
+    def create_subnet(self, **kwargs):
+        uri = '/subnets'
+        post_data = {'subnet': kwargs}
+        return self.create_resource(uri, post_data)
+
+    def update_subnet(self, subnet_id, **kwargs):
+        uri = '/subnets/%s' % subnet_id
+        post_data = {'subnet': kwargs}
+        return self.update_resource(uri, post_data)
+
+    def show_subnet(self, subnet_id, **fields):
+        uri = '/subnets/%s' % subnet_id
+        return self.show_resource(uri, **fields)
+
+    def delete_subnet(self, subnet_id):
+        uri = '/subnets/%s' % subnet_id
+        return self.delete_resource(uri)
+
+    def list_subnets(self, **filters):
+        uri = '/subnets'
+        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 23d936e..16d9823 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -41,7 +41,9 @@
 
     def __init__(self, *args, **kwargs):
         self.client = kwargs.pop('client', None)
+        self.network_client = kwargs.pop('network_client', None)
         self.networks_client = kwargs.pop('networks_client', None)
+        self.subnets_client = kwargs.pop('subnets_client', None)
         super(DeletableResource, self).__init__(*args, **kwargs)
 
     def __str__(self):
@@ -83,23 +85,23 @@
         self._router_ids = set()
 
     def update(self, *args, **kwargs):
-        result = self.client.update_subnet(self.id,
-                                           *args,
-                                           **kwargs)
+        result = self.subnets_client.update_subnet(self.id,
+                                                   *args,
+                                                   **kwargs)
         return super(DeletableSubnet, self).update(**result['subnet'])
 
     def add_to_router(self, router_id):
         self._router_ids.add(router_id)
-        self.client.add_router_interface_with_subnet_id(router_id,
-                                                        subnet_id=self.id)
+        self.network_client.add_router_interface_with_subnet_id(
+            router_id, subnet_id=self.id)
 
     def delete(self):
         for router_id in self._router_ids.copy():
-            self.client.remove_router_interface_with_subnet_id(
+            self.network_client.remove_router_interface_with_subnet_id(
                 router_id,
                 subnet_id=self.id)
             self._router_ids.remove(router_id)
-        self.client.delete_subnet(self.id)
+        self.subnets_client.delete_subnet(self.id)
 
 
 class DeletableRouter(DeletableResource):
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 4a8f729..fc3d984 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -380,7 +380,7 @@
 
         javelin.destroy_subnets([self.fake_object])
 
-        mocked_function = self.fake_client.networks.delete_subnet
+        mocked_function = self.fake_client.subnets.delete_subnet
         mocked_function.assert_called_once_with(fake_subnet_id)
 
     def test_destroy_routers(self):
diff --git a/tempest/tests/test_dynamic_creds.py b/tempest/tests/test_dynamic_creds.py
index 5f57268..92ed526 100644
--- a/tempest/tests/test_dynamic_creds.py
+++ b/tempest/tests/test_dynamic_creds.py
@@ -127,7 +127,7 @@
 
     def _mock_subnet_create(self, iso_creds, id, name):
         subnet_fix = self.useFixture(mockpatch.PatchObject(
-            iso_creds.network_admin_client,
+            iso_creds.subnets_admin_client,
             'create_subnet',
             return_value={'subnet': {'id': id, 'name': name}}))
         return subnet_fix
@@ -272,7 +272,7 @@
         net = mock.patch.object(creds.networks_admin_client,
                                 'delete_network')
         net_mock = net.start()
-        subnet = mock.patch.object(creds.network_admin_client,
+        subnet = mock.patch.object(creds.subnets_admin_client,
                                    'delete_subnet')
         subnet_mock = subnet.start()
         router = mock.patch.object(creds.network_admin_client,
@@ -362,7 +362,7 @@
         net = mock.patch.object(creds.networks_admin_client,
                                 'delete_network')
         net_mock = net.start()
-        subnet = mock.patch.object(creds.network_admin_client,
+        subnet = mock.patch.object(creds.subnets_admin_client,
                                    'delete_subnet')
         subnet_mock = subnet.start()
         router = mock.patch.object(creds.network_admin_client,
@@ -496,7 +496,7 @@
         net = mock.patch.object(creds.networks_admin_client,
                                 'delete_network')
         net_mock = net.start()
-        subnet = mock.patch.object(creds.network_admin_client,
+        subnet = mock.patch.object(creds.subnets_admin_client,
                                    'delete_subnet')
         subnet_mock = subnet.start()
         router = mock.patch.object(creds.network_admin_client,