Added a check for cloud-init completion before final ssh client check.
[snaps.git] / snaps / openstack / tests / create_instance_tests.py
index 998fe88..17831b3 100644 (file)
@@ -20,22 +20,37 @@ import unittest
 import uuid
 
 import os
 import uuid
 
 import os
+from neutronclient.common.exceptions import (
+    InvalidIpForSubnetClient, BadRequest)
 
 from snaps import file_utils
 
 from snaps import file_utils
-from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
-from snaps.openstack.create_image import OpenStackImage, ImageSettings
+from snaps.config.image import ImageConfig
+from snaps.config.keypair import KeypairConfig
+from snaps.config.network import PortConfig, NetworkConfig, SubnetConfig
+from snaps.config.router import RouterConfig
+from snaps.config.security_group import (
+    Protocol, SecurityGroupRuleConfig, Direction, SecurityGroupConfig)
+from snaps.config.vm_inst import (
+    VmInstanceConfig, FloatingIpConfig,  VmInstanceConfigError,
+    FloatingIpConfigError)
+from snaps.config.volume import VolumeConfig
+from snaps.openstack import create_network, create_router, create_instance
+from snaps.openstack.create_flavor import OpenStackFlavor
+from snaps.openstack.create_image import OpenStackImage
 from snaps.openstack.create_instance import (
     VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings)
 from snaps.openstack.create_instance import (
     VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings)
-from snaps.openstack.create_keypairs import OpenStackKeypair, KeypairSettings
-from snaps.openstack.create_network import OpenStackNetwork, PortSettings
+from snaps.openstack.create_keypairs import OpenStackKeypair
+from snaps.openstack.create_network import OpenStackNetwork
 from snaps.openstack.create_router import OpenStackRouter
 from snaps.openstack.create_router import OpenStackRouter
-from snaps.openstack.create_security_group import (
-    SecurityGroupSettings, OpenStackSecurityGroup, SecurityGroupRuleSettings,
-    Direction, Protocol)
+from snaps.openstack.create_security_group import OpenStackSecurityGroup
+from snaps.openstack.create_volume import OpenStackVolume
+from snaps.openstack.os_credentials import OSCreds
 from snaps.openstack.tests import openstack_tests, validation_utils
 from snaps.openstack.tests.os_source_file_test import (
     OSIntegrationTestCase, OSComponentTestCase)
 from snaps.openstack.tests import openstack_tests, validation_utils
 from snaps.openstack.tests.os_source_file_test import (
     OSIntegrationTestCase, OSComponentTestCase)
-from snaps.openstack.utils import nova_utils
+from snaps.openstack.utils import nova_utils, keystone_utils, neutron_utils
+from snaps.openstack.utils.nova_utils import RebootType
+from snaps.openstack.utils import nova_utils, settings_utils, neutron_utils
 
 __author__ = 'spisarski'
 
 
 __author__ = 'spisarski'
 
@@ -50,31 +65,31 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
     """
 
     def test_no_params(self):
     """
 
     def test_no_params(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(VmInstanceConfigError):
             VmInstanceSettings()
 
     def test_empty_config(self):
             VmInstanceSettings()
 
     def test_empty_config(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(VmInstanceConfigError):
             VmInstanceSettings(config=dict())
 
     def test_name_only(self):
             VmInstanceSettings(config=dict())
 
     def test_name_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(VmInstanceConfigError):
             VmInstanceSettings(name='foo')
 
     def test_config_with_name_only(self):
             VmInstanceSettings(name='foo')
 
     def test_config_with_name_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(VmInstanceConfigError):
             VmInstanceSettings(config={'name': 'foo'})
 
     def test_name_flavor_only(self):
             VmInstanceSettings(config={'name': 'foo'})
 
     def test_name_flavor_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(VmInstanceConfigError):
             VmInstanceSettings(name='foo', flavor='bar')
 
     def test_config_with_name_flavor_only(self):
             VmInstanceSettings(name='foo', flavor='bar')
 
     def test_config_with_name_flavor_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(VmInstanceConfigError):
             VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
 
     def test_name_flavor_port_only(self):
             VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
 
     def test_name_flavor_port_only(self):
-        port_settings = PortSettings(name='foo-port', network_name='bar-net')
+        port_settings = PortConfig(name='foo-port', network_name='bar-net')
         settings = VmInstanceSettings(name='foo', flavor='bar',
                                       port_settings=[port_settings])
         self.assertEqual('foo', settings.name)
         settings = VmInstanceSettings(name='foo', flavor='bar',
                                       port_settings=[port_settings])
         self.assertEqual('foo', settings.name)
@@ -89,9 +104,10 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
         self.assertEqual(300, settings.vm_delete_timeout)
         self.assertEqual(180, settings.ssh_connect_timeout)
         self.assertIsNone(settings.availability_zone)
         self.assertEqual(300, settings.vm_delete_timeout)
         self.assertEqual(180, settings.ssh_connect_timeout)
         self.assertIsNone(settings.availability_zone)
+        self.assertIsNone(settings.volume_names)
 
     def test_config_with_name_flavor_port_only(self):
 
     def test_config_with_name_flavor_port_only(self):
-        port_settings = PortSettings(name='foo-port', network_name='bar-net')
+        port_settings = PortConfig(name='foo-port', network_name='bar-net')
         settings = VmInstanceSettings(
             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
         self.assertEqual('foo', settings.name)
         settings = VmInstanceSettings(
             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
         self.assertEqual('foo', settings.name)
@@ -106,20 +122,20 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
         self.assertEqual(300, settings.vm_delete_timeout)
         self.assertEqual(180, settings.ssh_connect_timeout)
         self.assertIsNone(settings.availability_zone)
         self.assertEqual(300, settings.vm_delete_timeout)
         self.assertEqual(180, settings.ssh_connect_timeout)
         self.assertIsNone(settings.availability_zone)
+        self.assertIsNone(settings.volume_names)
 
     def test_all(self):
 
     def test_all(self):
-        port_settings = PortSettings(name='foo-port', network_name='bar-net')
+        port_settings = PortConfig(name='foo-port', network_name='bar-net')
         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
                                           router_name='foo-bar-router')
 
         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
                                           router_name='foo-bar-router')
 
-        settings = VmInstanceSettings(name='foo', flavor='bar',
-                                      port_settings=[port_settings],
-                                      security_group_names=['sec_grp_1'],
-                                      floating_ip_settings=[fip_settings],
-                                      sudo_user='joe', vm_boot_timeout=999,
-                                      vm_delete_timeout=333,
-                                      ssh_connect_timeout=111,
-                                      availability_zone='server name')
+        settings = VmInstanceSettings(
+            name='foo', flavor='bar', port_settings=[port_settings],
+            security_group_names=['sec_grp_1'],
+            floating_ip_settings=[fip_settings], sudo_user='joe',
+            vm_boot_timeout=999, vm_delete_timeout=333,
+            ssh_connect_timeout=111, availability_zone='server name',
+            volume_names=['vol1'])
         self.assertEqual('foo', settings.name)
         self.assertEqual('bar', settings.flavor)
         self.assertEqual(1, len(settings.port_settings))
         self.assertEqual('foo', settings.name)
         self.assertEqual('bar', settings.flavor)
         self.assertEqual(1, len(settings.port_settings))
@@ -138,9 +154,10 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
         self.assertEqual(333, settings.vm_delete_timeout)
         self.assertEqual(111, settings.ssh_connect_timeout)
         self.assertEqual('server name', settings.availability_zone)
         self.assertEqual(333, settings.vm_delete_timeout)
         self.assertEqual(111, settings.ssh_connect_timeout)
         self.assertEqual('server name', settings.availability_zone)
+        self.assertEqual('vol1', settings.volume_names[0])
 
     def test_config_all(self):
 
     def test_config_all(self):
-        port_settings = PortSettings(name='foo-port', network_name='bar-net')
+        port_settings = PortConfig(name='foo-port', network_name='bar-net')
         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
                                           router_name='foo-bar-router')
 
         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
                                           router_name='foo-bar-router')
 
@@ -149,7 +166,8 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
                'security_group_names': ['sec_grp_1'],
                'floating_ips': [fip_settings], 'sudo_user': 'joe',
                'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
                'security_group_names': ['sec_grp_1'],
                'floating_ips': [fip_settings], 'sudo_user': 'joe',
                'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
-               'ssh_connect_timeout': 111, 'availability_zone': 'server name'})
+               'ssh_connect_timeout': 111, 'availability_zone': 'server name',
+               'volume_names': ['vol2']})
         self.assertEqual('foo', settings.name)
         self.assertEqual('bar', settings.flavor)
         self.assertEqual(1, len(settings.port_settings))
         self.assertEqual('foo', settings.name)
         self.assertEqual('bar', settings.flavor)
         self.assertEqual(1, len(settings.port_settings))
@@ -167,6 +185,7 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
         self.assertEqual(333, settings.vm_delete_timeout)
         self.assertEqual(111, settings.ssh_connect_timeout)
         self.assertEqual('server name', settings.availability_zone)
         self.assertEqual(333, settings.vm_delete_timeout)
         self.assertEqual(111, settings.ssh_connect_timeout)
         self.assertEqual('server name', settings.availability_zone)
+        self.assertEqual('vol2', settings.volume_names[0])
 
 
 class FloatingIpSettingsUnitTests(unittest.TestCase):
 
 
 class FloatingIpSettingsUnitTests(unittest.TestCase):
@@ -175,42 +194,53 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
     """
 
     def test_no_params(self):
     """
 
     def test_no_params(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings()
 
     def test_empty_config(self):
             FloatingIpSettings()
 
     def test_empty_config(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(**dict())
 
     def test_name_only(self):
             FloatingIpSettings(**dict())
 
     def test_name_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(name='foo')
 
     def test_config_with_name_only(self):
             FloatingIpSettings(name='foo')
 
     def test_config_with_name_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(**{'name': 'foo'})
 
     def test_name_port_only(self):
             FloatingIpSettings(**{'name': 'foo'})
 
     def test_name_port_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(name='foo', port_name='bar')
 
     def test_config_with_name_port_only(self):
             FloatingIpSettings(name='foo', port_name='bar')
 
     def test_config_with_name_port_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(**{'name': 'foo', 'port_name': 'bar'})
 
     def test_name_router_only(self):
             FloatingIpSettings(**{'name': 'foo', 'port_name': 'bar'})
 
     def test_name_router_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(name='foo', router_name='bar')
 
     def test_config_with_name_router_only(self):
             FloatingIpSettings(name='foo', router_name='bar')
 
     def test_config_with_name_router_only(self):
-        with self.assertRaises(Exception):
+        with self.assertRaises(FloatingIpConfigError):
             FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'})
 
             FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'})
 
-    def test_name_port_router_only(self):
+    def test_name_port_router_name_only(self):
         settings = FloatingIpSettings(name='foo', port_name='foo-port',
                                       router_name='bar-router')
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
         settings = FloatingIpSettings(name='foo', port_name='foo-port',
                                       router_name='bar-router')
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
+        self.assertIsNone(settings.port_id)
+        self.assertEqual('bar-router', settings.router_name)
+        self.assertIsNone(settings.subnet_name)
+        self.assertTrue(settings.provisioning)
+
+    def test_name_port_router_id_only(self):
+        settings = FloatingIpSettings(name='foo', port_id='foo-port',
+                                      router_name='bar-router')
+        self.assertEqual('foo', settings.name)
+        self.assertEqual('foo-port', settings.port_id)
+        self.assertIsNone(settings.port_name)
         self.assertEqual('bar-router', settings.router_name)
         self.assertIsNone(settings.subnet_name)
         self.assertTrue(settings.provisioning)
         self.assertEqual('bar-router', settings.router_name)
         self.assertIsNone(settings.subnet_name)
         self.assertTrue(settings.provisioning)
@@ -221,6 +251,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
                'router_name': 'bar-router'})
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
                'router_name': 'bar-router'})
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
+        self.assertIsNone(settings.port_id)
         self.assertEqual('bar-router', settings.router_name)
         self.assertIsNone(settings.subnet_name)
         self.assertTrue(settings.provisioning)
         self.assertEqual('bar-router', settings.router_name)
         self.assertIsNone(settings.subnet_name)
         self.assertTrue(settings.provisioning)
@@ -232,6 +263,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
                                       provisioning=False)
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
                                       provisioning=False)
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
+        self.assertIsNone(settings.port_id)
         self.assertEqual('bar-router', settings.router_name)
         self.assertEqual('bar-subnet', settings.subnet_name)
         self.assertFalse(settings.provisioning)
         self.assertEqual('bar-router', settings.router_name)
         self.assertEqual('bar-subnet', settings.subnet_name)
         self.assertFalse(settings.provisioning)
@@ -243,6 +275,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
                'provisioning': False})
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
                'provisioning': False})
         self.assertEqual('foo', settings.name)
         self.assertEqual('foo-port', settings.port_name)
+        self.assertIsNone(settings.port_id)
         self.assertEqual('bar-router', settings.router_name)
         self.assertEqual('bar-subnet', settings.subnet_name)
         self.assertFalse(settings.provisioning)
         self.assertEqual('bar-router', settings.router_name)
         self.assertEqual('bar-subnet', settings.subnet_name)
         self.assertFalse(settings.provisioning)
@@ -261,6 +294,7 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         """
         super(self.__class__, self).__start__()
 
         """
         super(self.__class__, self).__start__()
 
+        self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.vm_inst_name = guid + '-inst'
         self.port_1_name = guid + 'port-1'
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.vm_inst_name = guid + '-inst'
         self.port_1_name = guid + 'port-1'
@@ -272,8 +306,11 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         self.inst_creator = None
 
         self.priv_net_config = openstack_tests.get_priv_net_config(
         self.inst_creator = None
 
         self.priv_net_config = openstack_tests.get_priv_net_config(
-            net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
-        self.port_settings = PortSettings(
+            project_name=self.os_creds.project_name,
+            net_name=guid + '-priv-net',
+            subnet_name=guid + '-priv-subnet',
+            netconf_override=self.netconf_override)
+        self.port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.priv_net_config.network_settings.name)
 
             name=self.port_1_name,
             network_name=self.priv_net_config.network_settings.name)
 
@@ -294,10 +331,15 @@ class SimpleHealthCheck(OSIntegrationTestCase):
             self.network_creator.create()
 
             # Create Flavor
             self.network_creator.create()
 
             # Create Flavor
+            self.flavor_ram = 256
+            if (self.flavor_metadata and
+               self.flavor_metadata.get('hw:mem_page_size') == 'large'):
+                self.flavor_ram = 1024
+            flavor_config = openstack_tests.get_flavor_config(
+                name=guid + '-flavor-name', ram=self.flavor_ram, disk=10,
+                vcpus=1, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10,
-                               vcpus=1, metadata=self.flavor_metadata))
+                self.admin_os_creds, flavor_config)
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
@@ -346,7 +388,7 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         Tests the creation of an OpenStack instance with a single port and
         ensures that it's assigned IP address is the actual.
         """
         Tests the creation of an OpenStack instance with a single port and
         ensures that it's assigned IP address is the actual.
         """
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -354,14 +396,14 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         self.inst_creator = OpenStackVmInstance(
             self.os_creds, instance_settings,
             self.image_creator.image_settings)
         self.inst_creator = OpenStackVmInstance(
             self.os_creds, instance_settings,
             self.image_creator.image_settings)
-        vm = self.inst_creator.create()
+        self.inst_creator.create()
 
         ip = self.inst_creator.get_port_ip(self.port_settings.name)
         self.assertIsNotNone(ip)
 
         self.assertTrue(self.inst_creator.vm_active(block=True))
 
 
         ip = self.inst_creator.get_port_ip(self.port_settings.name)
         self.assertIsNotNone(ip)
 
         self.assertTrue(self.inst_creator.vm_active(block=True))
 
-        self.assertTrue(check_dhcp_lease(vm, ip))
+        self.assertTrue(check_dhcp_lease(self.inst_creator, ip))
 
 
 class CreateInstanceSimpleTests(OSIntegrationTestCase):
 
 
 class CreateInstanceSimpleTests(OSIntegrationTestCase):
@@ -371,21 +413,16 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase):
 
     def setUp(self):
         """
 
     def setUp(self):
         """
-        Instantiates the CreateImage object that is responsible for downloading
-        and creating an OS image file
-        within OpenStack
+        Setup the objects required for the test
         """
         super(self.__class__, self).__start__()
 
         """
         super(self.__class__, self).__start__()
 
-        guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
-        self.vm_inst_name = guid + '-inst'
+        self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        self.vm_inst_name = self.guid + '-inst'
         self.nova = nova_utils.nova_client(self.os_creds)
         self.nova = nova_utils.nova_client(self.os_creds)
+        self.neutron = neutron_utils.neutron_client(self.os_creds)
         os_image_settings = openstack_tests.cirros_image_settings(
         os_image_settings = openstack_tests.cirros_image_settings(
-            name=guid + '-image', image_metadata=self.image_metadata)
-
-        net_config = openstack_tests.get_priv_net_config(
-            net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
-            router_name=guid + '-pub-router', external_net=self.ext_net_name)
+            name=self.guid + '-image', image_metadata=self.image_metadata)
 
         # Initialize for tearDown()
         self.image_creator = None
 
         # Initialize for tearDown()
         self.image_creator = None
@@ -401,21 +438,13 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase):
             self.image_creator.create()
 
             # Create Flavor
             self.image_creator.create()
 
             # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=self.guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10,
-                               vcpus=2, metadata=self.flavor_metadata))
+                self.admin_os_creds, flavor_config)
             self.flavor_creator.create()
             self.flavor_creator.create()
-
-            # Create Network
-            self.network_creator = OpenStackNetwork(
-                self.os_creds, net_config.network_settings)
-            self.network_creator.create()
-
-            self.port_settings = PortSettings(
-                name=guid + '-port',
-                network_name=net_config.network_settings.name)
-
+            self.network_creator = None
         except Exception as e:
             self.tearDown()
             raise e
         except Exception as e:
             self.tearDown()
             raise e
@@ -462,7 +491,23 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase):
         Tests the creation of an OpenStack instance with a single port with a
         static IP without a Floating IP.
         """
         Tests the creation of an OpenStack instance with a single port with a
         static IP without a Floating IP.
         """
-        instance_settings = VmInstanceSettings(
+        # Create Network
+        net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
+            net_name=self.guid + '-pub-net',
+            subnet_name=self.guid + '-pub-subnet',
+            router_name=self.guid + '-pub-router',
+            external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
+        self.network_creator = OpenStackNetwork(
+            self.os_creds, net_config.network_settings)
+        self.network_creator.create()
+
+        self.port_settings = PortConfig(
+            name=self.guid + '-port',
+            network_name=net_config.network_settings.name)
+
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -471,20 +516,174 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase):
             self.os_creds, instance_settings,
             self.image_creator.image_settings)
 
             self.os_creds, instance_settings,
             self.image_creator.image_settings)
 
-        vm_inst = self.inst_creator.create()
-        self.assertEqual(1, len(
-            nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
+        vm_inst = self.inst_creator.create(block=True)
+        vm_inst_get = nova_utils.get_server(
+            self.nova, self.neutron, self.keystone,
+            vm_inst_settings=instance_settings)
+        self.assertEqual(vm_inst, vm_inst_get)
+
+        self.assertIsNotNone(self.inst_creator.get_vm_inst().availability_zone)
+        self.assertIsNone(self.inst_creator.get_vm_inst().compute_host)
 
         # Delete instance
         nova_utils.delete_vm_instance(self.nova, vm_inst)
 
         self.assertTrue(self.inst_creator.vm_deleted(block=True))
 
         # Delete instance
         nova_utils.delete_vm_instance(self.nova, vm_inst)
 
         self.assertTrue(self.inst_creator.vm_deleted(block=True))
-        self.assertEqual(0, len(
-            nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
+        self.assertIsNone(nova_utils.get_server(
+            self.nova, self.neutron, self.keystone,
+            vm_inst_settings=instance_settings))
 
         # Exception should not be thrown
         self.inst_creator.clean()
 
 
         # Exception should not be thrown
         self.inst_creator.clean()
 
+    def test_create_admin_instance(self):
+        """
+        Tests the creation of an OpenStack instance with a single port with a
+        static IP without a Floating IP.
+        """
+        # Create Network
+        net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
+            net_name=self.guid + '-pub-net',
+            subnet_name=self.guid + '-pub-subnet',
+            router_name=self.guid + '-pub-router',
+            external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
+        self.network_creator = OpenStackNetwork(
+            self.admin_os_creds, net_config.network_settings)
+        self.network_creator.create()
+
+        self.port_settings = PortConfig(
+            name=self.guid + '-port',
+            network_name=net_config.network_settings.name)
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[self.port_settings])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.admin_os_creds, instance_settings,
+            self.image_creator.image_settings)
+
+        admin_nova = nova_utils.nova_client(self.admin_os_creds)
+        admin_neutron = neutron_utils.neutron_client(self.admin_os_creds)
+        admin_key = keystone_utils.keystone_client(self.admin_os_creds)
+        vm_inst = self.inst_creator.create(block=True)
+
+        self.assertIsNotNone(vm_inst)
+        vm_inst_get = nova_utils.get_server(
+            admin_nova, admin_neutron, admin_key,
+            vm_inst_settings=instance_settings)
+        self.assertEqual(vm_inst, vm_inst_get)
+
+        self.assertIsNone(nova_utils.get_server(
+            self.nova, self.neutron, self.keystone,
+            vm_inst_settings=instance_settings))
+
+        self.assertIsNotNone(self.inst_creator.get_vm_inst().availability_zone)
+        self.assertIsNotNone(self.inst_creator.get_vm_inst().compute_host)
+
+
+class CreateInstanceExternalNetTests(OSIntegrationTestCase):
+    """
+    Simple instance creation tests where the network is external
+    """
+
+    def setUp(self):
+        """
+        Instantiates the CreateImage object that is responsible for downloading
+        and creating an OS image file
+        within OpenStack
+        """
+        super(self.__class__, self).__start__()
+
+        guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        self.vm_inst_name = guid + '-inst'
+        self.nova = nova_utils.nova_client(self.admin_os_creds)
+        self.neutron = neutron_utils.neutron_client(self.admin_os_creds)
+        os_image_settings = openstack_tests.cirros_image_settings(
+            name=guid + '-image', image_metadata=self.image_metadata)
+
+        # Initialize for tearDown()
+        self.image_creator = None
+        self.flavor_creator = None
+        self.inst_creator = None
+
+        try:
+            # Create Image
+            self.image_creator = OpenStackImage(self.os_creds,
+                                                os_image_settings)
+            self.image_creator.create()
+
+            # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
+            self.flavor_creator = OpenStackFlavor(
+                self.admin_os_creds, flavor_config)
+            self.flavor_creator.create()
+
+            self.port_settings = PortConfig(
+                name=guid + '-port',
+                network_name=self.ext_net_name)
+
+        except Exception as e:
+            self.tearDown()
+            raise e
+
+    def tearDown(self):
+        """
+        Cleans the created object
+        """
+        if self.inst_creator:
+            try:
+                self.inst_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning VM instance with message '
+                    '- %s', e)
+
+        if self.flavor_creator:
+            try:
+                self.flavor_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning flavor with message - %s',
+                    e)
+
+        if self.image_creator and not self.image_creator.image_settings.exists:
+            try:
+                self.image_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning image with message - %s', e)
+
+        super(self.__class__, self).__clean__()
+
+    def test_create_instance_public_net(self):
+        """
+        Tests the creation of an OpenStack instance with a single port to
+        the external network.
+        """
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[self.port_settings])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.admin_os_creds, instance_settings,
+            self.image_creator.image_settings)
+
+        vm_inst = self.inst_creator.create(block=True)
+        vm_inst_get = nova_utils.get_server(
+            self.nova, self.neutron, self.keystone,
+            vm_inst_settings=instance_settings)
+        self.assertEqual(vm_inst, vm_inst_get)
+        ip = self.inst_creator.get_port_ip(self.port_settings.name)
+
+        check_dhcp_lease(self.inst_creator, ip)
+
 
 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
     """
 
 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
     """
@@ -496,8 +695,10 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         Instantiates the CreateImage object that is responsible for downloading
         and creating an OS image file within OpenStack
         """
         Instantiates the CreateImage object that is responsible for downloading
         and creating an OS image file within OpenStack
         """
+        self.proj_users = ['admin']
         super(self.__class__, self).__start__()
 
         super(self.__class__, self).__start__()
 
+        self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.keypair_priv_filepath = 'tmp/' + guid
         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.keypair_priv_filepath = 'tmp/' + guid
         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
@@ -517,8 +718,10 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         self.inst_creators = list()
 
         self.pub_net_config = openstack_tests.get_pub_net_config(
         self.inst_creators = list()
 
         self.pub_net_config = openstack_tests.get_pub_net_config(
+            project_name=self.os_creds.project_name,
             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
-            router_name=guid + '-pub-router', external_net=self.ext_net_name)
+            router_name=guid + '-pub-router', external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
         os_image_settings = openstack_tests.cirros_image_settings(
             name=guid + '-image', image_metadata=self.image_metadata)
         try:
         os_image_settings = openstack_tests.cirros_image_settings(
             name=guid + '-image', image_metadata=self.image_metadata)
         try:
@@ -538,32 +741,31 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
             self.router_creator.create()
 
             # Create Flavor
             self.router_creator.create()
 
             # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10,
-                               vcpus=2, metadata=self.flavor_metadata))
+                self.admin_os_creds, flavor_config)
             self.flavor_creator.create()
 
             self.keypair_creator = OpenStackKeypair(
             self.flavor_creator.create()
 
             self.keypair_creator = OpenStackKeypair(
-                self.os_creds, KeypairSettings(
+                self.os_creds, KeypairConfig(
                     name=self.keypair_name,
                     public_filepath=self.keypair_pub_filepath,
                     private_filepath=self.keypair_priv_filepath))
             self.keypair_creator.create()
 
             sec_grp_name = guid + '-sec-grp'
                     name=self.keypair_name,
                     public_filepath=self.keypair_pub_filepath,
                     private_filepath=self.keypair_priv_filepath))
             self.keypair_creator.create()
 
             sec_grp_name = guid + '-sec-grp'
-            rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
-                                              direction=Direction.ingress,
-                                              protocol=Protocol.icmp)
-            rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
-                                              direction=Direction.ingress,
-                                              protocol=Protocol.tcp,
-                                              port_range_min=22,
-                                              port_range_max=22)
+            rule1 = SecurityGroupRuleConfig(
+                sec_grp_name=sec_grp_name, direction=Direction.ingress,
+                protocol=Protocol.icmp)
+            rule2 = SecurityGroupRuleConfig(
+                sec_grp_name=sec_grp_name, direction=Direction.ingress,
+                protocol=Protocol.tcp, port_range_min=22, port_range_max=22)
             self.sec_grp_creator = OpenStackSecurityGroup(
                 self.os_creds,
             self.sec_grp_creator = OpenStackSecurityGroup(
                 self.os_creds,
-                SecurityGroupSettings(name=sec_grp_name,
-                                      rule_settings=[rule1, rule2]))
+                SecurityGroupConfig(
+                    name=sec_grp_name, rule_settings=[rule1, rule2]))
             self.sec_grp_creator.create()
         except Exception as e:
             self.tearDown()
             self.sec_grp_creator.create()
         except Exception as e:
             self.tearDown()
@@ -589,12 +791,6 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
                     'Unexpected exception cleaning keypair with message - %s',
                     e)
 
                     'Unexpected exception cleaning keypair with message - %s',
                     e)
 
-        if os.path.isfile(self.keypair_pub_filepath):
-            os.remove(self.keypair_pub_filepath)
-
-        if os.path.isfile(self.keypair_priv_filepath):
-            os.remove(self.keypair_priv_filepath)
-
         if self.flavor_creator:
             try:
                 self.flavor_creator.clean()
         if self.flavor_creator:
             try:
                 self.flavor_creator.clean()
@@ -643,17 +839,17 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         """
         ip_1 = '10.55.1.100'
         sub_settings = self.pub_net_config.network_settings.subnet_settings
         """
         ip_1 = '10.55.1.100'
         sub_settings = self.pub_net_config.network_settings.subnet_settings
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.pub_net_config.network_settings.name,
             ip_addrs=[
                 {'subnet_name': sub_settings[0].name, 'ip': ip_1}])
 
             name=self.port_1_name,
             network_name=self.pub_net_config.network_settings.name,
             ip_addrs=[
                 {'subnet_name': sub_settings[0].name, 'ip': ip_1}])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings],
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings],
-            floating_ip_settings=[FloatingIpSettings(
+            floating_ip_settings=[FloatingIpConfig(
                 name=self.floating_ip_name, port_name=self.port_1_name,
                 router_name=self.pub_net_config.router_settings.name)])
 
                 name=self.floating_ip_name, port_name=self.port_1_name,
                 router_name=self.pub_net_config.router_settings.name)])
 
@@ -662,26 +858,27 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
             self.image_creator.image_settings,
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
             self.image_creator.image_settings,
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
-        vm_inst = inst_creator.create()
+        vm_inst = inst_creator.create(block=True)
 
         self.assertEqual(ip_1, inst_creator.get_port_ip(self.port_1_name))
         self.assertTrue(inst_creator.vm_active(block=True))
 
         self.assertEqual(ip_1, inst_creator.get_port_ip(self.port_1_name))
         self.assertTrue(inst_creator.vm_active(block=True))
-        self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+        self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
 
     def test_ssh_client_fip_before_active(self):
         """
         Tests the ability to access a VM via SSH and a floating IP when it has
         been assigned prior to being active.
         """
 
     def test_ssh_client_fip_before_active(self):
         """
         Tests the ability to access a VM via SSH and a floating IP when it has
         been assigned prior to being active.
         """
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.pub_net_config.network_settings.name)
 
             name=self.port_1_name,
             network_name=self.pub_net_config.network_settings.name)
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings],
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings],
-            floating_ip_settings=[FloatingIpSettings(
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
+            floating_ip_settings=[FloatingIpConfig(
                 name=self.floating_ip_name, port_name=self.port_1_name,
                 router_name=self.pub_net_config.router_settings.name)])
 
                 name=self.floating_ip_name, port_name=self.port_1_name,
                 router_name=self.pub_net_config.router_settings.name)])
 
@@ -696,11 +893,9 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         self.assertTrue(inst_creator.vm_active(block=True))
 
         ip = inst_creator.get_port_ip(port_settings.name)
         self.assertTrue(inst_creator.vm_active(block=True))
 
         ip = inst_creator.get_port_ip(port_settings.name)
-        self.assertTrue(check_dhcp_lease(vm_inst, ip))
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
 
 
-        inst_creator.add_security_group(
-            self.sec_grp_creator.get_security_group())
-        self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+        self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
 
         self.assertTrue(validate_ssh_client(inst_creator))
 
 
         self.assertTrue(validate_ssh_client(inst_creator))
 
@@ -709,15 +904,16 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         Tests the ability to access a VM via SSH and a floating IP when it has
         been assigned prior to being active.
         """
         Tests the ability to access a VM via SSH and a floating IP when it has
         been assigned prior to being active.
         """
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.pub_net_config.network_settings.name)
 
             name=self.port_1_name,
             network_name=self.pub_net_config.network_settings.name)
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings],
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings],
-            floating_ip_settings=[FloatingIpSettings(
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
+            floating_ip_settings=[FloatingIpConfig(
                 name=self.floating_ip_name, port_name=self.port_1_name,
                 router_name=self.pub_net_config.router_settings.name)])
 
                 name=self.floating_ip_name, port_name=self.port_1_name,
                 router_name=self.pub_net_config.router_settings.name)])
 
@@ -734,117 +930,561 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         self.assertTrue(inst_creator.vm_active(block=True))
 
         ip = inst_creator.get_port_ip(port_settings.name)
         self.assertTrue(inst_creator.vm_active(block=True))
 
         ip = inst_creator.get_port_ip(port_settings.name)
-        self.assertTrue(check_dhcp_lease(vm_inst, ip))
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
 
 
-        inst_creator.add_security_group(
-            self.sec_grp_creator.get_security_group())
-        self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+        self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
 
         self.assertTrue(validate_ssh_client(inst_creator))
 
 
         self.assertTrue(validate_ssh_client(inst_creator))
 
-
-class CreateInstancePortManipulationTests(OSIntegrationTestCase):
-    """
-    Test for the CreateInstance class with a single NIC/Port where mac and IP
-    values are manually set
-    """
-
-    def setUp(self):
+    def test_ssh_client_fip_after_reboot(self):
         """
         """
-        Instantiates the CreateImage object that is responsible for downloading
-        and creating an OS image file within OpenStack
+        Tests the ability to access a VM via SSH and a floating IP after it has
+        been rebooted.
         """
         """
-        super(self.__class__, self).__start__()
-
-        guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
-        self.vm_inst_name = guid + '-inst'
-        self.port_1_name = guid + 'port-1'
-        self.port_2_name = guid + 'port-2'
-        self.floating_ip_name = guid + 'fip1'
+        port_settings = PortConfig(
+            name=self.port_1_name,
+            network_name=self.pub_net_config.network_settings.name)
 
 
-        # Initialize for tearDown()
-        self.image_creator = None
-        self.network_creator = None
-        self.flavor_creator = None
-        self.inst_creator = None
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings],
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
+            floating_ip_settings=[FloatingIpConfig(
+                name=self.floating_ip_name, port_name=self.port_1_name,
+                router_name=self.pub_net_config.router_settings.name)])
 
 
-        self.net_config = openstack_tests.get_priv_net_config(
-            net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
-            router_name=guid + '-pub-router', external_net=self.ext_net_name)
-        os_image_settings = openstack_tests.cirros_image_settings(
-            name=guid + '-image', image_metadata=self.image_metadata)
+        inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+        self.inst_creators.append(inst_creator)
 
 
-        try:
-            # Create Image
-            self.image_creator = OpenStackImage(self.os_creds,
-                                                os_image_settings)
-            self.image_creator.create()
+        # block=True will force the create() method to block until the
+        vm_inst = inst_creator.create(block=True)
+        self.assertIsNotNone(vm_inst)
 
 
-            # Create Network
-            self.network_creator = OpenStackNetwork(
-                self.os_creds, self.net_config.network_settings)
-            self.network_creator.create()
+        self.assertTrue(inst_creator.vm_active(block=True))
 
 
-            # Create Flavor
-            self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10,
-                               vcpus=2, metadata=self.flavor_metadata))
-            self.flavor_creator.create()
-        except Exception as e:
-            self.tearDown()
-            raise e
+        ip = inst_creator.get_port_ip(port_settings.name)
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
 
 
-    def tearDown(self):
-        """
-        Cleans the created object
-        """
-        if self.inst_creator:
-            try:
-                self.inst_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning VM instance with message '
-                    '- %s', e)
+        self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
 
 
-        if self.flavor_creator:
-            try:
-                self.flavor_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning flavor with message - %s',
-                    e)
+        self.assertTrue(validate_ssh_client(inst_creator))
 
 
-        if self.network_creator:
-            try:
-                self.network_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning network with message - %s',
-                    e)
+        # Test default reboot which should be 'SOFT'
+        inst_creator.reboot()
+        # Lag time to allow for shutdown routine to take effect
+        time.sleep(15)
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
+        self.assertTrue(validate_ssh_client(inst_creator))
 
 
-        if self.image_creator and not self.image_creator.image_settings.exists:
-            try:
-                self.image_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning image with message - %s', e)
+        # Test 'SOFT' reboot
+        inst_creator.reboot(reboot_type=RebootType.soft)
+        time.sleep(15)
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
+        self.assertTrue(validate_ssh_client(inst_creator))
 
 
-        super(self.__class__, self).__clean__()
+        # Test 'HARD' reboot
+        inst_creator.reboot(reboot_type=RebootType.hard)
+        time.sleep(15)
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
+        self.assertTrue(validate_ssh_client(inst_creator))
 
 
-    def test_set_custom_valid_ip_one_subnet(self):
+    def test_ssh_client_fip_after_init(self):
         """
         """
-        Tests the creation of an OpenStack instance with a single port with a
+        Tests the ability to assign a floating IP to an already initialized
+        OpenStackVmInstance object. After the floating IP has been allocated
+        and assigned, this test will ensure that it can be accessed via SSH.
+        """
+        port_settings = PortConfig(
+            name=self.port_1_name,
+            network_name=self.pub_net_config.network_settings.name)
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings],
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name])
+
+        inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+        self.inst_creators.append(inst_creator)
+
+        # block=True will force the create() method to block until the
+        vm_inst = inst_creator.create(block=True)
+        self.assertIsNotNone(vm_inst)
+
+        self.assertTrue(inst_creator.vm_active(block=True))
+        ip = inst_creator.get_port_ip(port_settings.name)
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
+        self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
+
+        inst_creator.add_floating_ip(FloatingIpConfig(
+            name=self.floating_ip_name, port_name=self.port_1_name,
+            router_name=self.pub_net_config.router_settings.name))
+
+        self.assertTrue(validate_ssh_client(inst_creator))
+
+    def test_ssh_client_fip_reverse_engineer(self):
+        """
+        Tests the ability to assign a floating IP to a reverse engineered
+        OpenStackVmInstance object. After the floating IP has been allocated
+        and assigned, this test will ensure that it can be accessed via SSH.
+        """
+        port_settings = PortConfig(
+            name=self.port_1_name,
+            network_name=self.pub_net_config.network_settings.name)
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings],
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name])
+
+        inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+        self.inst_creators.append(inst_creator)
+
+        # block=True will force the create() method to block until the
+        vm_inst = inst_creator.create(block=True)
+        self.assertIsNotNone(vm_inst)
+
+        self.assertTrue(inst_creator.vm_active(block=True))
+
+        vm_os_creds = OSCreds(
+            auth_url=self.admin_os_creds.auth_url,
+            username=self.admin_os_creds.username,
+            password=self.admin_os_creds.password,
+            project_name=self.os_creds.project_name,
+            identity_api_version=self.os_creds.identity_api_version)
+        derived_inst_creator = create_instance.generate_creator(
+            vm_os_creds, vm_inst, self.image_creator.image_settings,
+            self.os_creds.project_name, self.keypair_creator.keypair_settings)
+
+        # Tests to ensure that a instance can be returned with an invalid
+        # image config object and admin credentials (when the 'admin' user has
+        # been added to the project) as this should not matter unless one
+        # needs to access the machine via ssh and its floating IP
+
+        # Invalid ImageConfig
+        derived_foo_image_creator = create_instance.generate_creator(
+            vm_os_creds, vm_inst, ImageConfig(
+                name='foo', image_user='bar', format='qcow2',
+                image_file='foo/bar'),
+            vm_os_creds.project_name)
+        self.assertIsNotNone(derived_foo_image_creator)
+        self.assertTrue(derived_foo_image_creator.vm_active())
+
+        # None ImageConfig
+        derived_none_image_creator = create_instance.generate_creator(
+            vm_os_creds, vm_inst, None, vm_os_creds.project_name)
+        self.assertIsNotNone(derived_none_image_creator)
+        self.assertTrue(derived_none_image_creator.vm_active())
+
+        derived_inst_creator.add_floating_ip(FloatingIpConfig(
+            name=self.floating_ip_name, port_name=self.port_1_name,
+            router_name=self.pub_net_config.router_settings.name))
+        self.inst_creators.append(derived_inst_creator)
+
+        self.assertTrue(validate_ssh_client(
+            derived_inst_creator, fip_name=self.floating_ip_name))
+
+    def test_ssh_client_fip_second_creator(self):
+        """
+        Tests the ability to access a VM via SSH and a floating IP via a
+        creator that is identical to the original creator.
+        """
+        port_settings = PortConfig(
+            name=self.port_1_name,
+            network_name=self.pub_net_config.network_settings.name)
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings],
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
+            floating_ip_settings=[FloatingIpConfig(
+                name=self.floating_ip_name, port_name=self.port_1_name,
+                router_name=self.pub_net_config.router_settings.name)])
+
+        inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+        self.inst_creators.append(inst_creator)
+
+        # block=True will force the create() method to block until the
+        vm_inst = inst_creator.create(block=True)
+        self.assertIsNotNone(vm_inst)
+
+        self.assertTrue(inst_creator.vm_active(block=True))
+
+        ip = inst_creator.get_port_ip(port_settings.name)
+        self.assertTrue(check_dhcp_lease(inst_creator, ip))
+
+        self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
+
+        self.assertTrue(validate_ssh_client(inst_creator))
+
+        inst_creator2 = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+        inst_creator2.create()
+        self.assertTrue(validate_ssh_client(inst_creator2))
+
+
+class CreateInstanceIPv6NetworkTests(OSIntegrationTestCase):
+    """
+    Test for the CreateInstance class with a single NIC/Port with Floating IPs
+    """
+
+    def setUp(self):
+        """
+        Instantiates the CreateImage object that is responsible for downloading
+        and creating an OS image file within OpenStack
+        """
+        super(self.__class__, self).__start__()
+
+        self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
+        self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        self.keypair_priv_filepath = 'tmp/' + self.guid
+        self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
+        self.keypair_name = self.guid + '-kp'
+        self.vm_inst_name = self.guid + '-inst'
+        self.port1_name = self.guid + 'port1'
+        self.port2_name = self.guid + 'port2'
+
+        # Initialize for tearDown()
+        self.image_creator = None
+        self.network_creator = None
+        self.router_creator = None
+        self.flavor_creator = None
+        self.keypair_creator = None
+        self.sec_grp_creator = None
+        self.inst_creator = None
+
+        os_image_settings = openstack_tests.cirros_image_settings(
+            name=self.guid + '-image', image_metadata=self.image_metadata)
+        try:
+            self.image_creator = OpenStackImage(
+                self.os_creds, os_image_settings)
+            self.image_creator.create()
+
+            flavor_config = openstack_tests.get_flavor_config(
+                name=self.guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
+            self.flavor_creator = OpenStackFlavor(
+                self.admin_os_creds, flavor_config)
+            self.flavor_creator.create()
+
+            self.keypair_creator = OpenStackKeypair(
+                self.os_creds, KeypairConfig(
+                    name=self.keypair_name,
+                    public_filepath=self.keypair_pub_filepath,
+                    private_filepath=self.keypair_priv_filepath))
+            self.keypair_creator.create()
+
+            sec_grp_name = self.guid + '-sec-grp'
+            rule1 = SecurityGroupRuleConfig(
+                sec_grp_name=sec_grp_name, direction=Direction.ingress,
+                protocol=Protocol.icmp)
+            rule2 = SecurityGroupRuleConfig(
+                sec_grp_name=sec_grp_name, direction=Direction.ingress,
+                protocol=Protocol.tcp, port_range_min=22, port_range_max=22)
+            self.sec_grp_creator = OpenStackSecurityGroup(
+                self.os_creds,
+                SecurityGroupConfig(
+                    name=sec_grp_name, rule_settings=[rule1, rule2]))
+            self.sec_grp_creator.create()
+        except Exception as e:
+            self.tearDown()
+            raise e
+
+    def tearDown(self):
+        """
+        Cleans the created object
+        """
+        if self.inst_creator:
+            try:
+                self.inst_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning VM instance with message '
+                    '- %s', e)
+
+        if self.keypair_creator:
+            try:
+                self.keypair_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning keypair with message - %s',
+                    e)
+
+        if self.flavor_creator:
+            try:
+                self.flavor_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning flavor with message - %s',
+                    e)
+
+        if self.sec_grp_creator:
+            try:
+                self.sec_grp_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning security group with message'
+                    ' - %s', e)
+
+        if self.router_creator:
+            try:
+                self.router_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning router with message - %s',
+                    e)
+
+        if self.network_creator:
+            try:
+                self.network_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning network with message - %s',
+                    e)
+
+        if self.image_creator and not self.image_creator.image_settings.exists:
+            try:
+                self.image_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning image with message - %s', e)
+
+        super(self.__class__, self).__clean__()
+
+    def test_v4fip_v6overlay(self):
+        """
+        Tests the ability to assign an IPv4 floating IP to an IPv6 overlay
+        network when the external network does not have an IPv6 subnet.
+        """
+        subnet_settings = SubnetConfig(
+            name=self.guid + '-subnet', cidr='1:1:0:0:0:0:0:0/64',
+            ip_version=6)
+        network_settings = NetworkConfig(
+            name=self.guid + '-net', subnet_settings=[subnet_settings])
+        router_settings = RouterConfig(
+            name=self.guid + '-router', external_gateway=self.ext_net_name,
+            internal_subnets=[{'subnet': {
+                'project_name': self.os_creds.project_name,
+                'network_name': network_settings.name,
+                'subnet_name': subnet_settings.name}}])
+
+        # Create Network
+        self.network_creator = OpenStackNetwork(
+            self.os_creds, network_settings)
+        self.network_creator.create()
+
+        # Create Router
+        self.router_creator = OpenStackRouter(
+            self.os_creds, router_settings)
+        self.router_creator.create()
+
+        port_settings = PortConfig(
+            name=self.port1_name, network_name=network_settings.name)
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings],
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
+            floating_ip_settings=[FloatingIpConfig(
+                name='fip1', port_name=self.port1_name,
+                router_name=router_settings.name)])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+
+        with self.assertRaises(BadRequest):
+            self.inst_creator.create(block=True)
+
+    def test_fip_v4and6_overlay(self):
+        """
+        Tests the ability to assign an IPv4 floating IP to an IPv6 overlay
+        network when the external network does not have an IPv6 subnet.
+        """
+        subnet4_settings = SubnetConfig(
+            name=self.guid + '-subnet4', cidr='10.0.1.0/24',
+            ip_version=4)
+        subnet6_settings = SubnetConfig(
+            name=self.guid + '-subnet6', cidr='1:1:0:0:0:0:0:0/64',
+            ip_version=6)
+        network_settings = NetworkConfig(
+            name=self.guid + '-net',
+            subnet_settings=[subnet4_settings, subnet6_settings])
+        router_settings = RouterConfig(
+            name=self.guid + '-router', external_gateway=self.ext_net_name,
+            internal_subnets=[{'subnet': {
+                'project_name': self.os_creds.project_name,
+                'network_name': network_settings.name,
+                'subnet_name': subnet4_settings.name}}])
+
+        # Create Network
+        self.network_creator = OpenStackNetwork(
+            self.os_creds, network_settings)
+        self.network_creator.create()
+
+        # Create Router
+        self.router_creator = OpenStackRouter(
+            self.os_creds, router_settings)
+        self.router_creator.create()
+
+        port_settings = PortConfig(
+            name=self.port1_name, network_name=network_settings.name)
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings],
+            security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
+            floating_ip_settings=[FloatingIpConfig(
+                name='fip1', port_name=self.port1_name,
+                router_name=router_settings.name)])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings,
+            keypair_settings=self.keypair_creator.keypair_settings)
+
+        self.inst_creator.create(block=True)
+        self.inst_creator.cloud_init_complete(block=True)
+        ssh_client = self.inst_creator.ssh_client()
+        self.assertIsNotNone(ssh_client)
+
+
+class CreateInstancePortManipulationTests(OSIntegrationTestCase):
+    """
+    Test for the CreateInstance class with a single NIC/Port where mac and IP
+    values are manually set
+    """
+
+    def setUp(self):
+        """
+        Instantiates the CreateImage object that is responsible for downloading
+        and creating an OS image file within OpenStack
+        """
+        super(self.__class__, self).__start__()
+
+        self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        self.vm_inst_name = self.guid + '-inst'
+        self.port_1_name = self.guid + 'port-1'
+        self.port_2_name = self.guid + 'port-2'
+        self.floating_ip_name = self.guid + 'fip1'
+
+        # Initialize for tearDown()
+        self.image_creator = None
+        self.network_creator = None
+        self.network_creator2 = None
+        self.flavor_creator = None
+        self.inst_creator = None
+
+        self.net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
+            net_name=self.guid + '-pub-net',
+            subnet_name=self.guid + '-pub-subnet',
+            router_name=self.guid + '-pub-router',
+            external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
+        os_image_settings = openstack_tests.cirros_image_settings(
+            name=self.guid + '-image', image_metadata=self.image_metadata)
+
+        try:
+            # Create Image
+            self.image_creator = OpenStackImage(self.os_creds,
+                                                os_image_settings)
+            self.image_creator.create()
+
+            # Create Network
+            self.network_creator = OpenStackNetwork(
+                self.os_creds, self.net_config.network_settings)
+            self.network_creator.create()
+
+            # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=self.guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
+            self.flavor_creator = OpenStackFlavor(
+                self.admin_os_creds, flavor_config)
+            self.flavor_creator.create()
+        except Exception as e:
+            self.tearDown()
+            raise e
+
+    def tearDown(self):
+        """
+        Cleans the created object
+        """
+        if self.inst_creator:
+            try:
+                self.inst_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning VM instance with message '
+                    '- %s', e)
+
+        if self.flavor_creator:
+            try:
+                self.flavor_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning flavor with message - %s',
+                    e)
+
+        if self.network_creator:
+            try:
+                self.network_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning network with message - %s',
+                    e)
+
+        if self.network_creator2:
+            try:
+                self.network_creator2.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning network with message - %s',
+                    e)
+
+        if self.image_creator and not self.image_creator.image_settings.exists:
+            try:
+                self.image_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning image with message - %s', e)
+
+        super(self.__class__, self).__clean__()
+
+    def test_set_custom_valid_ip_one_subnet(self):
+        """
+        Tests the creation of an OpenStack instance with a single port with a
         static IP on a network with one subnet.
         """
         ip = '10.55.0.101'
         sub_settings = self.net_config.network_settings.subnet_settings
         static IP on a network with one subnet.
         """
         ip = '10.55.0.101'
         sub_settings = self.net_config.network_settings.subnet_settings
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -859,6 +1499,86 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
             subnet_name=self.net_config.network_settings.subnet_settings[
                 0].name))
 
             subnet_name=self.net_config.network_settings.subnet_settings[
                 0].name))
 
+    def test_set_one_port_two_ip_one_subnet(self):
+        """
+        Tests the creation of an OpenStack instance with a single port with a
+        two static IPs on a network with one subnet.
+        """
+        ip1 = '10.55.0.101'
+        ip2 = '10.55.0.102'
+        sub_settings = self.net_config.network_settings.subnet_settings
+        port_settings = PortConfig(
+            name=self.port_1_name,
+            network_name=self.net_config.network_settings.name,
+            ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip1},
+                      {'subnet_name': sub_settings[0].name, 'ip': ip2}])
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings)
+        vm_inst = self.inst_creator.create(block=True)
+
+        self.assertEqual(ip1, vm_inst.ports[0].ips[0]['ip_address'])
+        self.assertEqual(self.network_creator.get_network().subnets[0].id,
+                         vm_inst.ports[0].ips[0]['subnet_id'])
+        self.assertEqual(ip2, vm_inst.ports[0].ips[1]['ip_address'])
+        self.assertEqual(self.network_creator.get_network().subnets[0].id,
+                         vm_inst.ports[0].ips[1]['subnet_id'])
+
+    def test_set_one_port_two_ip_two_subnets(self):
+        """
+        Tests the creation of an OpenStack instance with a single port with a
+        two static IPs on a network with one subnet.
+        """
+        net2_config = NetworkConfig(
+            name=self.guid + 'net2', subnets=[
+                SubnetConfig(name=self.guid + '-subnet1', cidr='10.55.0.0/24'),
+                SubnetConfig(name=self.guid + '-subnet2', cidr='10.65.0.0/24'),
+            ])
+
+        # Create Network
+        self.network_creator2 = OpenStackNetwork(self.os_creds, net2_config)
+        net2 = self.network_creator2.create()
+
+        ip1 = '10.55.0.101'
+        ip2 = '10.65.0.101'
+
+        port_settings = PortConfig(
+            name=self.port_1_name,
+            network_name=net2_config.name,
+            ip_addrs=[
+                {'subnet_name': net2_config.subnet_settings[0].name,
+                 'ip': ip1},
+                {'subnet_name': net2_config.subnet_settings[1].name,
+                 'ip': ip2}])
+
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[port_settings])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings)
+        vm_inst = self.inst_creator.create(block=True)
+
+        subnet1_id = None
+        subnet2_id = None
+        for subnet in net2.subnets:
+            if subnet.name == net2_config.subnet_settings[0].name:
+                subnet1_id = subnet.id
+            if subnet.name == net2_config.subnet_settings[1].name:
+                subnet2_id = subnet.id
+        self.assertEqual(ip1, vm_inst.ports[0].ips[0]['ip_address'])
+        self.assertEqual(subnet1_id, vm_inst.ports[0].ips[0]['subnet_id'])
+        self.assertEqual(ip2, vm_inst.ports[0].ips[1]['ip_address'])
+        self.assertEqual(subnet2_id, vm_inst.ports[0].ips[1]['subnet_id'])
+
     def test_set_custom_invalid_ip_one_subnet(self):
         """
         Tests the creation of an OpenStack instance with a single port with a
     def test_set_custom_invalid_ip_one_subnet(self):
         """
         Tests the creation of an OpenStack instance with a single port with a
@@ -866,12 +1586,12 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         """
         ip = '10.66.0.101'
         sub_settings = self.net_config.network_settings.subnet_settings
         """
         ip = '10.66.0.101'
         sub_settings = self.net_config.network_settings.subnet_settings
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -880,7 +1600,7 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
             self.os_creds, instance_settings,
             self.image_creator.image_settings)
 
             self.os_creds, instance_settings,
             self.image_creator.image_settings)
 
-        with self.assertRaises(Exception):
+        with self.assertRaises(InvalidIpForSubnetClient):
             self.inst_creator.create()
 
     def test_set_custom_valid_mac(self):
             self.inst_creator.create()
 
     def test_set_custom_valid_mac(self):
@@ -889,12 +1609,12 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         the MAC address is assigned.
         """
         mac_addr = '0a:1b:2c:3d:4e:5f'
         the MAC address is assigned.
         """
         mac_addr = '0a:1b:2c:3d:4e:5f'
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             mac_address=mac_addr)
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             mac_address=mac_addr)
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -913,12 +1633,12 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         invalid MAC address value is being
         assigned. This should raise an Exception
         """
         invalid MAC address value is being
         assigned. This should raise an Exception
         """
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             mac_address='foo')
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             mac_address='foo')
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -938,13 +1658,13 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         ip = '10.55.0.101'
         mac_addr = '0a:1b:2c:3d:4e:5f'
         sub_settings = self.net_config.network_settings.subnet_settings
         ip = '10.55.0.101'
         mac_addr = '0a:1b:2c:3d:4e:5f'
         sub_settings = self.net_config.network_settings.subnet_settings
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             mac_address=mac_addr,
             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             mac_address=mac_addr,
             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -969,12 +1689,12 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         ip = '10.55.0.101'
         mac_addr = '0a:1b:2c:3d:4e:5f'
         pair = {'ip_address': ip, 'mac_address': mac_addr}
         ip = '10.55.0.101'
         mac_addr = '0a:1b:2c:3d:4e:5f'
         pair = {'ip_address': ip, 'mac_address': mac_addr}
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             allowed_address_pairs=[pair])
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             allowed_address_pairs=[pair])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -986,10 +1706,10 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
 
         port = self.inst_creator.get_port_by_name(port_settings.name)
         self.assertIsNotNone(port)
 
         port = self.inst_creator.get_port_by_name(port_settings.name)
         self.assertIsNotNone(port)
-        self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
-        self.assertEqual(1, len(port['port']['allowed_address_pairs']))
-        validation_utils.objects_equivalent(pair, port['port'][
-            'allowed_address_pairs'][0])
+        self.assertIsNotNone(port.allowed_address_pairs)
+        self.assertEqual(1, len(port.allowed_address_pairs))
+        validation_utils.objects_equivalent(pair,
+                                            port.allowed_address_pairs[0])
 
     def test_set_allowed_address_pairs_bad_mac(self):
         """
 
     def test_set_allowed_address_pairs_bad_mac(self):
         """
@@ -1001,12 +1721,12 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         pair = {'ip_address': ip, 'mac_address': mac_addr}
         pairs = set()
         pairs.add((ip, mac_addr))
         pair = {'ip_address': ip, 'mac_address': mac_addr}
         pairs = set()
         pairs.add((ip, mac_addr))
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             allowed_address_pairs=[pair])
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             allowed_address_pairs=[pair])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -1027,12 +1747,12 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         pair = {'ip_address': ip, 'mac_address': mac_addr}
         pairs = set()
         pairs.add((ip, mac_addr))
         pair = {'ip_address': ip, 'mac_address': mac_addr}
         pairs = set()
         pairs.add((ip, mac_addr))
-        port_settings = PortSettings(
+        port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             allowed_address_pairs=[pair])
 
             name=self.port_1_name,
             network_name=self.net_config.network_settings.name,
             allowed_address_pairs=[pair])
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[port_settings])
@@ -1067,7 +1787,9 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase):
         self.inst_creators = list()
 
         self.priv_net_config = openstack_tests.get_priv_net_config(
         self.inst_creators = list()
 
         self.priv_net_config = openstack_tests.get_priv_net_config(
-            net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
+            project_name=self.os_creds.project_name,
+            net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet',
+            netconf_override=self.netconf_override)
 
         os_image_settings = openstack_tests.cirros_image_settings(
             name=guid + '-image', image_metadata=self.image_metadata)
 
         os_image_settings = openstack_tests.cirros_image_settings(
             name=guid + '-image', image_metadata=self.image_metadata)
@@ -1079,10 +1801,11 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase):
             self.network_creator.create()
 
             # Create Flavor
             self.network_creator.create()
 
             # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=guid + '-flavor-name', ram=512, disk=1,
+                vcpus=1, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1,
-                               vcpus=1, metadata=self.flavor_metadata))
+                self.admin_os_creds, flavor_config)
             self.flavor_creator.create()
 
             # Create Image
             self.flavor_creator.create()
 
             # Create Image
@@ -1136,19 +1859,20 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase):
         Tests the creation of OpenStack VM instances to each compute node.
         """
         from snaps.openstack.utils import nova_utils
         Tests the creation of OpenStack VM instances to each compute node.
         """
         from snaps.openstack.utils import nova_utils
-        nova = nova_utils.nova_client(self.admin_os_creds)
-        zones = nova_utils.get_nova_availability_zones(nova)
+        nova = nova_utils.nova_client(
+            self.admin_os_creds, self.admin_os_session)
+        zone_hosts = nova_utils.get_availability_zone_hosts(nova)
 
         # Create Instance on each server/zone
         ctr = 0
 
         # Create Instance on each server/zone
         ctr = 0
-        for zone in zones:
+        for zone in zone_hosts:
             inst_name = self.vm_inst_name + '-' + zone
             ctr += 1
             inst_name = self.vm_inst_name + '-' + zone
             ctr += 1
-            port_settings = PortSettings(
+            port_settings = PortConfig(
                 name=self.port_base_name + '-' + str(ctr),
                 network_name=self.priv_net_config.network_settings.name)
 
                 name=self.port_base_name + '-' + str(ctr),
                 network_name=self.priv_net_config.network_settings.name)
 
-            instance_settings = VmInstanceSettings(
+            instance_settings = VmInstanceConfig(
                 name=inst_name,
                 flavor=self.flavor_creator.flavor_settings.name,
                 availability_zone=zone,
                 name=inst_name,
                 flavor=self.flavor_creator.flavor_settings.name,
                 availability_zone=zone,
@@ -1157,256 +1881,25 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase):
                 self.admin_os_creds, instance_settings,
                 self.image_creator.image_settings)
             self.inst_creators.append(inst_creator)
                 self.admin_os_creds, instance_settings,
                 self.image_creator.image_settings)
             self.inst_creators.append(inst_creator)
-            inst_creator.create()
+            inst_creator.create(block=True)
+            avail_zone = inst_creator.get_vm_inst().availability_zone
+            self.assertTrue(avail_zone in zone)
+            compute_host = inst_creator.get_vm_inst().compute_host
+            self.assertTrue(compute_host in zone)
 
         # Validate instances to ensure they've been deployed to the correct
         # server
         index = 0
 
         # Validate instances to ensure they've been deployed to the correct
         # server
         index = 0
-        for zone in zones:
+        for zone in zone_hosts:
             creator = self.inst_creators[index]
             self.assertTrue(creator.vm_active(block=True))
             creator = self.inst_creators[index]
             self.assertTrue(creator.vm_active(block=True))
-            vm = creator.get_vm_inst()
-            deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
-            deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
+            info = creator.get_vm_info()
+            deployed_zone = info['OS-EXT-AZ:availability_zone']
+            deployed_host = info['OS-EXT-SRV-ATTR:host']
             self.assertEqual(zone, deployed_zone + ':' + deployed_host)
             index += 1
 
 
             self.assertEqual(zone, deployed_zone + ':' + deployed_host)
             index += 1
 
 
-class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
-    """
-    Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP
-    and eth1 w/o.
-    These tests require a Centos image
-    """
-
-    def setUp(self):
-        """
-        Instantiates the CreateImage object that is responsible for downloading
-        and creating an OS image file within OpenStack
-        """
-        super(self.__class__, self).__start__()
-
-        # Initialize for tearDown()
-        self.image_creator = None
-        self.network_creators = list()
-        self.router_creators = list()
-        self.flavor_creator = None
-        self.keypair_creator = None
-        self.sec_grp_creator = None
-        self.inst_creator = None
-
-        self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
-        self.keypair_priv_filepath = 'tmp/' + self.guid
-        self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
-        self.keypair_name = self.guid + '-kp'
-        self.vm_inst_name = self.guid + '-inst'
-        self.port_1_name = self.guid + '-port-1'
-        self.port_2_name = self.guid + '-port-2'
-        self.floating_ip_name = self.guid + 'fip1'
-        self.priv_net_config = openstack_tests.get_priv_net_config(
-            net_name=self.guid + '-priv-net',
-            subnet_name=self.guid + '-priv-subnet',
-            router_name=self.guid + '-priv-router',
-            external_net=self.ext_net_name)
-        self.pub_net_config = openstack_tests.get_pub_net_config(
-            net_name=self.guid + '-pub-net',
-            subnet_name=self.guid + '-pub-subnet',
-            router_name=self.guid + '-pub-router',
-            external_net=self.ext_net_name)
-
-        image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
-        os_image_settings = openstack_tests.centos_image_settings(
-            name=image_name, image_metadata=self.image_metadata)
-
-        try:
-            # Create Image
-            self.image_creator = OpenStackImage(self.os_creds,
-                                                os_image_settings)
-            self.image_creator.create()
-
-            # First network is public
-            self.network_creators.append(OpenStackNetwork(
-                self.os_creds, self.pub_net_config.network_settings))
-            # Second network is private
-            self.network_creators.append(OpenStackNetwork(
-                self.os_creds, self.priv_net_config.network_settings))
-            for network_creator in self.network_creators:
-                network_creator.create()
-
-            self.router_creators.append(OpenStackRouter(
-                self.os_creds, self.pub_net_config.router_settings))
-            self.router_creators.append(OpenStackRouter(
-                self.os_creds, self.priv_net_config.router_settings))
-
-            # Create Routers
-            for router_creator in self.router_creators:
-                router_creator.create()
-
-            # Create Flavor
-            self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=self.guid + '-flavor-name', ram=512,
-                               disk=10, vcpus=2,
-                               metadata=self.flavor_metadata))
-            self.flavor_creator.create()
-
-            # Create Keypair
-            self.keypair_creator = OpenStackKeypair(
-                self.os_creds, KeypairSettings(
-                    name=self.keypair_name,
-                    public_filepath=self.keypair_pub_filepath,
-                    private_filepath=self.keypair_priv_filepath))
-            self.keypair_creator.create()
-
-            sec_grp_name = self.guid + '-sec-grp'
-            rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
-                                              direction=Direction.ingress,
-                                              protocol=Protocol.icmp)
-            rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
-                                              direction=Direction.ingress,
-                                              protocol=Protocol.tcp,
-                                              port_range_min=22,
-                                              port_range_max=22)
-            self.sec_grp_creator = OpenStackSecurityGroup(
-                self.os_creds,
-                SecurityGroupSettings(name=sec_grp_name,
-                                      rule_settings=[rule1, rule2]))
-            self.sec_grp_creator.create()
-        except Exception as e:
-            self.tearDown()
-            raise Exception(str(e))
-
-    def tearDown(self):
-        """
-        Cleans the created objects
-        """
-        if self.inst_creator:
-            try:
-                self.inst_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning VM instance with message '
-                    '- %s', e)
-
-        if self.keypair_creator:
-            try:
-                self.keypair_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning keypair with message - %s',
-                    e)
-
-        if os.path.isfile(self.keypair_pub_filepath):
-            os.remove(self.keypair_pub_filepath)
-
-        if os.path.isfile(self.keypair_priv_filepath):
-            os.remove(self.keypair_priv_filepath)
-
-        if self.flavor_creator:
-            try:
-                self.flavor_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning flavor with message - %s',
-                    e)
-
-        for router_creator in self.router_creators:
-            try:
-                router_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning router with message - %s',
-                    e)
-
-        for network_creator in self.network_creators:
-            try:
-                network_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning network with message - %s',
-                    e)
-
-        if self.sec_grp_creator:
-            try:
-                self.sec_grp_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning security group with message'
-                    ' - %s', e)
-
-        if self.image_creator and not self.image_creator.image_settings.exists:
-            try:
-                self.image_creator.clean()
-            except Exception as e:
-                logger.error(
-                    'Unexpected exception cleaning image with message - %s', e)
-
-        super(self.__class__, self).__clean__()
-
-    def test_dual_ports_dhcp(self):
-        """
-        Tests the creation of an OpenStack instance with a dual ports/NICs with
-        a DHCP assigned IP.
-        NOTE: This test and any others that call ansible will most likely fail
-        unless you do one of two things:
-        1. Have a ~/.ansible.cfg (or alternate means) to
-           set host_key_checking = False
-        2. Set the following environment variable in your executing shell:
-           ANSIBLE_HOST_KEY_CHECKING=False
-        Should this not be performed, the creation of the host ssh key will
-        cause your ansible calls to fail.
-        """
-        # Create ports/NICs for instance
-        ports_settings = []
-        ctr = 1
-        for network_creator in self.network_creators:
-            ports_settings.append(PortSettings(
-                name=self.guid + '-port-' + str(ctr),
-                network_name=network_creator.network_settings.name))
-            ctr += 1
-
-        # Create instance
-        instance_settings = VmInstanceSettings(
-            name=self.vm_inst_name,
-            flavor=self.flavor_creator.flavor_settings.name,
-            port_settings=ports_settings,
-            floating_ip_settings=[FloatingIpSettings(
-                name=self.floating_ip_name, port_name=self.port_1_name,
-                router_name=self.pub_net_config.router_settings.name)])
-
-        self.inst_creator = OpenStackVmInstance(
-            self.os_creds, instance_settings,
-            self.image_creator.image_settings,
-            keypair_settings=self.keypair_creator.keypair_settings)
-
-        vm_inst = self.inst_creator.create(block=True)
-
-        self.assertEqual(vm_inst, self.inst_creator.get_vm_inst())
-
-        # Effectively blocks until VM has been properly activated
-        self.assertTrue(self.inst_creator.vm_active(block=True))
-
-        ip = self.inst_creator.get_port_ip(ports_settings[0].name)
-        self.assertTrue(check_dhcp_lease(vm_inst, ip))
-
-        # Add security group to VM
-        self.inst_creator.add_security_group(
-            self.sec_grp_creator.get_security_group())
-
-        # Effectively blocks until VM's ssh port has been opened
-        self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
-
-        # TODO - Refactor config_nics() to return a status that can be
-        # validated here.
-        self.inst_creator.config_nics()
-
-        # TODO - *** ADD VALIDATION HERE ***
-        # TODO - Add validation that both floating IPs work
-        # TODO - Add tests where only one NIC has a floating IP
-        # TODO - Add tests where one attempts to place a floating IP on a
-        # network/router without an external gateway
-
-
 class InstanceSecurityGroupTests(OSIntegrationTestCase):
     """
     Tests that include, add, and remove security groups from VM instances
 class InstanceSecurityGroupTests(OSIntegrationTestCase):
     """
     Tests that include, add, and remove security groups from VM instances
@@ -1421,7 +1914,7 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
 
         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.vm_inst_name = self.guid + '-inst'
 
         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.vm_inst_name = self.guid + '-inst'
-        self.nova = nova_utils.nova_client(self.os_creds)
+        self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
         os_image_settings = openstack_tests.cirros_image_settings(
             name=self.guid + '-image', image_metadata=self.image_metadata)
 
         os_image_settings = openstack_tests.cirros_image_settings(
             name=self.guid + '-image', image_metadata=self.image_metadata)
 
@@ -1431,10 +1924,12 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.floating_ip_name = self.guid + 'fip1'
 
         net_config = openstack_tests.get_priv_net_config(
         self.floating_ip_name = self.guid + 'fip1'
 
         net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
             net_name=self.guid + '-pub-net',
             subnet_name=self.guid + '-pub-subnet',
             router_name=self.guid + '-pub-router',
             net_name=self.guid + '-pub-net',
             subnet_name=self.guid + '-pub-subnet',
             router_name=self.guid + '-pub-router',
-            external_net=self.ext_net_name)
+            external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
 
         # Initialize for tearDown()
         self.image_creator = None
 
         # Initialize for tearDown()
         self.image_creator = None
@@ -1456,14 +1951,14 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
             self.network_creator.create()
 
             # Create Flavor
             self.network_creator.create()
 
             # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=self.guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=self.guid + '-flavor-name', ram=128,
-                               disk=10, vcpus=2,
-                               metadata=self.flavor_metadata))
+                self.admin_os_creds, flavor_config)
             self.flavor_creator.create()
 
             self.flavor_creator.create()
 
-            self.port_settings = PortSettings(
+            self.port_settings = PortConfig(
                 name=self.guid + '-port',
                 network_name=net_config.network_settings.name)
         except Exception as e:
                 name=self.guid + '-port',
                 network_name=net_config.network_settings.name)
         except Exception as e:
@@ -1520,7 +2015,7 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         Tests the addition of a security group created after the instance.
         """
         # Create instance
         Tests the addition of a security group created after the instance.
         """
         # Create instance
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -1531,30 +2026,30 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
-        sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
-                                                 description='hello group')
+        sec_grp_settings = SecurityGroupConfig(
+            name=self.guid + '-name', description='hello group')
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Check that group has not been added
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Check that group has not been added
-        self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                          sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
         # Add security group to instance after activated
         self.inst_creator.add_security_group(sec_grp)
 
         # Validate that security group has been added
 
         # Add security group to instance after activated
         self.inst_creator.add_security_group(sec_grp)
 
         # Validate that security group has been added
-        self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                         sec_grp_settings.name))
+        self.assertTrue(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
     def test_add_invalid_security_group(self):
         """
         Tests the addition of a security group that no longer exists.
         """
         # Create instance
 
     def test_add_invalid_security_group(self):
         """
         Tests the addition of a security group that no longer exists.
         """
         # Create instance
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -1565,8 +2060,8 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
-        sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
-                                                 description='hello group')
+        sec_grp_settings = SecurityGroupConfig(
+            name=self.guid + '-name', description='hello group')
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
@@ -1574,15 +2069,15 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Check that group has not been added
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Check that group has not been added
-        self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                          sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
         # Add security group to instance after activated
         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
 
         # Validate that security group has been added
 
         # Add security group to instance after activated
         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
 
         # Validate that security group has been added
-        self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                          sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
     def test_remove_security_group(self):
         """
 
     def test_remove_security_group(self):
         """
@@ -1590,15 +2085,15 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         instance.
         """
         # Create security group object to add to instance
         instance.
         """
         # Create security group object to add to instance
-        sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
-                                                 description='hello group')
+        sec_grp_settings = SecurityGroupConfig(
+            name=self.guid + '-name', description='hello group')
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Create instance
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Create instance
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             security_group_names=[sec_grp_settings.name],
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             security_group_names=[sec_grp_settings.name],
@@ -1610,14 +2105,15 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
-        self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
+        self.assertTrue(inst_has_sec_grp(
+            self.nova, vm_inst, sec_grp_settings.name))
 
         # Add security group to instance after activated
         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
 
         # Validate that security group has been added
 
         # Add security group to instance after activated
         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
 
         # Validate that security group has been added
-        self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                          sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
     def test_remove_security_group_never_added(self):
         """
 
     def test_remove_security_group_never_added(self):
         """
@@ -1625,15 +2121,15 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         place.
         """
         # Create security group object to add to instance
         place.
         """
         # Create security group object to add to instance
-        sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
-                                                 description='hello group')
+        sec_grp_settings = SecurityGroupConfig(
+            name=self.guid + '-name', description='hello group')
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Create instance
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Create instance
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -1644,15 +2140,15 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
-        self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                          sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
         # Add security group to instance after activated
         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
 
         # Validate that security group has been added
 
         # Add security group to instance after activated
         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
 
         # Validate that security group has been added
-        self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                          sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
     def test_add_same_security_group(self):
         """
 
     def test_add_same_security_group(self):
         """
@@ -1660,15 +2156,15 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         instance.
         """
         # Create security group object to add to instance
         instance.
         """
         # Create security group object to add to instance
-        sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
-                                                 description='hello group')
+        sec_grp_settings = SecurityGroupConfig(
+            name=self.guid + '-name', description='hello group')
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Create instance
         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
                                                  sec_grp_settings)
         sec_grp = sec_grp_creator.create()
         self.sec_grp_creators.append(sec_grp_creator)
 
         # Create instance
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             security_group_names=[sec_grp_settings.name],
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             security_group_names=[sec_grp_settings.name],
@@ -1680,56 +2176,58 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
-        self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                         sec_grp_settings.name))
+        self.assertTrue(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
         # Add security group to instance after activated
         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
 
         # Validate that security group has been added
 
         # Add security group to instance after activated
         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
 
         # Validate that security group has been added
-        self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(),
-                                         sec_grp_settings.name))
+        self.assertTrue(inst_has_sec_grp(
+            self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
 
 
 
 
-def inst_has_sec_grp(vm_inst, sec_grp_name):
+def inst_has_sec_grp(nova, vm_inst, sec_grp_name):
     """
     Returns true if instance has a security group of a given name
     """
     Returns true if instance has a security group of a given name
-    :return:
+    :param nova: the nova client
+    :param vm_inst: the VmInst domain object
+    :param sec_grp_name: the name of the security group to validate
+    :return: T/F
     """
     """
-    if not hasattr(vm_inst, 'security_groups'):
-        return False
-
-    found = False
-    for sec_grp_dict in vm_inst.security_groups:
-        if sec_grp_name in sec_grp_dict['name']:
-            found = True
-            break
-    return found
+    sec_grp_names = nova_utils.get_server_security_group_names(nova, vm_inst)
+    for name in sec_grp_names:
+        if sec_grp_name == name:
+            return True
+    return False
 
 
 
 
-def validate_ssh_client(instance_creator):
+def validate_ssh_client(instance_creator, fip_name=None):
     """
     Returns True if instance_creator returns an SSH client that is valid
     :param instance_creator: the object responsible for creating the VM
                              instance
     """
     Returns True if instance_creator returns an SSH client that is valid
     :param instance_creator: the object responsible for creating the VM
                              instance
+    :param fip_name: the name of the floating IP to use
     :return: T/F
     """
     ssh_active = instance_creator.vm_ssh_active(block=True)
 
     if ssh_active:
     :return: T/F
     """
     ssh_active = instance_creator.vm_ssh_active(block=True)
 
     if ssh_active:
-        ssh_client = instance_creator.ssh_client()
+        ssh_client = instance_creator.ssh_client(fip_name=fip_name)
         if ssh_client:
         if ssh_client:
-            out = ssh_client.exec_command('pwd')[1]
+            try:
+                out = ssh_client.exec_command('pwd')[1]
+                channel = out.channel
+                in_buffer = channel.in_buffer
+                pwd_out = in_buffer.read(1024)
+                if not pwd_out or len(pwd_out) < 10:
+                    return False
+                return True
+            finally:
+                ssh_client.close()
         else:
             return False
 
         else:
             return False
 
-        channel = out.channel
-        in_buffer = channel.in_buffer
-        pwd_out = in_buffer.read(1024)
-        if not pwd_out or len(pwd_out) < 10:
-            return False
-        return True
-
     return False
 
 
     return False
 
 
@@ -1748,11 +2246,13 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.image_name = guid
         self.vm_inst_name = guid + '-inst'
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.image_name = guid
         self.vm_inst_name = guid + '-inst'
-        self.nova = nova_utils.nova_client(self.os_creds)
+        self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
 
         net_config = openstack_tests.get_priv_net_config(
 
         net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
-            router_name=guid + '-pub-router', external_net=self.ext_net_name)
+            router_name=guid + '-pub-router', external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
 
         # Initialize for tearDown()
         self.image_creator = None
 
         # Initialize for tearDown()
         self.image_creator = None
@@ -1788,10 +2288,11 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
             self.image_creator.create()
 
             # Create Flavor
             self.image_creator.create()
 
             # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10,
-                               vcpus=2, metadata=self.flavor_metadata))
+                self.admin_os_creds, flavor_config)
             self.flavor_creator.create()
 
             # Create Network
             self.flavor_creator.create()
 
             # Create Network
@@ -1799,7 +2300,7 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
                 self.os_creds, net_config.network_settings)
             self.network_creator.create()
 
                 self.os_creds, net_config.network_settings)
             self.network_creator.create()
 
-            self.port_settings = PortSettings(
+            self.port_settings = PortConfig(
                 name=guid + '-port',
                 network_name=net_config.network_settings.name)
         except Exception as e:
                 name=guid + '-port',
                 network_name=net_config.network_settings.name)
         except Exception as e:
@@ -1847,7 +2348,7 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
         """
         Tests the creation of an OpenStack instance from a 3-part image.
         """
         """
         Tests the creation of an OpenStack instance from a 3-part image.
         """
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -1892,9 +2393,10 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.inst_creator = None
 
         self.priv_net_config = openstack_tests.get_priv_net_config(
         self.inst_creator = None
 
         self.priv_net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
             net_name=self.guid + '-priv-net',
             subnet_name=self.guid + '-priv-subnet')
             net_name=self.guid + '-priv-net',
             subnet_name=self.guid + '-priv-subnet')
-        self.port_settings = PortSettings(
+        self.port_settings = PortConfig(
             name=self.port_1_name,
             network_name=self.priv_net_config.network_settings.name)
 
             name=self.port_1_name,
             network_name=self.priv_net_config.network_settings.name)
 
@@ -1909,11 +2411,11 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
             self.network_creator.create()
 
             # Create Flavor
             self.network_creator.create()
 
             # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=self.guid + '-flavor-name', ram=256, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
             self.flavor_creator = OpenStackFlavor(
             self.flavor_creator = OpenStackFlavor(
-                self.os_creds,
-                FlavorSettings(
-                    name=self.guid + '-flavor-name', ram=128, disk=10,
-                    vcpus=1))
+                self.os_creds, flavor_config)
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
@@ -1957,6 +2459,8 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir):
             shutil.rmtree(self.tmpDir)
 
         if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir):
             shutil.rmtree(self.tmpDir)
 
+        super(self.__class__, self).__clean__()
+
     def test_inst_from_file_image_simple_flat(self):
         """
         Creates a VM instance from a locally sourced file image using simply
     def test_inst_from_file_image_simple_flat(self):
         """
         Creates a VM instance from a locally sourced file image using simply
@@ -1982,7 +2486,7 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
         self.image_creator.create()
 
         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
         self.image_creator.create()
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2018,7 +2522,7 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
         self.image_creator.create()
 
         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
         self.image_creator.create()
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2043,14 +2547,14 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         image_settings = self.image_creator.image_settings
         test_image_creator = OpenStackImage(
             self.os_creds,
         image_settings = self.image_creator.image_settings
         test_image_creator = OpenStackImage(
             self.os_creds,
-            ImageSettings(name=image_settings.name,
-                          image_user=image_settings.image_user,
-                          exists=True))
+            ImageConfig(
+                name=image_settings.name, image_user=image_settings.image_user,
+                exists=True))
         test_image_creator.create()
         self.assertEqual(self.image_creator.get_image().id,
                          test_image_creator.get_image().id)
 
         test_image_creator.create()
         self.assertEqual(self.image_creator.get_image().id,
                          test_image_creator.get_image().id)
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2075,17 +2579,17 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.image_creator.create()
 
         metadata = {
         self.image_creator.create()
 
         metadata = {
-            'cirros':
-                {'config':
-                     {'name': os_image_settings.name,
-                      'image_user': os_image_settings.image_user,
-                      'exists': True}}}
+            'cirros': {
+                'config': {
+                    'name': os_image_settings.name,
+                    'image_user': os_image_settings.image_user,
+                    'exists': True}}}
         test_image_settings = openstack_tests.cirros_image_settings(
             image_metadata=metadata)
         test_image = OpenStackImage(self.os_creds, test_image_settings)
         test_image.create()
 
         test_image_settings = openstack_tests.cirros_image_settings(
             image_metadata=metadata)
         test_image = OpenStackImage(self.os_creds, test_image_settings)
         test_image.create()
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2110,22 +2614,22 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
 
         metadata = {
             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
 
         metadata = {
-            'cirros':
-                {'config':
-                     {'name': self.image_name,
-                      'image_user': openstack_tests.CIRROS_USER,
-                      'image_file': self.image_file.name,
-                      'format': openstack_tests.DEFAULT_IMAGE_FORMAT,
-                      'kernel_image_settings':
-                          {'name': self.image_name + '-kernel',
-                           'image_user': openstack_tests.CIRROS_USER,
-                           'image_file': kernel_file.name,
-                           'format': openstack_tests.DEFAULT_IMAGE_FORMAT},
-                      'ramdisk_image_settings':
-                          {'name': self.image_name + '-ramdisk',
-                           'image_user': openstack_tests.CIRROS_USER,
-                           'image_file': ramdisk_file.name,
-                           'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}}
+            'cirros': {
+                'config': {
+                    'name': self.image_name,
+                    'image_user': openstack_tests.CIRROS_USER,
+                    'image_file': self.image_file.name,
+                    'format': openstack_tests.DEFAULT_IMAGE_FORMAT,
+                    'kernel_image_settings': {
+                        'name': self.image_name + '-kernel',
+                        'image_user': openstack_tests.CIRROS_USER,
+                        'image_file': kernel_file.name,
+                        'format': openstack_tests.DEFAULT_IMAGE_FORMAT},
+                    'ramdisk_image_settings': {
+                        'name': self.image_name + '-ramdisk',
+                        'image_user': openstack_tests.CIRROS_USER,
+                        'image_file': ramdisk_file.name,
+                        'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}}
 
         os_image_settings = openstack_tests.cirros_image_settings(
             name=self.image_name, image_metadata=metadata)
 
         os_image_settings = openstack_tests.cirros_image_settings(
             name=self.image_name, image_metadata=metadata)
@@ -2165,7 +2669,7 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
         self.image_creator.create()
 
         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
         self.image_creator.create()
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2235,7 +2739,7 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.assertIsNotNone(self.image_creator.get_kernel_image())
         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
 
         self.assertIsNotNone(self.image_creator.get_kernel_image())
         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2305,7 +2809,7 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.assertIsNotNone(self.image_creator.get_kernel_image())
         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
 
         self.assertIsNotNone(self.image_creator.get_kernel_image())
         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2338,14 +2842,14 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         image_settings = self.image_creator.image_settings
         test_image_creator = OpenStackImage(
             self.os_creds,
         image_settings = self.image_creator.image_settings
         test_image_creator = OpenStackImage(
             self.os_creds,
-            ImageSettings(name=image_settings.name,
-                          image_user=image_settings.image_user,
-                          exists=True))
+            ImageConfig(
+                name=image_settings.name, image_user=image_settings.image_user,
+                exists=True))
         test_image_creator.create()
         self.assertEqual(self.image_creator.get_image().id,
                          test_image_creator.get_image().id)
 
         test_image_creator.create()
         self.assertEqual(self.image_creator.get_image().id,
                          test_image_creator.get_image().id)
 
-        instance_settings = VmInstanceSettings(
+        instance_settings = VmInstanceConfig(
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
             name=self.vm_inst_name,
             flavor=self.flavor_creator.flavor_settings.name,
             port_settings=[self.port_settings])
@@ -2357,10 +2861,424 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase):
         self.assertTrue(self.inst_creator.vm_active(block=True))
 
 
         self.assertTrue(self.inst_creator.vm_active(block=True))
 
 
-def check_dhcp_lease(vm, ip, timeout=160):
+class CreateInstanceTwoNetTests(OSIntegrationTestCase):
+    """
+    Tests the ability of two VMs to communicate when attached to separate
+    private networks that are tied together with a router.
+    """
+
+    def setUp(self):
+        """
+        Instantiates the CreateImage object that is responsible for downloading
+        and creating an OS image file within OpenStack
+        """
+        super(self.__class__, self).__start__()
+
+        cidr1 = '10.200.201.0/24'
+        cidr2 = '10.200.202.0/24'
+        static_gateway_ip1 = '10.200.201.1'
+        static_gateway_ip2 = '10.200.202.1'
+        self.ip1 = '10.200.201.5'
+        self.ip2 = '10.200.202.5'
+
+        self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
+
+        # Initialize for tearDown()
+        self.image_creator = None
+        self.network_creators = list()
+        self.router_creator = None
+        self.flavor_creator = None
+        self.sec_grp_creator = None
+        self.inst_creators = list()
+
+        self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        self.vm_inst1_name = self.guid + '-inst1'
+        self.vm_inst2_name = self.guid + '-inst2'
+        self.port_1_name = self.guid + '-vm1-port'
+        self.port_2_name = self.guid + '-vm2-port'
+        self.net_config_1 = NetworkConfig(
+            name=self.guid + '-net1',
+            subnet_settings=[
+                create_network.SubnetConfig(
+                    cidr=cidr1, name=self.guid + '-subnet1',
+                    gateway_ip=static_gateway_ip1)])
+        self.net_config_2 = NetworkConfig(
+            name=self.guid + '-net2',
+            subnet_settings=[
+                create_network.SubnetConfig(
+                    cidr=cidr2, name=self.guid + '-subnet2',
+                    gateway_ip=static_gateway_ip2)])
+
+        image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        os_image_settings = openstack_tests.cirros_image_settings(
+            name=image_name, image_metadata=self.image_metadata)
+
+        try:
+            # Create Image
+            self.image_creator = OpenStackImage(
+                self.os_creds, os_image_settings)
+            self.image_creator.create()
+
+            # First network is public
+            self.network_creators.append(OpenStackNetwork(
+                self.os_creds, self.net_config_1))
+
+            # Second network is private
+            self.network_creators.append(OpenStackNetwork(
+                self.os_creds, self.net_config_2))
+            for network_creator in self.network_creators:
+                network_creator.create()
+
+            port_settings = [
+                PortConfig(
+                    name=self.guid + '-router-port1',
+                    ip_addrs=[{
+                        'subnet_name':
+                            self.net_config_1.subnet_settings[0].name,
+                        'ip': static_gateway_ip1
+                    }],
+                    network_name=self.net_config_1.name),
+                PortConfig(
+                    name=self.guid + '-router-port2',
+                    ip_addrs=[{
+                        'subnet_name':
+                            self.net_config_2.subnet_settings[0].name,
+                        'ip': static_gateway_ip2
+                    }],
+                    network_name=self.net_config_2.name)]
+
+            router_settings = RouterConfig(
+                name=self.guid + '-pub-router', port_settings=port_settings)
+            self.router_creator = OpenStackRouter(
+                self.os_creds, router_settings)
+            self.router_creator.create()
+
+            flavor_config = openstack_tests.get_flavor_config(
+                name=self.guid + '-flavor-name', ram=512, disk=10,
+                vcpus=2, metadata=self.flavor_metadata)
+            self.flavor_creator = OpenStackFlavor(
+                self.admin_os_creds, flavor_config)
+            self.flavor_creator.create()
+
+            self.sec_grp_name = self.guid + '-sec-grp'
+            rule1 = SecurityGroupRuleConfig(
+                sec_grp_name=self.sec_grp_name, direction=Direction.ingress,
+                protocol=Protocol.icmp)
+            rule2 = SecurityGroupRuleConfig(
+                sec_grp_name=self.sec_grp_name, direction=Direction.egress,
+                protocol=Protocol.icmp)
+            self.sec_grp_creator = OpenStackSecurityGroup(
+                self.os_creds,
+                SecurityGroupConfig(
+                    name=self.sec_grp_name, rule_settings=[rule1, rule2]))
+            self.sec_grp_creator.create()
+        except:
+            self.tearDown()
+            raise
+
+    def tearDown(self):
+        """
+        Cleans the created objects
+        """
+        for inst_creator in self.inst_creators:
+            try:
+                inst_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning VM instance with message '
+                    '- %s', e)
+
+        if self.flavor_creator:
+            try:
+                self.flavor_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning flavor with message - %s',
+                    e)
+
+        if self.router_creator:
+            try:
+                self.router_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning router with message - %s',
+                    e)
+
+        for network_creator in self.network_creators:
+            try:
+                network_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning network with message - %s',
+                    e)
+
+        if self.sec_grp_creator:
+            try:
+                self.sec_grp_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning security group with message'
+                    ' - %s', e)
+
+        if self.image_creator and not self.image_creator.image_settings.exists:
+            try:
+                self.image_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning image with message - %s', e)
+
+        super(self.__class__, self).__clean__()
+
+    def test_ping_via_router(self):
+        """
+        Tests the creation of two OpenStack instances with one port on
+        different private networks wit a router in between to ensure that they
+        can ping
+        through
+        """
+        # Create ports/NICs for instance
+        ports_settings = []
+        ctr = 1
+        for network_creator in self.network_creators:
+            ports_settings.append(PortConfig(
+                name=self.guid + '-port-' + str(ctr),
+                network_name=network_creator.network_settings.name))
+            ctr += 1
+
+        # Configure instances
+        instance1_settings = VmInstanceConfig(
+            name=self.vm_inst1_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            userdata=_get_ping_userdata(self.ip2),
+            security_group_names=self.sec_grp_name,
+            port_settings=[PortConfig(
+                name=self.port_1_name,
+                ip_addrs=[{
+                    'subnet_name':
+                        self.net_config_1.subnet_settings[0].name,
+                    'ip': self.ip1
+                }],
+                network_name=self.network_creators[0].network_settings.name)])
+        instance2_settings = VmInstanceConfig(
+            name=self.vm_inst2_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            userdata=_get_ping_userdata(self.ip1),
+            security_group_names=self.sec_grp_name,
+            port_settings=[PortConfig(
+                name=self.port_2_name,
+                ip_addrs=[{
+                    'subnet_name':
+                        self.net_config_2.subnet_settings[0].name,
+                    'ip': self.ip2
+                }],
+                network_name=self.network_creators[1].network_settings.name)])
+
+        # Create instances
+        self.inst_creators.append(OpenStackVmInstance(
+            self.os_creds, instance1_settings,
+            self.image_creator.image_settings))
+        self.inst_creators.append(OpenStackVmInstance(
+            self.os_creds, instance2_settings,
+            self.image_creator.image_settings))
+
+        for inst_creator in self.inst_creators:
+            inst_creator.create(block=True)
+
+        # Check for DHCP lease
+        self.assertTrue(check_dhcp_lease(self.inst_creators[0], self.ip1))
+        self.assertTrue(check_dhcp_lease(self.inst_creators[1], self.ip2))
+
+        # Effectively blocks until VM has been properly activated
+        self.assertTrue(check_ping(self.inst_creators[0]))
+        self.assertTrue(check_ping(self.inst_creators[1]))
+
+
+class CreateInstanceVolumeTests(OSIntegrationTestCase):
+    """
+    Simple instance creation with an attached volume
+    """
+
+    def setUp(self):
+        """
+        Instantiates the CreateImage object that is responsible for downloading
+        and creating an OS image file
+        within OpenStack
+        """
+        super(self.__class__, self).__start__()
+
+        guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+        self.vm_inst_name = guid + '-inst'
+        self.nova = nova_utils.nova_client(
+            self.os_creds, self.os_session)
+        self.neutron = neutron_utils.neutron_client(
+            self.os_creds, self.os_session)
+        os_image_settings = openstack_tests.cirros_image_settings(
+            name=guid + '-image', image_metadata=self.image_metadata)
+
+        net_config = openstack_tests.get_priv_net_config(
+            project_name=self.os_creds.project_name,
+            net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
+            router_name=guid + '-pub-router', external_net=self.ext_net_name,
+            netconf_override=self.netconf_override)
+
+        self.volume_settings1 = VolumeConfig(
+            name=self.__class__.__name__ + '-' + str(guid) + '-1')
+        self.volume_settings2 = VolumeConfig(
+            name=self.__class__.__name__ + '-' + str(guid) + '-2')
+
+        # Initialize for tearDown()
+        self.image_creator = None
+        self.flavor_creator = None
+
+        self.network_creator = None
+        self.inst_creator = None
+        self.volume_creator1 = None
+        self.volume_creator2 = None
+
+        try:
+            # Create Image
+            self.image_creator = OpenStackImage(self.os_creds,
+                                                os_image_settings)
+            self.image_creator.create()
+
+            # Create Flavor
+            flavor_config = openstack_tests.get_flavor_config(
+                name=guid + '-flavor-name', ram=256, disk=1,
+                vcpus=2, metadata=self.flavor_metadata)
+            self.flavor_creator = OpenStackFlavor(
+                self.admin_os_creds, flavor_config)
+            self.flavor_creator.create()
+
+            # Create Network
+            self.network_creator = OpenStackNetwork(
+                self.os_creds, net_config.network_settings)
+            self.network_creator.create()
+
+            self.port_settings = PortConfig(
+                name=guid + '-port',
+                network_name=net_config.network_settings.name)
+
+            self.volume_creator1 = OpenStackVolume(
+                self.os_creds, self.volume_settings1)
+            self.volume_creator1.create(block=True)
+
+            self.volume_creator2 = OpenStackVolume(
+                self.os_creds, self.volume_settings2)
+            self.volume_creator2.create(block=True)
+
+        except Exception as e:
+            self.tearDown()
+            raise e
+
+    def tearDown(self):
+        """
+        Cleans the created object
+        """
+        if self.inst_creator:
+            try:
+                self.inst_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning VM instance with message '
+                    '- %s', e)
+
+        if self.flavor_creator:
+            try:
+                self.flavor_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning flavor with message - %s',
+                    e)
+
+        if self.network_creator:
+            try:
+                self.network_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning network with message - %s',
+                    e)
+
+        if self.volume_creator2:
+            try:
+                self.volume_creator2.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning volume with message - %s',
+                    e)
+
+        if self.volume_creator1:
+            try:
+                self.volume_creator1.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning volume with message - %s',
+                    e)
+
+        if self.image_creator and not self.image_creator.image_settings.exists:
+            try:
+                self.image_creator.clean()
+            except Exception as e:
+                logger.error(
+                    'Unexpected exception cleaning image with message - %s', e)
+
+        super(self.__class__, self).__clean__()
+
+    def test_create_instance_with_one_volume(self):
+        """
+        Tests the creation of an OpenStack instance with a single volume.
+        """
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[self.port_settings],
+            volume_names=[self.volume_settings1.name])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings)
+
+        vm_inst = self.inst_creator.create(block=True)
+        self.assertIsNotNone(nova_utils.get_server(
+            self.nova, self.neutron, self.keystone,
+            vm_inst_settings=instance_settings))
+
+        self.assertIsNotNone(vm_inst)
+        self.assertEqual(1, len(vm_inst.volume_ids))
+        self.assertEqual(self.volume_creator1.get_volume().id,
+                         vm_inst.volume_ids[0]['id'])
+
+    def test_create_instance_with_two_volumes(self):
+        """
+        Tests the creation of an OpenStack instance with a single volume.
+        """
+        instance_settings = VmInstanceConfig(
+            name=self.vm_inst_name,
+            flavor=self.flavor_creator.flavor_settings.name,
+            port_settings=[self.port_settings],
+            volume_names=[self.volume_settings1.name,
+                          self.volume_settings2.name])
+
+        self.inst_creator = OpenStackVmInstance(
+            self.os_creds, instance_settings,
+            self.image_creator.image_settings)
+
+        vm_inst = self.inst_creator.create(block=True)
+        self.assertIsNotNone(nova_utils.get_server(
+            self.nova, self.neutron, self.keystone,
+            vm_inst_settings=instance_settings))
+
+        self.assertIsNotNone(vm_inst)
+        self.assertEqual(2, len(vm_inst.volume_ids))
+        self.assertEqual(self.volume_creator1.get_volume().id,
+                         vm_inst.volume_ids[0]['id'])
+        self.assertEqual(self.volume_creator2.get_volume().id,
+                         vm_inst.volume_ids[1]['id'])
+
+
+def check_dhcp_lease(inst_creator, ip, timeout=160):
     """
     Returns true if the expected DHCP lease has been acquired
     """
     Returns true if the expected DHCP lease has been acquired
-    :param vm: the OpenStack VM instance object
+    :param inst_creator: the SNAPS OpenStackVmInstance object
     :param ip: the IP address to look for
     :param timeout: how long to query for IP address
     :return:
     :param ip: the IP address to look for
     :param timeout: how long to query for IP address
     :return:
@@ -2371,7 +3289,7 @@ def check_dhcp_lease(vm, ip, timeout=160):
     logger.info("Looking for IP %s in the console log" % ip)
     full_log = ''
     while timeout > time.time() - start_time:
     logger.info("Looking for IP %s in the console log" % ip)
     full_log = ''
     while timeout > time.time() - start_time:
-        output = vm.get_console_output()
+        output = inst_creator.get_console_output()
         full_log = full_log + output
         if re.search(ip, output):
             logger.info('DHCP lease obtained logged in console')
         full_log = full_log + output
         if re.search(ip, output):
             logger.info('DHCP lease obtained logged in console')
@@ -2384,3 +3302,43 @@ def check_dhcp_lease(vm, ip, timeout=160):
         logger.debug('Full console output -\n' + full_log)
 
     return found
         logger.debug('Full console output -\n' + full_log)
 
     return found
+
+
+def _get_ping_userdata(test_ip):
+    """
+    Returns the post VM creation script to be added into the VM's userdata
+    :param test_ip: the IP value to substitute into the script
+    :return: the bash script contents
+    """
+    if test_ip:
+        return ("#!/bin/sh\n\n"
+                "while true; do\n"
+                " ping -c 1 %s 2>&1 >/dev/null\n"
+                " RES=$?\n"
+                " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
+                "  echo 'vPing OK'\n"
+                "  break\n"
+                " else\n"
+                "  echo 'vPing KO'\n"
+                " fi\n"
+                " sleep 1\n"
+                "done\n" % test_ip)
+    return None
+
+
+def check_ping(vm_creator, timeout=160):
+    """
+    Check for VM for ping result
+    """
+    tries = 0
+
+    while tries < timeout:
+        time.sleep(1)
+        p_console = vm_creator.get_console_output()
+        if "vPing OK" in p_console:
+            return True
+        elif "failed to read iid from metadata" in p_console or tries > 5:
+            return False
+        tries += 1
+
+    return False