Merge "Consider pre-existing VMs when testing server list"
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index 0bad96a..94edb6c 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -22,7 +22,7 @@
     @test.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
     def test_add_image_member(self):
         image = self._create_image()
-        self.image_member_client.add_member(self.alt_tenant_id, image)
+        self.image_member_client.create_image_member(image, self.alt_tenant_id)
         body = self.image_member_client.list_image_members(image)
         members = body['members']
         members = map(lambda x: x['member_id'], members)
@@ -33,9 +33,10 @@
     @test.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
     def test_get_shared_images(self):
         image = self._create_image()
-        self.image_member_client.add_member(self.alt_tenant_id, image)
+        self.image_member_client.create_image_member(image, self.alt_tenant_id)
         share_image = self._create_image()
-        self.image_member_client.add_member(self.alt_tenant_id, share_image)
+        self.image_member_client.create_image_member(share_image,
+                                                     self.alt_tenant_id)
         body = self.image_member_client.list_shared_images(
             self.alt_tenant_id)
         images = body['shared_images']
@@ -46,8 +47,10 @@
     @test.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
     def test_remove_member(self):
         image_id = self._create_image()
-        self.image_member_client.add_member(self.alt_tenant_id, image_id)
-        self.image_member_client.delete_member(self.alt_tenant_id, image_id)
+        self.image_member_client.create_image_member(image_id,
+                                                     self.alt_tenant_id)
+        self.image_member_client.delete_image_member(image_id,
+                                                     self.alt_tenant_id)
         body = self.image_member_client.list_image_members(image_id)
         members = body['members']
         self.assertEqual(0, len(members), str(members))
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
index d46a836..2538781 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -26,8 +26,8 @@
         # Add member with non existing image.
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.image_member_client.add_member,
-                          self.alt_tenant_id, non_exist_image)
+                          self.image_member_client.create_image_member,
+                          non_exist_image, self.alt_tenant_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('e1559f05-b667-4f1b-a7af-518b52dc0c0f')
@@ -35,8 +35,8 @@
         # Delete member with non existing image.
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.image_member_client.delete_member,
-                          self.alt_tenant_id, non_exist_image)
+                          self.image_member_client.delete_image_member,
+                          non_exist_image, self.alt_tenant_id)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('f5720333-dd69-4194-bb76-d2f048addd56')
@@ -45,8 +45,8 @@
         image_id = self._create_image()
         non_exist_tenant = data_utils.rand_uuid_hex()
         self.assertRaises(lib_exc.NotFound,
-                          self.image_member_client.delete_member,
-                          non_exist_tenant, image_id)
+                          self.image_member_client.delete_image_member,
+                          image_id, non_exist_tenant)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('f25f89e4-0b6c-453b-a853-1f80b9d7ef26')
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 6d5559d..59ac646 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -16,6 +16,7 @@
 from six import moves
 
 from tempest.api.image import base
+from tempest.common import image as common_image
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
@@ -306,7 +307,8 @@
     @test.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
-        resp_metadata = self.client.check_image(self.image_id)
+        resp = self.client.check_image(self.image_id)
+        resp_metadata = common_image.get_image_meta_from_headers(resp)
         expected = {'key1': 'value1'}
         self.assertEqual(expected, resp_metadata['properties'])
 
@@ -314,12 +316,14 @@
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'key1': 'alt1', 'key2': 'value2'}
-        metadata = self.client.check_image(self.image_id)
+        resp = self.client.check_image(self.image_id)
+        metadata = common_image.get_image_meta_from_headers(resp)
         self.assertEqual(metadata['properties'], {'key1': 'value1'})
         metadata['properties'].update(req_metadata)
         metadata = self.client.update_image(
             self.image_id, properties=metadata['properties'])['image']
 
-        resp_metadata = self.client.check_image(self.image_id)
+        resp = self.client.check_image(self.image_id)
+        resp_metadata = common_image.get_image_meta_from_headers(resp)
         expected = {'key1': 'alt1', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata['properties'])
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index db323de..f9d7a9b 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -157,7 +157,8 @@
         spec.append([CONF.object_storage.operator_role])
         spec.append([CONF.object_storage.reseller_admin_role])
     if CONF.service_available.heat:
-        spec.append([CONF.orchestration.stack_owner_role])
+        spec.append([CONF.orchestration.stack_owner_role,
+                     CONF.object_storage.operator_role])
     if admin:
         spec.append('admin')
     resources = []
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 5cce0bb..bf6c537 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -16,8 +16,8 @@
 
 import six
 
-from tempest import exceptions
 from tempest.lib import auth
+from tempest.lib import exceptions
 
 
 @six.add_metaclass(abc.ABCMeta)
diff --git a/tempest/common/image.py b/tempest/common/image.py
new file mode 100644
index 0000000..42ce5ac
--- /dev/null
+++ b/tempest/common/image.py
@@ -0,0 +1,38 @@
+# Copyright 2016 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.
+
+
+def get_image_meta_from_headers(resp):
+    meta = {'properties': {}}
+    for key in resp.response:
+        value = resp.response[key]
+        if key.startswith('x-image-meta-property-'):
+            _key = key[22:]
+            meta['properties'][_key] = value
+        elif key.startswith('x-image-meta-'):
+            _key = key[13:]
+            meta[_key] = value
+
+    for key in ['is_public', 'protected', 'deleted']:
+        if key in meta:
+            meta[key] = meta[key].strip().lower() in ('t', 'true', 'yes', '1')
+
+    for key in ['size', 'min_ram', 'min_disk']:
+        if key in meta:
+            try:
+                meta[key] = int(meta[key])
+            except ValueError:
+                pass
+    return meta
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
index c3c9a41..a55ee32 100644
--- a/tempest/common/validation_resources.py
+++ b/tempest/common/validation_resources.py
@@ -22,6 +22,26 @@
 LOG = logging.getLogger(__name__)
 
 
+def _create_neutron_sec_group_rules(os, sec_group):
+    sec_group_rules_client = os.security_group_rules_client
+    ethertype = 'IPv4'
+    if CONF.validation.ip_version_for_ssh == 6:
+        ethertype = 'IPv6'
+
+    sec_group_rules_client.create_security_group_rule(
+        security_group_id=sec_group['id'],
+        protocol='tcp',
+        ethertype=ethertype,
+        port_range_min=22,
+        port_range_max=22,
+        direction='ingress')
+    sec_group_rules_client.create_security_group_rule(
+        security_group_id=sec_group['id'],
+        protocol='icmp',
+        ethertype=ethertype,
+        direction='ingress')
+
+
 def create_ssh_security_group(os, add_rule=False):
     security_groups_client = os.compute_security_groups_client
     security_group_rules_client = os.compute_security_group_rules_client
@@ -30,12 +50,15 @@
     security_group = security_groups_client.create_security_group(
         name=sg_name, description=sg_description)['security_group']
     if add_rule:
-        security_group_rules_client.create_security_group_rule(
-            parent_group_id=security_group['id'], ip_protocol='tcp',
-            from_port=22, to_port=22)
-        security_group_rules_client.create_security_group_rule(
-            parent_group_id=security_group['id'], ip_protocol='icmp',
-            from_port=-1, to_port=-1)
+        if CONF.service_available.neutron:
+            _create_neutron_sec_group_rules(os, security_group)
+        else:
+            security_group_rules_client.create_security_group_rule(
+                parent_group_id=security_group['id'], ip_protocol='tcp',
+                from_port=22, to_port=22)
+            security_group_rules_client.create_security_group_rule(
+                parent_group_id=security_group['id'], ip_protocol='icmp',
+                from_port=-1, to_port=-1)
     LOG.debug("SSH Validation resource security group with tcp and icmp "
               "rules %s created"
               % sg_name)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 23d7f88..d8dad69 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -15,6 +15,7 @@
 
 from oslo_log import log as logging
 
+from tempest.common import image as common_image
 from tempest import config
 from tempest import exceptions
 from tempest.lib.common.utils import misc as misc_utils
@@ -127,7 +128,11 @@
         # The 'check_image' method is used here because the show_image method
         # returns image details plus the image itself which is very expensive.
         # The 'check_image' method returns just image details.
-        show_image = client.check_image
+        def _show_image_v1(image_id):
+            resp = client.check_image(image_id)
+            return common_image.get_image_meta_from_headers(resp)
+
+        show_image = _show_image_v1
     else:
         show_image = client.show_image
 
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 92f335f..f534f30 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -13,157 +13,65 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
+
+from tempest.lib import exceptions
 
 
-class TempestException(Exception):
-    """Base Tempest Exception
-
-    To correctly use this class, inherit from it and define
-    a 'message' property. That message will get printf'd
-    with the keyword arguments provided to the constructor.
-    """
-    message = "An unknown exception occurred"
-
-    def __init__(self, *args, **kwargs):
-        super(TempestException, self).__init__()
-        try:
-            self._error_string = self.message % kwargs
-        except Exception:
-            # at least get the core message out if something happened
-            self._error_string = self.message
-        if len(args) > 0:
-            # If there is a non-kwarg parameter, assume it's the error
-            # message or reason description and tack it on to the end
-            # of the exception message
-            # Convert all arguments into their string representations...
-            args = ["%s" % arg for arg in args]
-            self._error_string = (self._error_string +
-                                  "\nDetails: %s" % '\n'.join(args))
-
-    def __str__(self):
-        return self._error_string
-
-
-class RestClientException(TempestException,
-                          testtools.TestCase.failureException):
-    pass
-
-
-class InvalidConfiguration(TempestException):
+class InvalidConfiguration(exceptions.TempestException):
     message = "Invalid Configuration"
 
 
-class InvalidCredentials(TempestException):
-    message = "Invalid Credentials"
-
-
-class InvalidServiceTag(TempestException):
+class InvalidServiceTag(exceptions.TempestException):
     message = "Invalid service tag"
 
 
-class InvalidIdentityVersion(TempestException):
-    message = "Invalid version %(identity_version)s of the identity service"
-
-
-class TimeoutException(TempestException):
+class TimeoutException(exceptions.TempestException):
     message = "Request timed out"
 
 
-class BuildErrorException(TempestException):
+class BuildErrorException(exceptions.TempestException):
     message = "Server %(server_id)s failed to build and is in ERROR status"
 
 
-class ImageKilledException(TempestException):
+class ImageKilledException(exceptions.TempestException):
     message = "Image %(image_id)s 'killed' while waiting for '%(status)s'"
 
 
-class AddImageException(TempestException):
+class AddImageException(exceptions.TempestException):
     message = "Image %(image_id)s failed to become ACTIVE in the allotted time"
 
 
-class VolumeBuildErrorException(TempestException):
+class VolumeBuildErrorException(exceptions.TempestException):
     message = "Volume %(volume_id)s failed to build and is in ERROR status"
 
 
-class VolumeRestoreErrorException(TempestException):
+class VolumeRestoreErrorException(exceptions.TempestException):
     message = "Volume %(volume_id)s failed to restore and is in ERROR status"
 
 
-class SnapshotBuildErrorException(TempestException):
+class SnapshotBuildErrorException(exceptions.TempestException):
     message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"
 
 
-class VolumeBackupException(TempestException):
+class VolumeBackupException(exceptions.TempestException):
     message = "Volume backup %(backup_id)s failed and is in ERROR status"
 
 
-class StackBuildErrorException(TempestException):
+class StackBuildErrorException(exceptions.TempestException):
     message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
                "due to '%(stack_status_reason)s'")
 
 
-class EndpointNotFound(TempestException):
-    message = "Endpoint not found"
-
-
-class IdentityError(TempestException):
-    message = "Got identity error"
-
-
-class ServerUnreachable(TempestException):
+class ServerUnreachable(exceptions.TempestException):
     message = "The server is not reachable via the configured network"
 
 
 # NOTE(andreaf) This exception is added here to facilitate the migration
 # of get_network_from_name and preprov_creds to tempest.lib, and it should
 # be migrated along with them
-class InvalidTestResource(TempestException):
+class InvalidTestResource(exceptions.TempestException):
     message = "%(name) is not a valid %(type), or the name is ambiguous"
 
 
-class RFCViolation(RestClientException):
+class RFCViolation(exceptions.RestClientException):
     message = "RFC Violation"
-
-
-class InvalidHttpSuccessCode(RestClientException):
-    message = "The success code is different than the expected one"
-
-
-class BadRequest(RestClientException):
-    message = "Bad request"
-
-
-class ResponseWithNonEmptyBody(RFCViolation):
-    message = ("RFC Violation! Response with %(status)d HTTP Status Code "
-               "MUST NOT have a body")
-
-
-class ResponseWithEntity(RFCViolation):
-    message = ("RFC Violation! Response with 205 HTTP Status Code "
-               "MUST NOT have an entity")
-
-
-class InvalidHTTPResponseHeader(RestClientException):
-    message = "HTTP response header is invalid"
-
-
-class InvalidStructure(TempestException):
-    message = "Invalid structure of table with details"
-
-
-class CommandFailed(Exception):
-    def __init__(self, returncode, cmd, output, stderr):
-        super(CommandFailed, self).__init__()
-        self.returncode = returncode
-        self.cmd = cmd
-        self.stdout = output
-        self.stderr = stderr
-
-    def __str__(self):
-        return ("Command '%s' returned non-zero exit status %d.\n"
-                "stdout:\n%s\n"
-                "stderr:\n%s" % (self.cmd,
-                                 self.returncode,
-                                 self.stdout,
-                                 self.stderr))
diff --git a/tempest/lib/exceptions.py b/tempest/lib/exceptions.py
index 259bbbb..2a6a788 100644
--- a/tempest/lib/exceptions.py
+++ b/tempest/lib/exceptions.py
@@ -149,6 +149,10 @@
     message = "Unexpected response code received"
 
 
+class InvalidIdentityVersion(TempestException):
+    message = "Invalid version %(identity_version)s of the identity service"
+
+
 class InvalidStructure(TempestException):
     message = "Invalid structure of table with details"
 
diff --git a/tempest/manager.py b/tempest/manager.py
index 72762ab..f2659a8 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 from tempest import config
-from tempest import exceptions
 from tempest.lib import auth
+from tempest.lib import exceptions
 
 CONF = config.CONF
 
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 6994b9c..dd6e0e5 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -23,6 +23,7 @@
 import six
 
 from tempest.common import compute
+from tempest.common import image as common_image
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
 from tempest.common import waiters
@@ -30,7 +31,6 @@
 from tempest import exceptions
 from tempest.lib.common.utils import test_utils
 from tempest.lib import exceptions as lib_exc
-from tempest.scenario import network_resources
 import tempest.test
 
 CONF = config.CONF
@@ -224,7 +224,7 @@
                 port = self._create_port(network_id=net_id,
                                          client=clients.ports_client,
                                          **create_port_body)
-                ports.append({'port': port.id})
+                ports.append({'port': port['id']})
             if ports:
                 kwargs['networks'] = ports
             self.ports = ports
@@ -469,7 +469,8 @@
             cleanup_args=[_image_client.delete_image, image_id])
         if CONF.image_feature_enabled.api_v1:
             # In glance v1 the additional properties are stored in the headers.
-            snapshot_image = _image_client.check_image(image_id)
+            resp = _image_client.check_image(image_id)
+            snapshot_image = common_image.get_image_meta_from_headers(resp)
             image_props = snapshot_image.get('properties', {})
         else:
             # In glance v2 the additional properties are flattened.
@@ -705,12 +706,12 @@
             tenant_id = networks_client.tenant_id
         name = data_utils.rand_name(namestart)
         result = networks_client.create_network(name=name, tenant_id=tenant_id)
-        network = network_resources.DeletableNetwork(
-            networks_client=networks_client, routers_client=routers_client,
-            **result['network'])
-        self.assertEqual(network.name, name)
+        network = result['network']
+
+        self.assertEqual(network['name'], name)
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
-                        network.delete)
+                        self.networks_client.delete_network,
+                        network['id'])
         return network
 
     def _list_networks(self, *args, **kwargs):
@@ -780,13 +781,13 @@
         # blocks until an unallocated block is found.
         for subnet_cidr in tenant_cidr.subnet(num_bits):
             str_cidr = str(subnet_cidr)
-            if cidr_in_use(str_cidr, tenant_id=network.tenant_id):
+            if cidr_in_use(str_cidr, tenant_id=network['tenant_id']):
                 continue
 
             subnet = dict(
                 name=data_utils.rand_name(namestart),
-                network_id=network.id,
-                tenant_id=network.tenant_id,
+                network_id=network['id'],
+                tenant_id=network['tenant_id'],
                 cidr=str_cidr,
                 ip_version=ip_version,
                 **kwargs
@@ -799,11 +800,13 @@
                 if not is_overlapping_cidr:
                     raise
         self.assertIsNotNone(result, 'Unable to allocate tenant network')
-        subnet = network_resources.DeletableSubnet(
-            subnets_client=subnets_client,
-            routers_client=routers_client, **result['subnet'])
-        self.assertEqual(subnet.cidr, str_cidr)
-        self.addCleanup(test_utils.call_and_ignore_notfound_exc, subnet.delete)
+
+        subnet = result['subnet']
+        self.assertEqual(subnet['cidr'], str_cidr)
+
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        subnets_client.delete_subnet, subnet['id'])
+
         return subnet
 
     def _create_port(self, network_id, client=None, namestart='port-quotatest',
@@ -816,9 +819,9 @@
             network_id=network_id,
             **kwargs)
         self.assertIsNotNone(result, 'Unable to allocate port')
-        port = network_resources.DeletablePort(ports_client=client,
-                                               **result['port'])
-        self.addCleanup(test_utils.call_and_ignore_notfound_exc, port.delete)
+        port = result['port']
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        client.delete_port, port['id'])
         return port
 
     def _get_server_port_id_and_ip4(self, server, ip_addr=None):
@@ -853,7 +856,7 @@
         net = self._list_networks(name=network_name)
         self.assertNotEqual(len(net), 0,
                             "Unable to get network by name: %s" % network_name)
-        return network_resources.AttributeDict(net[0])
+        return net[0]
 
     def create_floating_ip(self, thing, external_network_id=None,
                            port_id=None, client=None):
@@ -872,44 +875,51 @@
             tenant_id=thing['tenant_id'],
             fixed_ip_address=ip4
         )
-        floating_ip = network_resources.DeletableFloatingIp(
-            client=client,
-            **result['floatingip'])
+        floating_ip = result['floatingip']
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
-                        floating_ip.delete)
+                        self.floating_ips_client.delete_floatingip,
+                        floating_ip['id'])
         return floating_ip
 
     def _associate_floating_ip(self, floating_ip, server):
         port_id, _ = self._get_server_port_id_and_ip4(server)
-        floating_ip.update(port_id=port_id)
-        self.assertEqual(port_id, floating_ip.port_id)
+        kwargs = dict(port_id=port_id)
+        floating_ip = self.floating_ips_client.update_floatingip(
+            floating_ip['id'], **kwargs)['floatingip']
+        self.assertEqual(port_id, floating_ip['port_id'])
         return floating_ip
 
     def _disassociate_floating_ip(self, floating_ip):
-        """:param floating_ip: type DeletableFloatingIp"""
-        floating_ip.update(port_id=None)
-        self.assertIsNone(floating_ip.port_id)
+        """:param floating_ip: floating_ips_client.create_floatingip"""
+        kwargs = dict(port_id=None)
+        floating_ip = self.floating_ips_client.update_floatingip(
+            floating_ip['id'], **kwargs)['floatingip']
+        self.assertIsNone(floating_ip['port_id'])
         return floating_ip
 
     def check_floating_ip_status(self, floating_ip, status):
         """Verifies floatingip reaches the given status
 
-        :param floating_ip: network_resources.DeletableFloatingIp floating
-        IP to check status
+        :param dict floating_ip: floating IP dict to check status
         :param status: target status
         :raises: AssertionError if status doesn't match
         """
+        floatingip_id = floating_ip['id']
+
         def refresh():
-            floating_ip.refresh()
-            return status == floating_ip.status
+            result = (self.floating_ips_client.
+                      show_floatingip(floatingip_id)['floatingip'])
+            return status == result['status']
 
         tempest.test.call_until_true(refresh,
                                      CONF.network.build_timeout,
                                      CONF.network.build_interval)
-        self.assertEqual(status, floating_ip.status,
+        floating_ip = self.floating_ips_client.show_floatingip(
+            floatingip_id)['floatingip']
+        self.assertEqual(status, floating_ip['status'],
                          message="FloatingIP: {fp} is at status: {cst}. "
                                  "failed  to reach status: {st}"
-                         .format(fp=floating_ip, cst=floating_ip.status,
+                         .format(fp=floating_ip, cst=floating_ip['status'],
                                  st=status))
         LOG.info("FloatingIP: {fp} is at status: {st}"
                  .format(fp=floating_ip, st=status))
@@ -982,8 +992,8 @@
             secgroup=secgroup,
             security_groups_client=security_groups_client)
         for rule in rules:
-            self.assertEqual(tenant_id, rule.tenant_id)
-            self.assertEqual(secgroup.id, rule.security_group_id)
+            self.assertEqual(tenant_id, rule['tenant_id'])
+            self.assertEqual(secgroup['id'], rule['security_group_id'])
         return secgroup
 
     def _create_empty_security_group(self, client=None, tenant_id=None,
@@ -995,7 +1005,7 @@
          - IPv6 egress to any
 
         :param tenant_id: secgroup will be created in this tenant
-        :returns: DeletableSecurityGroup -- containing the secgroup created
+        :returns: the created security group
         """
         if client is None:
             client = self.security_groups_client
@@ -1007,15 +1017,14 @@
                        description=sg_desc)
         sg_dict['tenant_id'] = tenant_id
         result = client.create_security_group(**sg_dict)
-        secgroup = network_resources.DeletableSecurityGroup(
-            client=client, routers_client=self.routers_client,
-            **result['security_group']
-        )
-        self.assertEqual(secgroup.name, sg_name)
-        self.assertEqual(tenant_id, secgroup.tenant_id)
-        self.assertEqual(secgroup.description, sg_desc)
+
+        secgroup = result['security_group']
+        self.assertEqual(secgroup['name'], sg_name)
+        self.assertEqual(tenant_id, secgroup['tenant_id'])
+        self.assertEqual(secgroup['description'], sg_desc)
+
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
-                        secgroup.delete)
+                        client.delete_security_group, secgroup['id'])
         return secgroup
 
     def _default_security_group(self, client=None, tenant_id=None):
@@ -1033,8 +1042,7 @@
         ]
         msg = "No default security group for tenant %s." % (tenant_id)
         self.assertTrue(len(sgs) > 0, msg)
-        return network_resources.DeletableSecurityGroup(client=client,
-                                                        **sgs[0])
+        return sgs[0]
 
     def _create_security_group_rule(self, secgroup=None,
                                     sec_group_rules_client=None,
@@ -1045,7 +1053,7 @@
         Create a rule in a secgroup. if secgroup not defined will search for
         default secgroup in tenant_id.
 
-        :param secgroup: type DeletableSecurityGroup.
+        :param secgroup: the security group.
         :param tenant_id: if secgroup not passed -- the tenant in which to
             search for default secgroup
         :param kwargs: a dictionary containing rule parameters:
@@ -1067,17 +1075,15 @@
             secgroup = self._default_security_group(
                 client=security_groups_client, tenant_id=tenant_id)
 
-        ruleset = dict(security_group_id=secgroup.id,
-                       tenant_id=secgroup.tenant_id)
+        ruleset = dict(security_group_id=secgroup['id'],
+                       tenant_id=secgroup['tenant_id'])
         ruleset.update(kwargs)
 
         sg_rule = sec_group_rules_client.create_security_group_rule(**ruleset)
-        sg_rule = network_resources.DeletableSecurityGroupRule(
-            client=sec_group_rules_client,
-            **sg_rule['security_group_rule']
-        )
-        self.assertEqual(secgroup.tenant_id, sg_rule.tenant_id)
-        self.assertEqual(secgroup.id, sg_rule.security_group_id)
+        sg_rule = sg_rule['security_group_rule']
+
+        self.assertEqual(secgroup['tenant_id'], sg_rule['tenant_id'])
+        self.assertEqual(secgroup['id'], sg_rule['security_group_id'])
 
         return sg_rule
 
@@ -1131,7 +1137,7 @@
                     if msg not in ex._error_string:
                         raise ex
                 else:
-                    self.assertEqual(r_direction, sg_rule.direction)
+                    self.assertEqual(r_direction, sg_rule['direction'])
                     rules.append(sg_rule)
 
         return rules
@@ -1153,10 +1159,11 @@
         network_id = CONF.network.public_network_id
         if router_id:
             body = client.show_router(router_id)
-            return network_resources.AttributeDict(**body['router'])
+            return body['router']
         elif network_id:
             router = self._create_router(client, tenant_id)
-            router.set_gateway(network_id)
+            kwargs = {'external_gateway_info': dict(network_id=network_id)}
+            router = client.update_router(router['id'], **kwargs)['router']
             return router
         else:
             raise Exception("Neither of 'public_router_id' or "
@@ -1172,15 +1179,18 @@
         result = client.create_router(name=name,
                                       admin_state_up=True,
                                       tenant_id=tenant_id)
-        router = network_resources.DeletableRouter(routers_client=client,
-                                                   **result['router'])
-        self.assertEqual(router.name, name)
-        self.addCleanup(test_utils.call_and_ignore_notfound_exc, router.delete)
+        router = result['router']
+        self.assertEqual(router['name'], name)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        client.delete_router,
+                        router['id'])
         return router
 
     def _update_router_admin_state(self, router, admin_state_up):
-        router.update(admin_state_up=admin_state_up)
-        self.assertEqual(admin_state_up, router.admin_state_up)
+        kwargs = dict(admin_state_up=admin_state_up)
+        router = self.routers_client.update_router(
+            router['id'], **kwargs)['router']
+        self.assertEqual(admin_state_up, router['admin_state_up'])
 
     def create_networks(self, networks_client=None,
                         routers_client=None, subnets_client=None,
@@ -1213,7 +1223,6 @@
                 tenant_id=tenant_id)
             router = self._get_router(client=routers_client,
                                       tenant_id=tenant_id)
-
             subnet_kwargs = dict(network=network,
                                  subnets_client=subnets_client,
                                  routers_client=routers_client)
@@ -1221,7 +1230,17 @@
             if dns_nameservers is not None:
                 subnet_kwargs['dns_nameservers'] = dns_nameservers
             subnet = self._create_subnet(**subnet_kwargs)
-            subnet.add_to_router(router.id)
+            if not routers_client:
+                routers_client = self.routers_client
+            router_id = router['id']
+            routers_client.add_router_interface(router_id,
+                                                subnet_id=subnet['id'])
+
+            # save a cleanup job to remove this association between
+            # router and subnet
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            routers_client.remove_router_interface, router_id,
+                            subnet_id=subnet['id'])
         return network, subnet, router
 
 
diff --git a/tempest/scenario/network_resources.py b/tempest/scenario/network_resources.py
deleted file mode 100644
index 667476f..0000000
--- a/tempest/scenario/network_resources.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-# 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.
-
-import abc
-import time
-
-import six
-
-from tempest import exceptions
-from tempest.lib.common.utils import misc
-
-
-class AttributeDict(dict):
-    """Provide attribute access (dict.key) to dictionary values."""
-
-    def __getattr__(self, name):
-        """Allow attribute access for all keys in the dict."""
-        if name in self:
-            return self[name]
-        return super(AttributeDict, self).__getattribute__(name)
-
-
-@six.add_metaclass(abc.ABCMeta)
-class DeletableResource(AttributeDict):
-    """Support deletion of neutron resources (networks, subnets)
-
-    via a delete() method, as is supported by keystone and nova resources.
-    """
-
-    def __init__(self, *args, **kwargs):
-        self.client = kwargs.pop('client', None)
-        self.networks_client = kwargs.pop('networks_client', None)
-        self.routers_client = kwargs.pop('routers_client', None)
-        self.subnets_client = kwargs.pop('subnets_client', None)
-        self.ports_client = kwargs.pop('ports_client', None)
-        super(DeletableResource, self).__init__(*args, **kwargs)
-
-    def __str__(self):
-        return '<%s id="%s" name="%s">' % (self.__class__.__name__,
-                                           self.id, self.name)
-
-    @abc.abstractmethod
-    def delete(self):
-        return
-
-    @abc.abstractmethod
-    def refresh(self):
-        return
-
-    def __hash__(self):
-        return hash(self.id)
-
-    def wait_for_status(self, status):
-        if not hasattr(self, 'status'):
-            return
-
-        def helper_get():
-            self.refresh()
-            return self
-
-        return self.wait_for_resource_status(helper_get, status)
-
-    def wait_for_resource_status(self, fetch, status):
-        """Waits for a network resource to reach a status
-
-        @param fetch: the callable to be used to query the resource status
-        @type fetch: callable that takes no parameters and returns the resource
-        @param status: the status that the resource has to reach
-        @type status: String
-        """
-        interval = self.build_interval
-        timeout = self.build_timeout
-        start_time = time.time()
-
-        while time.time() - start_time <= timeout:
-            resource = fetch()
-            if resource['status'] == status:
-                return
-            time.sleep(interval)
-
-        # At this point, the wait has timed out
-        message = 'Resource %s' % (str(resource))
-        message += ' failed to reach status %s' % status
-        message += ' (current: %s)' % resource['status']
-        message += ' within the required time %s' % timeout
-        caller = misc.find_test_caller()
-        if caller:
-            message = '(%s) %s' % (caller, message)
-        raise exceptions.TimeoutException(message)
-
-
-class DeletableNetwork(DeletableResource):
-
-    def delete(self):
-        self.networks_client.delete_network(self.id)
-
-
-class DeletableSubnet(DeletableResource):
-
-    def __init__(self, *args, **kwargs):
-        super(DeletableSubnet, self).__init__(*args, **kwargs)
-        self._router_ids = set()
-
-    def update(self, *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.routers_client.add_router_interface(router_id,
-                                                 subnet_id=self.id)
-
-    def delete(self):
-        for router_id in self._router_ids.copy():
-            self.routers_client.remove_router_interface(router_id,
-                                                        subnet_id=self.id)
-            self._router_ids.remove(router_id)
-        self.subnets_client.delete_subnet(self.id)
-
-
-class DeletableRouter(DeletableResource):
-
-    def set_gateway(self, network_id):
-        return self.update(external_gateway_info=dict(network_id=network_id))
-
-    def unset_gateway(self):
-        return self.update(external_gateway_info=dict())
-
-    def update(self, *args, **kwargs):
-        result = self.routers_client.update_router(self.id,
-                                                   *args,
-                                                   **kwargs)
-        return super(DeletableRouter, self).update(**result['router'])
-
-    def delete(self):
-        self.unset_gateway()
-        self.routers_client.delete_router(self.id)
-
-
-class DeletableFloatingIp(DeletableResource):
-
-    def refresh(self, *args, **kwargs):
-        result = self.client.show_floatingip(self.id,
-                                             *args,
-                                             **kwargs)
-        super(DeletableFloatingIp, self).update(**result['floatingip'])
-
-    def update(self, *args, **kwargs):
-        result = self.client.update_floatingip(self.id,
-                                               *args,
-                                               **kwargs)
-        super(DeletableFloatingIp, self).update(**result['floatingip'])
-
-    def __repr__(self):
-        return '<%s addr="%s">' % (self.__class__.__name__,
-                                   self.floating_ip_address)
-
-    def __str__(self):
-        return '<"FloatingIP" addr="%s" id="%s">' % (self.floating_ip_address,
-                                                     self.id)
-
-    def delete(self):
-        self.client.delete_floatingip(self.id)
-
-
-class DeletablePort(DeletableResource):
-
-    def delete(self):
-        self.ports_client.delete_port(self.id)
-
-
-class DeletableSecurityGroup(DeletableResource):
-
-    def delete(self):
-        self.client.delete_security_group(self.id)
-
-
-class DeletableSecurityGroupRule(DeletableResource):
-
-    def __repr__(self):
-        return '<%s id="%s">' % (self.__class__.__name__, self.id)
-
-    def delete(self):
-        self.client.delete_security_group_rule(self.id)
-
-
-class DeletablePool(DeletableResource):
-
-    def delete(self):
-        self.client.delete_pool(self.id)
-
-
-class DeletableMember(DeletableResource):
-
-    def delete(self):
-        self.client.delete_member(self.id)
-
-
-class DeletableVip(DeletableResource):
-
-    def delete(self):
-        self.client.delete_vip(self.id)
-
-    def refresh(self):
-        result = self.client.show_vip(self.id)
-        super(DeletableVip, self).update(**result['vip'])
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index bfdb0c2..e4b699e 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -61,7 +61,7 @@
         server_name = data_utils.rand_name('server-smoke')
         server = self.create_server(
             name=server_name,
-            networks=[{'uuid': network.id}],
+            networks=[{'uuid': network['id']}],
             key_name=keypair['name'],
             security_groups=security_groups,
             wait_until='ACTIVE')
@@ -81,7 +81,7 @@
             server, username, private_key,
             should_connect=should_connect,
             servers_for_debug=[server])
-        floating_ip_addr = floating_ip.floating_ip_address
+        floating_ip_addr = floating_ip['floating_ip_address']
         # Check FloatingIP status before checking the connectivity
         self.check_floating_ip_status(floating_ip, 'ACTIVE')
         self.check_public_network_connectivity(floating_ip_addr, username,
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index f5134e5..402a70c 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -25,7 +25,6 @@
 from tempest import exceptions
 from tempest.lib.common.utils import test_utils
 from tempest.scenario import manager
-from tempest.scenario import network_resources
 from tempest import test
 
 CONF = config.CONF
@@ -114,7 +113,7 @@
         self.port_id = None
         if boot_with_port:
             # create a port on the network and boot with that
-            self.port_id = self._create_port(self.network['id']).id
+            self.port_id = self._create_port(self.network['id'])['id']
             self.ports.append({'port': self.port_id})
 
         name = data_utils.rand_name('server-smoke')
@@ -133,30 +132,30 @@
         seen_nets = self._list_networks()
         seen_names = [n['name'] for n in seen_nets]
         seen_ids = [n['id'] for n in seen_nets]
-        self.assertIn(self.network.name, seen_names)
-        self.assertIn(self.network.id, seen_ids)
+        self.assertIn(self.network['name'], seen_names)
+        self.assertIn(self.network['id'], seen_ids)
 
         if self.subnet:
             seen_subnets = self._list_subnets()
             seen_net_ids = [n['network_id'] for n in seen_subnets]
             seen_subnet_ids = [n['id'] for n in seen_subnets]
-            self.assertIn(self.network.id, seen_net_ids)
-            self.assertIn(self.subnet.id, seen_subnet_ids)
+            self.assertIn(self.network['id'], seen_net_ids)
+            self.assertIn(self.subnet['id'], seen_subnet_ids)
 
         if self.router:
             seen_routers = self._list_routers()
             seen_router_ids = [n['id'] for n in seen_routers]
             seen_router_names = [n['name'] for n in seen_routers]
-            self.assertIn(self.router.name,
+            self.assertIn(self.router['name'],
                           seen_router_names)
-            self.assertIn(self.router.id,
+            self.assertIn(self.router['id'],
                           seen_router_ids)
 
     def _create_server(self, name, network, port_id=None):
         keypair = self.create_keypair()
         self.keypairs[keypair['name']] = keypair
         security_groups = [{'name': self.security_group['name']}]
-        network = {'uuid': network.id}
+        network = {'uuid': network['id']}
         if port_id is not None:
             network['port'] = port_id
 
@@ -198,7 +197,7 @@
         """
         ssh_login = CONF.validation.image_ssh_user
         floating_ip, server = self.floating_ip_tuple
-        ip_address = floating_ip.floating_ip_address
+        ip_address = floating_ip['floating_ip_address']
         private_key = None
         floatingip_status = 'DOWN'
         if should_connect:
@@ -239,7 +238,7 @@
 
     def _hotplug_server(self):
         old_floating_ip, server = self.floating_ip_tuple
-        ip_address = old_floating_ip.floating_ip_address
+        ip_address = old_floating_ip['floating_ip_address']
         private_key = self._get_server_key(server)
         ssh_client = self.get_remote_client(
             ip_address, private_key=private_key)
@@ -250,7 +249,7 @@
         old_port = port_list[0]
         interface = self.interface_client.create_interface(
             server_id=server['id'],
-            net_id=self.new_net.id)['interfaceAttachment']
+            net_id=self.new_net['id'])['interfaceAttachment']
         self.addCleanup(self.ports_client.wait_for_resource_deletion,
                         interface['port_id'])
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
@@ -270,9 +269,7 @@
                 "Old port: %s. Number of new ports: %d" % (
                     CONF.network.build_timeout, old_port,
                     len(self.new_port_list)))
-        new_port = network_resources.DeletablePort(
-            ports_client=self.ports_client,
-            **self.new_port_list[0])
+        new_port = self.new_port_list[0]
 
         def check_new_nic():
             new_nic_list = self._get_server_nics(ssh_client)
@@ -287,7 +284,8 @@
 
         num, new_nic = self.diff_list[0]
         ssh_client.assign_static_ip(nic=new_nic,
-                                    addr=new_port.fixed_ips[0]['ip_address'])
+                                    addr=new_port['fixed_ips'][0][
+                                        'ip_address'])
         ssh_client.set_nic_state(nic=new_nic)
 
     def _get_server_nics(self, ssh_client):
@@ -307,7 +305,7 @@
         # get all network ports in the new network
         internal_ips = (p['fixed_ips'][0]['ip_address'] for p in
                         self._list_ports(tenant_id=server['tenant_id'],
-                                         network_id=network.id)
+                                         network_id=network['id'])
                         if p['device_owner'].startswith('network'))
 
         self._check_server_connectivity(floating_ip,
@@ -335,7 +333,7 @@
 
     def _check_server_connectivity(self, floating_ip, address_list,
                                    should_connect=True):
-        ip_address = floating_ip.floating_ip_address
+        ip_address = floating_ip['floating_ip_address']
         private_key = self._get_server_key(self.floating_ip_tuple.server)
         ssh_source = self.get_remote_client(
             ip_address, private_key=private_key)
@@ -451,7 +449,13 @@
         self._create_server(name, self.new_net)
         self._check_network_internal_connectivity(network=self.new_net,
                                                   should_connect=False)
-        self.new_subnet.add_to_router(self.router.id)
+        router_id = self.router['id']
+        self.routers_client.add_router_interface(
+            router_id, subnet_id=self.new_subnet['id'])
+
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.routers_client.remove_router_interface,
+                        router_id, subnet_id=self.new_subnet['id'])
         self._check_network_internal_connectivity(network=self.new_net,
                                                   should_connect=True)
 
@@ -553,7 +557,7 @@
         self.check_public_network_connectivity(should_connect=True)
 
         floating_ip, server = self.floating_ip_tuple
-        ip_address = floating_ip.floating_ip_address
+        ip_address = floating_ip['floating_ip_address']
         private_key = self._get_server_key(server)
         ssh_client = self.get_remote_client(
             ip_address, private_key=private_key)
@@ -568,9 +572,11 @@
                                  act_serv=servers,
                                  trgt_serv=dns_servers))
 
-        self.subnet.update(dns_nameservers=[alt_dns_server])
+        self.subnet = self.subnets_client.update_subnet(
+            self.subnet['id'], dns_nameservers=[alt_dns_server])['subnet']
+
         # asserts that Neutron DB has updated the nameservers
-        self.assertEqual([alt_dns_server], self.subnet.dns_nameservers,
+        self.assertEqual([alt_dns_server], self.subnet['dns_nameservers'],
                          "Failed to update subnet's nameservers")
 
         def check_new_dns_server():
@@ -695,7 +701,8 @@
 
         # NOTE(kevinbenton): we have to use the admin credentials to check
         # for the distributed flag because self.router only has a project view.
-        admin = self.admin_manager.routers_client.show_router(self.router.id)
+        admin = self.admin_manager.routers_client.show_router(
+            self.router['id'])
         if admin['router'].get('distributed', False):
             msg = "Rescheduling test does not apply to distributed routers."
             raise self.skipException(msg)
@@ -704,16 +711,16 @@
 
         # remove resource from agents
         hosting_agents = set(a["id"] for a in
-                             list_hosts(self.router.id)['agents'])
+                             list_hosts(self.router['id'])['agents'])
         no_migration = agent_list_alive == hosting_agents
         LOG.info("Router will be assigned to {mig} hosting agent".
                  format(mig="the same" if no_migration else "a new"))
 
         for hosting_agent in hosting_agents:
-            unschedule_router(hosting_agent, self.router.id)
+            unschedule_router(hosting_agent, self.router['id'])
             self.assertNotIn(hosting_agent,
                              [a["id"] for a in
-                              list_hosts(self.router.id)['agents']],
+                              list_hosts(self.router['id'])['agents']],
                              'unscheduling router failed')
 
         # verify resource is un-functional
@@ -730,7 +737,7 @@
                         router_id=self.router['id'])
         self.assertEqual(
             target_agent,
-            list_hosts(self.router.id)['agents'][0]['id'],
+            list_hosts(self.router['id'])['agents'][0]['id'],
             "Router failed to reschedule. Hosting agent doesn't match "
             "target agent")
 
@@ -776,12 +783,12 @@
                                      network_id=self.new_net["id"])
         spoof_port = new_ports[0]
         private_key = self._get_server_key(server)
-        ssh_client = self.get_remote_client(fip.floating_ip_address,
+        ssh_client = self.get_remote_client(fip['floating_ip_address'],
                                             private_key=private_key)
         spoof_nic = ssh_client.get_nic_name_by_mac(spoof_port["mac_address"])
         name = data_utils.rand_name('peer')
         peer = self._create_server(name, self.new_net)
-        peer_address = peer['addresses'][self.new_net.name][0]['addr']
+        peer_address = peer['addresses'][self.new_net['name']][0]['addr']
         self._check_remote_connectivity(ssh_client, dest=peer_address,
                                         nic=spoof_nic, should_succeed=True)
         ssh_client.set_mac_address(spoof_nic, spoof_mac)
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index a52d8f9..59ebb7a 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -17,6 +17,7 @@
 import six
 
 from tempest import config
+from tempest.lib.common.utils import test_utils
 from tempest.scenario import manager
 from tempest import test
 
@@ -82,8 +83,12 @@
                                    ip_version=4)
 
         router = self._get_router(tenant_id=self.tenant_id)
-        sub4.add_to_router(router_id=router['id'])
-        self.addCleanup(sub4.delete)
+        self.routers_client.add_router_interface(router['id'],
+                                                 subnet_id=sub4['id'])
+
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.routers_client.remove_router_interface,
+                        router['id'], subnet_id=sub4['id'])
 
         self.subnets_v6 = []
         for _ in range(n_subnets6):
@@ -94,10 +99,14 @@
                                        ipv6_ra_mode=address6_mode,
                                        ipv6_address_mode=address6_mode)
 
-            sub6.add_to_router(router_id=router['id'])
-            self.addCleanup(sub6.delete)
-            self.subnets_v6.append(sub6)
+            self.routers_client.add_router_interface(router['id'],
+                                                     subnet_id=sub6['id'])
 
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            self.routers_client.remove_router_interface,
+                            router['id'], subnet_id=sub6['id'])
+
+            self.subnets_v6.append(sub6)
         return [self.network, self.network_v6] if dualnet else [self.network]
 
     @staticmethod
@@ -119,12 +128,12 @@
         srv = self.create_server(
             key_name=self.keypair['name'],
             security_groups=[{'name': self.sec_grp['name']}],
-            networks=[{'uuid': n.id} for n in networks],
+            networks=[{'uuid': n['id']} for n in networks],
             wait_until='ACTIVE')
         fip = self.create_floating_ip(thing=srv)
         ips = self.define_server_ips(srv=srv)
         ssh = self.get_remote_client(
-            ip_address=fip.floating_ip_address,
+            ip_address=fip['floating_ip_address'],
             username=username)
         return ssh, ips, srv["id"]
 
@@ -139,7 +148,7 @@
         """
         ports = [p["mac_address"] for p in
                  self._list_ports(device_id=sid,
-                                  network_id=self.network_v6.id)]
+                                  network_id=self.network_v6['id'])]
         self.assertEqual(1, len(ports),
                          message=("Multiple IPv6 ports found on network %s. "
                                   "ports: %s")
@@ -190,11 +199,11 @@
             self._check_connectivity(sshv4_1,
                                      ips_from_api_2['6'][i])
             self._check_connectivity(sshv4_1,
-                                     self.subnets_v6[i].gateway_ip)
+                                     self.subnets_v6[i]['gateway_ip'])
             self._check_connectivity(sshv4_2,
                                      ips_from_api_1['6'][i])
             self._check_connectivity(sshv4_2,
-                                     self.subnets_v6[i].gateway_ip)
+                                     self.subnets_v6[i]['gateway_ip'])
 
     def _check_connectivity(self, source, dest):
         self.assertTrue(
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index adc9008..86185c8 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -227,22 +227,23 @@
         seen_names = [n['name'] for n in seen_nets]
         seen_ids = [n['id'] for n in seen_nets]
 
-        self.assertIn(tenant.network.name, seen_names)
-        self.assertIn(tenant.network.id, seen_ids)
+        self.assertIn(tenant.network['name'], seen_names)
+        self.assertIn(tenant.network['id'], seen_ids)
 
         seen_subnets = [(n['id'], n['cidr'], n['network_id'])
                         for n in self._list_subnets()]
-        mysubnet = (tenant.subnet.id, tenant.subnet.cidr, tenant.network.id)
+        mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
+                    tenant.network['id'])
         self.assertIn(mysubnet, seen_subnets)
 
         seen_routers = self._list_routers()
         seen_router_ids = [n['id'] for n in seen_routers]
         seen_router_names = [n['name'] for n in seen_routers]
 
-        self.assertIn(tenant.router.name, seen_router_names)
-        self.assertIn(tenant.router.id, seen_router_ids)
+        self.assertIn(tenant.router['name'], seen_router_names)
+        self.assertIn(tenant.router['id'], seen_router_ids)
 
-        myport = (tenant.router.id, tenant.subnet.id)
+        myport = (tenant.router['id'], tenant.subnet['id'])
         router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
                         in self._list_ports()
                         if self._is_router_port(i)]
@@ -270,7 +271,7 @@
             kwargs["scheduler_hints"] = {'different_host': self.servers}
         server = self.create_server(
             name=name,
-            networks=[{'uuid': tenant.network.id}],
+            networks=[{'uuid': tenant.network["id"]}],
             key_name=tenant.keypair['name'],
             security_groups=security_groups_names,
             wait_until='ACTIVE',
@@ -353,10 +354,10 @@
     def _get_server_ip(self, server, floating=False):
         """returns the ip (floating/internal) of a server"""
         if floating:
-            server_ip = self.floating_ips[server['id']].floating_ip_address
+            server_ip = self.floating_ips[server['id']]['floating_ip_address']
         else:
             server_ip = None
-            network_name = self.tenants[server['tenant_id']].network.name
+            network_name = self.tenants[server['tenant_id']].network['name']
             if network_name in server['addresses']:
                 server_ip = server['addresses'][network_name][0]['addr']
         return server_ip
@@ -364,7 +365,7 @@
     def _connect_to_access_point(self, tenant):
         """create ssh connection to tenant access point"""
         access_point_ssh = \
-            self.floating_ips[tenant.access_point['id']].floating_ip_address
+            self.floating_ips[tenant.access_point['id']]['floating_ip_address']
         private_key = tenant.keypair['private_key']
         access_point_ssh = self.get_remote_client(
             access_point_ssh, private_key=private_key)
@@ -388,7 +389,7 @@
     def _test_in_tenant_allow(self, tenant):
         ruleset = dict(
             protocol='icmp',
-            remote_group_id=tenant.security_groups['default'].id,
+            remote_group_id=tenant.security_groups['default']['id'],
             direction='ingress'
         )
         self._create_security_group_rule(
@@ -464,7 +465,7 @@
             for port in port_list if port['fixed_ips']
         ]
         server_ip = self._get_server_ip(tenant.access_point)
-        subnet_id = tenant.subnet.id
+        subnet_id = tenant.subnet['id']
         self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
 
     @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
@@ -545,7 +546,7 @@
 
             # update port with new security group and check connectivity
             self.ports_client.update_port(port_id, security_groups=[
-                new_tenant.security_groups['new_sg'].id])
+                new_tenant.security_groups['new_sg']['id']])
             self._check_connectivity(
                 access_point=access_point_ssh,
                 ip=self._get_server_ip(server))
diff --git a/tempest/services/image/v1/json/image_members_client.py b/tempest/services/image/v1/json/image_members_client.py
index df16d2fd..e7fa0c9 100644
--- a/tempest/services/image/v1/json/image_members_client.py
+++ b/tempest/services/image/v1/json/image_members_client.py
@@ -39,7 +39,7 @@
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
-    def add_member(self, member_id, image_id, **kwargs):
+    def create_image_member(self, image_id, member_id, **kwargs):
         """Add a member to an image.
 
         Available params: see http://developer.openstack.org/
@@ -51,7 +51,7 @@
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
 
-    def delete_member(self, member_id, image_id):
+    def delete_image_member(self, image_id, member_id):
         """Removes a membership from the image.
 
         Available params: see http://developer.openstack.org/
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index 4ffaf3b..30325c0 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -31,28 +31,6 @@
 class ImagesClient(rest_client.RestClient):
     api_version = "v1"
 
-    def _image_meta_from_headers(self, headers):
-        meta = {'properties': {}}
-        for key, value in six.iteritems(headers):
-            if key.startswith('x-image-meta-property-'):
-                _key = key[22:]
-                meta['properties'][_key] = value
-            elif key.startswith('x-image-meta-'):
-                _key = key[13:]
-                meta[_key] = value
-
-        for key in ['is_public', 'protected', 'deleted']:
-            if key in meta:
-                meta[key] = meta[key].strip().lower() in ('t', 'true', 'yes',
-                                                          '1')
-        for key in ['size', 'min_ram', 'min_disk']:
-            if key in meta:
-                try:
-                    meta[key] = int(meta[key])
-                except ValueError:
-                    pass
-        return meta
-
     def _image_meta_to_headers(self, fields):
         headers = {}
         fields_copy = copy.deepcopy(fields)
@@ -98,9 +76,13 @@
             self._http = self._get_http()
         return self._http
 
-    def create_image(self, **kwargs):
+    def create_image(self, data=None, **kwargs):
+        """Create an image.
+
+        Available params: http://developer.openstack.org/
+                          api-ref-image-v1.html#createImage-v1
+        """
         headers = {}
-        data = kwargs.pop('data', None)
         headers.update(self._image_meta_to_headers(kwargs))
 
         if data is not None:
@@ -111,9 +93,13 @@
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
-    def update_image(self, image_id, **kwargs):
+    def update_image(self, image_id, data=None, **kwargs):
+        """Update an image.
+
+        Available params: http://developer.openstack.org/
+                          api-ref-image-v1.html#updateImage-v1
+        """
         headers = {}
-        data = kwargs.pop('data', None)
         headers.update(self._image_meta_to_headers(kwargs))
 
         if data is not None:
@@ -164,9 +150,8 @@
     def check_image(self, image_id):
         """Check image metadata."""
         url = 'images/%s' % image_id
-        resp, __ = self.head(url)
+        resp, body = self.head(url)
         self.expected_success(200, resp.status)
-        body = self._image_meta_from_headers(resp)
         return rest_client.ResponseBody(resp, body)
 
     def show_image(self, image_id):
@@ -178,7 +163,8 @@
 
     def is_resource_deleted(self, id):
         try:
-            if self.check_image(id)['status'] == 'deleted':
+            resp = self.check_image(id)
+            if resp.response["x-image-meta-status"] == 'deleted':
                 return True
         except lib_exc.NotFound:
             return True
diff --git a/tempest/test.py b/tempest/test.py
index 4c0d0bb..4e06db8 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -39,6 +39,7 @@
 from tempest import exceptions
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
 
 LOG = logging.getLogger(__name__)
 
@@ -539,7 +540,7 @@
             if hasattr(cred_provider, credentials_method):
                 creds = getattr(cred_provider, credentials_method)()
             else:
-                raise exceptions.InvalidCredentials(
+                raise lib_exc.InvalidCredentials(
                     "Invalid credentials type %s" % credential_type)
         return cls.client_manager(credentials=creds.credentials,
                                   service=cls._service)
diff --git a/tempest/tests/cmd/test_account_generator.py b/tempest/tests/cmd/test_account_generator.py
index f253802..b3931d1 100755
--- a/tempest/tests/cmd/test_account_generator.py
+++ b/tempest/tests/cmd/test_account_generator.py
@@ -234,7 +234,7 @@
         self.assertIn('admin', resource_types)
         self.assertIn(['fake_operator'], resource_types)
         self.assertIn(['fake_reseller'], resource_types)
-        self.assertIn(['fake_owner'], resource_types)
+        self.assertIn(['fake_owner', 'fake_operator'], resource_types)
         for resource in resources:
             self.assertIsNotNone(resource[1].network)
             self.assertIsNotNone(resource[1].router)
diff --git a/tempest/tests/common/test_image.py b/tempest/tests/common/test_image.py
new file mode 100644
index 0000000..fdd0ae8
--- /dev/null
+++ b/tempest/tests/common/test_image.py
@@ -0,0 +1,40 @@
+# Copyright 2016 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.common import image
+from tempest.lib.common import rest_client
+from tempest.tests import base
+
+
+class TestImage(base.TestCase):
+
+    def test_get_image_meta_from_headers(self):
+        resp = {
+            'x-image-meta-id': 'ea30c926-0629-4400-bb6e-f8a8da6a4e56',
+            'x-image-meta-owner': '8f421f9470e645b1b10f5d2db7804924',
+            'x-image-meta-status': 'queued',
+            'x-image-meta-name': 'New Http Image'
+        }
+        respbody = rest_client.ResponseBody(resp)
+        observed = image.get_image_meta_from_headers(respbody)
+
+        expected = {
+            'properties': {},
+            'id': 'ea30c926-0629-4400-bb6e-f8a8da6a4e56',
+            'owner': '8f421f9470e645b1b10f5d2db7804924',
+            'status': 'queued',
+            'name': 'New Http Image'
+        }
+        self.assertEqual(expected, observed)
diff --git a/tempest/tests/lib/test_auth.py b/tempest/tests/lib/test_auth.py
index c08bf6a..12590a3 100644
--- a/tempest/tests/lib/test_auth.py
+++ b/tempest/tests/lib/test_auth.py
@@ -802,3 +802,12 @@
         _, auth_data = self.auth_provider.get_auth()
         self.assertIn('domain', auth_data)
         self.assertNotIn('project', auth_data)
+
+
+class TestGetCredentials(base.TestCase):
+
+    def test_invalid_identity_version(self):
+        with testtools.ExpectedException(exceptions.InvalidIdentityVersion,
+                                         '.* v1 .*'):
+            auth.get_credentials('http://localhost/identity/v3',
+                                 identity_version='v1')