Merge "Check for kernel_url and ramdisk_url keys in dict"
[snaps.git] / snaps / openstack / tests / create_instance_tests.py
index d733547..2cb1cdc 100644 (file)
@@ -14,6 +14,7 @@
 # limitations under the License.
 import logging
 import os
 # limitations under the License.
 import logging
 import os
+import re
 import time
 import unittest
 import uuid
 import time
 import unittest
 import uuid
@@ -27,7 +28,7 @@ from snaps.openstack.create_image import OpenStackImage
 from snaps.openstack.create_security_group import SecurityGroupSettings, OpenStackSecurityGroup
 from snaps.openstack.tests import openstack_tests, validation_utils
 from snaps.openstack.utils import nova_utils
 from snaps.openstack.create_security_group import SecurityGroupSettings, OpenStackSecurityGroup
 from snaps.openstack.tests import openstack_tests, validation_utils
 from snaps.openstack.utils import nova_utils
-from snaps.openstack.tests.os_source_file_test import OSComponentTestCase, OSIntegrationTestCase
+from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
 
 __author__ = 'spisarski'
 
 
 __author__ = 'spisarski'
 
@@ -58,10 +59,21 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
             VmInstanceSettings(config={'name': 'foo'})
 
     def test_name_flavor_only(self):
             VmInstanceSettings(config={'name': 'foo'})
 
     def test_name_flavor_only(self):
-        settings = VmInstanceSettings(name='foo', flavor='bar')
+        with self.assertRaises(Exception):
+            VmInstanceSettings(name='foo', flavor='bar')
+
+    def test_config_with_name_flavor_only(self):
+        with self.assertRaises(Exception):
+            VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
+
+    def test_name_flavor_port_only(self):
+        port_settings = PortSettings(name='foo-port', network_name='bar-net')
+        settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings])
         self.assertEquals('foo', settings.name)
         self.assertEquals('bar', settings.flavor)
         self.assertEquals('foo', settings.name)
         self.assertEquals('bar', settings.flavor)
-        self.assertEquals(0, len(settings.port_settings))
+        self.assertEquals(1, len(settings.port_settings))
+        self.assertEquals('foo-port', settings.port_settings[0].name)
+        self.assertEquals('bar-net', settings.port_settings[0].network_name)
         self.assertEquals(0, len(settings.security_group_names))
         self.assertEquals(0, len(settings.floating_ip_settings))
         self.assertIsNone(settings.sudo_user)
         self.assertEquals(0, len(settings.security_group_names))
         self.assertEquals(0, len(settings.floating_ip_settings))
         self.assertIsNone(settings.sudo_user)
@@ -70,11 +82,14 @@ class VmInstanceSettingsUnitTests(unittest.TestCase):
         self.assertEquals(180, settings.ssh_connect_timeout)
         self.assertIsNone(settings.availability_zone)
 
         self.assertEquals(180, settings.ssh_connect_timeout)
         self.assertIsNone(settings.availability_zone)
 
-    def test_config_with_name_flavor_only(self):
-        settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
+    def test_config_with_name_flavor_port_only(self):
+        port_settings = PortSettings(name='foo-port', network_name='bar-net')
+        settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
         self.assertEquals('foo', settings.name)
         self.assertEquals('bar', settings.flavor)
         self.assertEquals('foo', settings.name)
         self.assertEquals('bar', settings.flavor)
-        self.assertEquals(0, len(settings.port_settings))
+        self.assertEquals(1, len(settings.port_settings))
+        self.assertEquals('foo-port', settings.port_settings[0].name)
+        self.assertEquals('bar-net', settings.port_settings[0].network_name)
         self.assertEquals(0, len(settings.security_group_names))
         self.assertEquals(0, len(settings.floating_ip_settings))
         self.assertIsNone(settings.sudo_user)
         self.assertEquals(0, len(settings.security_group_names))
         self.assertEquals(0, len(settings.floating_ip_settings))
         self.assertIsNone(settings.sudo_user)
@@ -228,7 +243,7 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         self.floating_ip_name = guid + 'fip1'
 
         # Initialize for tearDown()
         self.floating_ip_name = guid + 'fip1'
 
         # Initialize for tearDown()
-        self.image_creator = None
+        self.image_creators = list()
         self.network_creator = None
         self.flavor_creator = None
         self.inst_creator = None
         self.network_creator = None
         self.flavor_creator = None
         self.inst_creator = None
@@ -238,12 +253,35 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         self.port_settings = PortSettings(
             name=self.port_1_name, network_name=self.priv_net_config.network_settings.name)
 
         self.port_settings = PortSettings(
             name=self.port_1_name, network_name=self.priv_net_config.network_settings.name)
 
+        # Create Image
+        # Set the default image settings, then set any custom parameters sent from the app
         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
 
         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
 
+        if self.image_metadata:
+            if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                self.os_image_settings.url = self.image_metadata['disk_url']
+            if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
         try:
         try:
-            # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
 
             # Create Network
             self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
 
             # Create Network
             self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
@@ -252,7 +290,7 @@ class SimpleHealthCheck(OSIntegrationTestCase):
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=1024, disk=10, vcpus=1))
+                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=1, metadata=self.flavor_metadata))
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
@@ -277,18 +315,14 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         if self.flavor_creator:
             try:
                 self.flavor_creator.clean()
         if self.flavor_creator:
             try:
                 self.flavor_creator.clean()
-            except Exception as e:
-                logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
-
-        if self.network_creator:
-            try:
-                self.network_creator.clean()
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
-        if self.image_creator:
+        if self.image_creators:
             try:
             try:
-                self.image_creator.clean()
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
@@ -302,7 +336,8 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
 
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
 
-        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_creators[-1].image_settings)
         vm = self.inst_creator.create()
 
         ip = self.inst_creator.get_port_ip(self.port_settings.name)
         vm = self.inst_creator.create()
 
         ip = self.inst_creator.get_port_ip(self.port_settings.name)
@@ -311,15 +346,29 @@ class SimpleHealthCheck(OSIntegrationTestCase):
         self.assertTrue(self.inst_creator.vm_active(block=True))
 
         found = False
         self.assertTrue(self.inst_creator.vm_active(block=True))
 
         found = False
-        timeout = 100
+        timeout = 160
         start_time = time.time()
         start_time = time.time()
-        match_value = 'Lease of ' + ip + ' obtained,'
+        match_value = 'Lease of.*obtained'
 
 
+        logger.info("Looking for expression %s in the console log" % match_value)
+        full_log = ''
         while timeout > time.time() - start_time:
             output = vm.get_console_output()
         while timeout > time.time() - start_time:
             output = vm.get_console_output()
-            if match_value in output:
-                found = True
+            full_log = full_log + output
+            if re.search(match_value, output):
+                logger.info('DHCP lease obtained logged in console')
+                if ip in output:
+                    logger.info('With correct IP address')
+                    found = True
+                else:
+                    logger.error('With incorrect IP address')
                 break
                 break
+
+        if not found:
+            logger.error('Full console output -\n' + full_log)
+        else:
+            logger.debug('Full console output -\n' + full_log)
+
         self.assertTrue(found)
 
 
         self.assertTrue(found)
 
 
@@ -339,20 +388,58 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase):
         self.nova = nova_utils.nova_client(self.os_creds)
         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
 
         self.nova = nova_utils.nova_client(self.os_creds)
         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
 
+        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)
+
         # Initialize for tearDown()
         # Initialize for tearDown()
-        self.image_creator = None
+        self.image_creators = list()
         self.flavor_creator = None
         self.flavor_creator = None
+
+        self.net_creator = None
         self.inst_creator = None
 
         try:
             # Create Image
         self.inst_creator = None
 
         try:
             # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # Set any custom parameters sent from the app
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    self.os_image_settings.url = self.image_metadata['disk_url']
+                if 'extra_properties' in self.image_metadata and  self.image_metadata['extra_properties']:
+                    self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
+
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2))
+                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
             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)
+
         except Exception as e:
             self.tearDown()
             raise e
         except Exception as e:
             self.tearDown()
             raise e
@@ -373,9 +460,17 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase):
             except Exception as e:
                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
 
-        if self.image_creator:
+        if self.net_creator:
             try:
             try:
-                self.image_creator.clean()
+                self.net_creator.clean()
+            except Exception as e:
+                logger.error('Unexpected exception cleaning network with message - ' + e.message)
+
+        if self.image_creators:
+            try:
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
@@ -385,10 +480,11 @@ 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(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name)
+        instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
+                                               port_settings=[self.port_settings])
 
         self.inst_creator = OpenStackVmInstance(
 
         self.inst_creator = OpenStackVmInstance(
-            self.os_creds, instance_settings, self.image_creator.image_settings)
+            self.os_creds, instance_settings, self.image_creators[-1].image_settings)
 
         vm_inst = self.inst_creator.create()
         self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
 
         vm_inst = self.inst_creator.create()
         self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
@@ -425,7 +521,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         self.floating_ip_name = guid + 'fip1'
 
         # Initialize for tearDown()
         self.floating_ip_name = guid + 'fip1'
 
         # Initialize for tearDown()
-        self.image_creator = None
+        self.image_creators = list()
         self.network_creator = None
         self.router_creator = None
         self.flavor_creator = None
         self.network_creator = None
         self.router_creator = None
         self.flavor_creator = None
@@ -439,8 +535,31 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
 
         try:
             # Create Image
 
         try:
             # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # Set any custom parameters sent from the app
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    self.os_image_settings.url = self.image_metadata['disk_url']
+                if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                    self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
 
             # Create Network
             self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
 
             # Create Network
             self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
@@ -453,7 +572,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2))
+                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
             self.flavor_creator.create()
 
             self.keypair_creator = OpenStackKeypair(
             self.flavor_creator.create()
 
             self.keypair_creator = OpenStackKeypair(
@@ -505,9 +624,11 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
-        if self.image_creator:
+        if self.image_creators:
             try:
             try:
-                self.image_creator.clean()
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
@@ -530,7 +651,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
                 router_name=self.pub_net_config.router_settings.name)])
 
         inst_creator = OpenStackVmInstance(
                 router_name=self.pub_net_config.router_settings.name)])
 
         inst_creator = OpenStackVmInstance(
-            self.os_creds, instance_settings, self.image_creator.image_settings,
+            self.os_creds, instance_settings, self.image_creators[-1].image_settings,
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
         vm_inst = inst_creator.create()
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
         vm_inst = inst_creator.create()
@@ -553,7 +674,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
                 router_name=self.pub_net_config.router_settings.name)])
 
         inst_creator = OpenStackVmInstance(
                 router_name=self.pub_net_config.router_settings.name)])
 
         inst_creator = OpenStackVmInstance(
-            self.os_creds, instance_settings, self.image_creator.image_settings,
+            self.os_creds, instance_settings, self.image_creators[-1].image_settings,
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
         vm_inst = inst_creator.create()
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
         vm_inst = inst_creator.create()
@@ -562,7 +683,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         self.assertTrue(inst_creator.vm_active(block=True))
         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
 
         self.assertTrue(inst_creator.vm_active(block=True))
         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
 
-        validate_ssh_client(inst_creator)
+        self.assertTrue(validate_ssh_client(inst_creator))
 
     def test_ssh_client_fip_after_active(self):
         """
 
     def test_ssh_client_fip_after_active(self):
         """
@@ -578,7 +699,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
                 router_name=self.pub_net_config.router_settings.name)])
 
         inst_creator = OpenStackVmInstance(
                 router_name=self.pub_net_config.router_settings.name)])
 
         inst_creator = OpenStackVmInstance(
-            self.os_creds, instance_settings, self.image_creator.image_settings,
+            self.os_creds, instance_settings, self.image_creators[-1].image_settings,
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
 
             keypair_settings=self.keypair_creator.keypair_settings)
         self.inst_creators.append(inst_creator)
 
@@ -589,7 +710,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
         self.assertTrue(inst_creator.vm_active(block=True))
         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
 
         self.assertTrue(inst_creator.vm_active(block=True))
         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
 
-        validate_ssh_client(inst_creator)
+        self.assertTrue(validate_ssh_client(inst_creator))
 
     # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
     # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
 
     # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
     # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
@@ -607,7 +728,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
     #             router_name=self.pub_net_config.router_settings.name)])
     #
     #     inst_creator_1 = OpenStackVmInstance(
     #             router_name=self.pub_net_config.router_settings.name)])
     #
     #     inst_creator_1 = OpenStackVmInstance(
-    #         self.os_creds, instance_settings_1, self.image_creator.image_settings,
+    #         self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
     #         keypair_settings=self.keypair_creator.keypair_settings)
     #     self.inst_creators.append(inst_creator_1)
     #
     #         keypair_settings=self.keypair_creator.keypair_settings)
     #     self.inst_creators.append(inst_creator_1)
     #
@@ -625,7 +746,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
     #             router_name=self.pub_net_config.router_settings.name)])
     #
     #     inst_creator_1 = OpenStackVmInstance(
     #             router_name=self.pub_net_config.router_settings.name)])
     #
     #     inst_creator_1 = OpenStackVmInstance(
-    #         self.os_creds, instance_settings_1, self.image_creator.image_settings,
+    #         self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
     #         keypair_settings=self.keypair_creator.keypair_settings)
     #     self.inst_creators.append(inst_creator_1)
     #     inst_creator_1.create(block=True)
     #         keypair_settings=self.keypair_creator.keypair_settings)
     #     self.inst_creators.append(inst_creator_1)
     #     inst_creator_1.create(block=True)
@@ -648,7 +769,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
     #         port_settings=[port_settings_2])
     #
     #     inst_creator_2 = OpenStackVmInstance(
     #         port_settings=[port_settings_2])
     #
     #     inst_creator_2 = OpenStackVmInstance(
-    #         self.os_creds, instance_settings_2, self.image_creator.image_settings)
+    #         self.os_creds, instance_settings_2, self.image_creators[-1].image_settings)
     #     self.inst_creators.append(inst_creator_2)
     #     inst_creator_2.create(block=True)
     #
     #     self.inst_creators.append(inst_creator_2)
     #     inst_creator_2.create(block=True)
     #
@@ -666,13 +787,13 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
     #         port_settings=[port_settings_3])
     #
     #     inst_creator_3 = OpenStackVmInstance(
     #         port_settings=[port_settings_3])
     #
     #     inst_creator_3 = OpenStackVmInstance(
-    #         self.os_creds, instance_settings_3, self.image_creator.image_settings)
+    #         self.os_creds, instance_settings_3, self.image_creators[-1].image_settings)
     #     self.inst_creators.append(inst_creator_3)
     #     inst_creator_3.create(block=True)
     #
     #     print 'foo'
     #     self.inst_creators.append(inst_creator_3)
     #     inst_creator_3.create(block=True)
     #
     #     print 'foo'
-    # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would expect
-    # inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
+    # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would
+    # expect inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
     # TODO - Add validation
 
 
     # TODO - Add validation
 
 
@@ -695,7 +816,7 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         self.floating_ip_name = guid + 'fip1'
 
         # Initialize for tearDown()
         self.floating_ip_name = guid + 'fip1'
 
         # Initialize for tearDown()
-        self.image_creator = None
+        self.image_creators = list()
         self.network_creator = None
         self.flavor_creator = None
         self.inst_creator = None
         self.network_creator = None
         self.flavor_creator = None
         self.inst_creator = None
@@ -707,8 +828,31 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
 
         try:
             # Create Image
 
         try:
             # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # Set any custom parameters sent from the app
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    self.os_image_settings.url = self.image_metadata['disk_url']
+                if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                    self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
 
             # Create Network
             self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
 
             # Create Network
             self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
@@ -717,7 +861,7 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2))
+                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()
             self.flavor_creator.create()
         except Exception as e:
             self.tearDown()
@@ -745,9 +889,11 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
-        if self.image_creator:
+        if self.image_creators:
             try:
             try:
-                self.image_creator.clean()
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
@@ -765,7 +911,8 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
         self.inst_creator.create()
 
         self.assertEquals(ip, self.inst_creator.get_port_ip(
         self.inst_creator.create()
 
         self.assertEquals(ip, self.inst_creator.get_port_ip(
@@ -783,7 +930,8 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
 
         with self.assertRaises(Exception):
             self.inst_creator.create()
 
         with self.assertRaises(Exception):
             self.inst_creator.create()
@@ -799,7 +947,8 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
         self.inst_creator.create()
 
         self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
         self.inst_creator.create()
 
         self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
@@ -816,7 +965,7 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         self.inst_creator = OpenStackVmInstance(
             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)
+            self.os_creds, instance_settings, self.image_creators[-1].image_settings)
 
         with self.assertRaises(Exception):
             self.inst_creator.create()
 
         with self.assertRaises(Exception):
             self.inst_creator.create()
@@ -834,7 +983,8 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
         self.inst_creator.create()
 
         self.assertEquals(ip, self.inst_creator.get_port_ip(
         self.inst_creator.create()
 
         self.assertEquals(ip, self.inst_creator.get_port_ip(
@@ -854,7 +1004,8 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
         self.inst_creator.create()
 
         port = self.inst_creator.get_port_by_name(port_settings.name)
         self.inst_creator.create()
 
         port = self.inst_creator.get_port_by_name(port_settings.name)
@@ -879,7 +1030,8 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
         with self.assertRaises(Exception):
             self.inst_creator.create()
 
         with self.assertRaises(Exception):
             self.inst_creator.create()
 
@@ -899,12 +1051,13 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase):
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
 
         instance_settings = VmInstanceSettings(
             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)
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
         with self.assertRaises(Exception):
             self.inst_creator.create()
 
 
         with self.assertRaises(Exception):
             self.inst_creator.create()
 
 
-class CreateInstanceOnComputeHost(OSComponentTestCase):
+class CreateInstanceOnComputeHost(OSIntegrationTestCase):
     """
     Test for the CreateInstance where one VM is deployed to each compute node
     """
     """
     Test for the CreateInstance where one VM is deployed to each compute node
     """
@@ -914,12 +1067,14 @@ class CreateInstanceOnComputeHost(OSComponentTestCase):
         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
         """
+        super(self.__class__, self).__start__()
+
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.vm_inst_name = guid + '-inst'
         self.port_base_name = guid + 'port'
 
         # Initialize for tearDown()
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
         self.vm_inst_name = guid + '-inst'
         self.port_base_name = guid + 'port'
 
         # Initialize for tearDown()
-        self.image_creator = None
+        self.image_creators = list()
         self.flavor_creator = None
         self.network_creator = None
         self.inst_creators = list()
         self.flavor_creator = None
         self.network_creator = None
         self.inst_creators = list()
@@ -931,18 +1086,41 @@ class CreateInstanceOnComputeHost(OSComponentTestCase):
 
         try:
             # Create Network
 
         try:
             # Create Network
-            self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
+            self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
             self.network_creator.create()
 
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
             self.network_creator.create()
 
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
-                self.os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1))
+                self.admin_os_creds,
+                FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
             self.flavor_creator.create()
 
             # Create Image
             self.flavor_creator.create()
 
             # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # Set any custom parameters sent from the app
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    self.os_image_settings.url = self.image_metadata['disk_url']
+                if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                    self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
 
         except Exception as e:
             self.tearDown()
 
         except Exception as e:
             self.tearDown()
@@ -970,18 +1148,22 @@ class CreateInstanceOnComputeHost(OSComponentTestCase):
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
-        if self.image_creator:
+        if self.image_creators:
             try:
             try:
-                self.image_creator.clean()
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
+        super(self.__class__, self).__clean__()
+
     def test_deploy_vm_to_each_compute_node(self):
         """
         Tests the creation of OpenStack VM instances to each compute node.
         """
         from snaps.openstack.utils import nova_utils
     def test_deploy_vm_to_each_compute_node(self):
         """
         Tests the creation of OpenStack VM instances to each compute node.
         """
         from snaps.openstack.utils import nova_utils
-        nova = nova_utils.nova_client(self.os_creds)
+        nova = nova_utils.nova_client(self.admin_os_creds)
         zones = nova_utils.get_nova_availability_zones(nova)
 
         # Create Instance on each server/zone
         zones = nova_utils.get_nova_availability_zones(nova)
 
         # Create Instance on each server/zone
@@ -996,7 +1178,7 @@ class CreateInstanceOnComputeHost(OSComponentTestCase):
                 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
                 port_settings=[port_settings])
             inst_creator = OpenStackVmInstance(
                 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
                 port_settings=[port_settings])
             inst_creator = OpenStackVmInstance(
-                self.os_creds, instance_settings, self.image_creator.image_settings)
+                self.admin_os_creds, instance_settings, self.image_creators[-1].image_settings)
             self.inst_creators.append(inst_creator)
             inst_creator.create()
 
             self.inst_creators.append(inst_creator)
             inst_creator.create()
 
@@ -1026,7 +1208,7 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
         super(self.__class__, self).__start__()
 
         # Initialize for tearDown()
         super(self.__class__, self).__start__()
 
         # Initialize for tearDown()
-        self.image_creator = None
+        self.image_creators = list()
         self.network_creators = list()
         self.router_creators = list()
         self.flavor_creator = None
         self.network_creators = list()
         self.router_creators = list()
         self.flavor_creator = None
@@ -1052,8 +1234,31 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
 
         try:
             # Create Image
 
         try:
             # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # Set any custom parameters sent from the app
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    self.os_image_settings.url = self.image_metadata['disk_url']
+                if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                    self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
 
             # First network is public
             self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
 
             # First network is public
             self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
@@ -1072,7 +1277,8 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=self.guid + '-flavor-name', ram=2048, disk=10, vcpus=2))
+                FlavorSettings(name=self.guid + '-flavor-name', ram=512, disk=10, vcpus=2,
+                               metadata=self.flavor_metadata))
             self.flavor_creator.create()
 
             # Create Keypair
             self.flavor_creator.create()
 
             # Create Keypair
@@ -1125,9 +1331,11 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
-        if self.image_creator:
+        if self.image_creators:
             try:
             try:
-                self.image_creator.clean()
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
@@ -1159,7 +1367,7 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
                 router_name=self.pub_net_config.router_settings.name)])
 
         self.inst_creator = OpenStackVmInstance(
                 router_name=self.pub_net_config.router_settings.name)])
 
         self.inst_creator = OpenStackVmInstance(
-            self.os_creds, instance_settings, self.image_creator.image_settings,
+            self.os_creds, instance_settings, self.image_creators[-1].image_settings,
             keypair_settings=self.keypair_creator.keypair_settings)
 
         vm_inst = self.inst_creator.create(block=True)
             keypair_settings=self.keypair_creator.keypair_settings)
 
         vm_inst = self.inst_creator.create(block=True)
@@ -1196,21 +1404,17 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         self.nova = nova_utils.nova_client(self.os_creds)
         self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
 
         self.nova = nova_utils.nova_client(self.os_creds)
         self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
 
-        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.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.pub_net_config = openstack_tests.get_pub_net_config(
+        net_config = openstack_tests.get_priv_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)
 
         # Initialize for tearDown()
             net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
             router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
 
         # Initialize for tearDown()
-        self.image_creator = None
-        self.keypair_creator = None
+        self.image_creators = list()
         self.flavor_creator = None
         self.network_creator = None
         self.router_creator = None
         self.flavor_creator = None
         self.network_creator = None
         self.router_creator = None
@@ -1219,28 +1423,45 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
 
         try:
             # Create Image
 
         try:
             # Create Image
-            self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
-            self.image_creator.create()
+            # Set any custom parameters sent from the app
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    self.os_image_settings.url = self.image_metadata['disk_url']
+                if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                    self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
+
+            # If this is a 3-part image create the kernel and ramdisk images first
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
+                    kernel_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
+
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings = openstack_tests.cirros_url_image(
+                        name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
+                    self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
+                    ramdisk_image = self.image_creators[-1].create()
+                    self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
+
+            self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
+            self.image_creators[-1].create()
 
             # Create Network
 
             # Create Network
-            self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
+            self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
             self.network_creator.create()
 
             self.network_creator.create()
 
-            # Create Router
-            self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
-            self.router_creator.create()
-
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=self.guid + '-flavor-name', ram=2048, disk=10, vcpus=2))
+                FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=2,
+                               metadata=self.flavor_metadata))
             self.flavor_creator.create()
 
             self.flavor_creator.create()
 
-            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()
+            self.port_settings = PortSettings(name=self.guid + '-port',
+                                              network_name=net_config.network_settings.name)
         except Exception as e:
             self.tearDown()
             raise e
         except Exception as e:
             self.tearDown()
             raise e
@@ -1261,39 +1482,23 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
             except Exception as e:
                 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
 
-        if self.keypair_creator:
-            try:
-                self.keypair_creator.clean()
-            except Exception as e:
-                logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
-
-        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 - ' + e.message)
 
         if self.flavor_creator:
             try:
                 self.flavor_creator.clean()
             except Exception as e:
                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
 
-        if self.router_creator:
-            try:
-                self.router_creator.clean()
-            except Exception as e:
-                logger.error('Unexpected exception cleaning router with message - ' + e.message)
-
         if self.network_creator:
             try:
                 self.network_creator.clean()
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
         if self.network_creator:
             try:
                 self.network_creator.clean()
             except Exception as e:
                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
 
-        if self.image_creator:
+        if self.image_creators:
             try:
             try:
-                self.image_creator.clean()
+                while self.image_creators:
+                    self.image_creators[-1].clean()
+                    self.image_creators.pop()
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
             except Exception as e:
                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
 
@@ -1305,9 +1510,10 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         """
         # Create instance
         instance_settings = VmInstanceSettings(
         """
         # Create instance
         instance_settings = VmInstanceSettings(
-            name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name)
-        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
-        vm_inst = self.inst_creator.create()
+            name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
+        vm_inst = self.inst_creator.create(block=True)
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
@@ -1331,9 +1537,10 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         """
         # Create instance
         instance_settings = VmInstanceSettings(
         """
         # Create instance
         instance_settings = VmInstanceSettings(
-            name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name)
-        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
-        vm_inst = self.inst_creator.create()
+            name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
+        vm_inst = self.inst_creator.create(block=True)
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
         self.assertIsNotNone(vm_inst)
 
         # Create security group object to add to instance
@@ -1365,9 +1572,10 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         # Create instance
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
         # Create instance
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
-            security_group_names=[sec_grp_settings.name])
-        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
-        vm_inst = self.inst_creator.create()
+            security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
+        vm_inst = self.inst_creator.create(block=True)
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
         self.assertIsNotNone(vm_inst)
 
         # Check that group has been added
@@ -1391,13 +1599,14 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
 
         # Create instance
         instance_settings = VmInstanceSettings(
 
         # Create instance
         instance_settings = VmInstanceSettings(
-            name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name)
-        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
-        vm_inst = self.inst_creator.create()
+            name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
+        vm_inst = self.inst_creator.create(block=True)
         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(vm_inst, sec_grp_settings.name))
+        self.assertFalse(inst_has_sec_grp(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))
 
         # Add security group to instance after activated
         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
@@ -1418,13 +1627,14 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase):
         # Create instance
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
         # Create instance
         instance_settings = VmInstanceSettings(
             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
-            security_group_names=[sec_grp_settings.name])
-        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
-        vm_inst = self.inst_creator.create()
+            security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
+        self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
+                                                self.image_creators[-1].image_settings)
+        vm_inst = self.inst_creator.create(block=True)
         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.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))
 
         # Add security group to instance after activated
         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
@@ -1503,33 +1713,56 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
 
         try:
             # Create Images
 
         try:
             # Create Images
+            # Set properties
+            properties = {}
+            if self.image_metadata:
+                if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
+                    properties = self.image_metadata['extra_properties']
+
             # Create the kernel image
             # Create the kernel image
-            kernel_image_settings = openstack_tests.cirros_url_image(name=self.image_name+'_kernel',
+            kernel_image_settings = openstack_tests.cirros_url_image(
+                name=self.image_name+'_kernel',
                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
+
+            if self.image_metadata:
+                if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
+                    kernel_image_settings.url = self.image_metadata['kernel_url']
+
             self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
             kernel_image = self.image_creators[-1].create()
 
             # Create the ramdisk image
             self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
             kernel_image = self.image_creators[-1].create()
 
             # Create the ramdisk image
-            ramdisk_image_settings = openstack_tests.cirros_url_image(name=self.image_name+'_ramdisk',
+            ramdisk_image_settings = openstack_tests.cirros_url_image(
+                name=self.image_name+'_ramdisk',
                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
+
+            if self.image_metadata:
+                if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
+                    ramdisk_image_settings.url = self.image_metadata['ramdisk_url']
+
             self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
             ramdisk_image = self.image_creators[-1].create()
             self.assertIsNotNone(ramdisk_image)
 
             # Create the main image
             self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
             ramdisk_image = self.image_creators[-1].create()
             self.assertIsNotNone(ramdisk_image)
 
             # Create the main image
-            os_image_settings = openstack_tests.cirros_url_image(name=self.image_name,
+            os_image_settings = openstack_tests.cirros_url_image(
+                name=self.image_name,
                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
-            properties = {}
+            if self.image_metadata:
+                if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
+                    os_image_settings.url = self.image_metadata['disk_url']
+
             properties['kernel_id'] = kernel_image.id
             properties['ramdisk_id'] = ramdisk_image.id
             os_image_settings.extra_properties = properties
             self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
             created_image = self.image_creators[-1].create()
             properties['kernel_id'] = kernel_image.id
             properties['ramdisk_id'] = ramdisk_image.id
             os_image_settings.extra_properties = properties
             self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
             created_image = self.image_creators[-1].create()
+            self.assertIsNotNone(created_image)
 
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
 
             # Create Flavor
             self.flavor_creator = OpenStackFlavor(
                 self.admin_os_creds,
-                FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2))
+                FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
             self.flavor_creator.create()
 
             # Create Network
             self.flavor_creator.create()
 
             # Create Network
@@ -1588,6 +1821,8 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
         vm_inst = self.inst_creator.create()
         self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
 
         vm_inst = self.inst_creator.create()
         self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
 
+        self.assertTrue(self.inst_creator.vm_active(block=True))
+
         # Delete instance
         nova_utils.delete_vm_instance(self.nova, vm_inst)
 
         # Delete instance
         nova_utils.delete_vm_instance(self.nova, vm_inst)
 
@@ -1596,4 +1831,3 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
 
         # Exception should not be thrown
         self.inst_creator.clean()
 
         # Exception should not be thrown
         self.inst_creator.clean()
-