diff options
Diffstat (limited to 'snaps/openstack/utils/tests/heat_utils_tests.py')
-rw-r--r-- | snaps/openstack/utils/tests/heat_utils_tests.py | 599 |
1 files changed, 493 insertions, 106 deletions
diff --git a/snaps/openstack/utils/tests/heat_utils_tests.py b/snaps/openstack/utils/tests/heat_utils_tests.py index 44235ff..fa240bd 100644 --- a/snaps/openstack/utils/tests/heat_utils_tests.py +++ b/snaps/openstack/utils/tests/heat_utils_tests.py @@ -13,21 +13,25 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging +import os + import pkg_resources import uuid import time -from snaps.openstack import create_stack -from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings +import snaps.config.stack as stack_config +from snaps.config.flavor import FlavorConfig +from snaps.openstack.create_flavor import OpenStackFlavor from snaps.openstack.create_image import OpenStackImage from snaps.openstack.create_instance import OpenStackVmInstance -from snaps.openstack.create_stack import StackSettings +from snaps.openstack.create_stack import StackConfig from snaps.openstack.tests import openstack_tests from snaps.openstack.tests.os_source_file_test import OSComponentTestCase from snaps.openstack.utils import ( - heat_utils, neutron_utils, nova_utils, settings_utils, glance_utils) + heat_utils, neutron_utils, nova_utils, settings_utils, glance_utils, + cinder_utils, keystone_utils) __author__ = 'spisarski' @@ -43,12 +47,12 @@ class HeatSmokeTests(OSComponentTestCase): """ Tests to ensure that the proper credentials can connect. """ - heat = heat_utils.heat_client(self.os_creds) + heat = heat_utils.heat_client(self.os_creds, self.os_session) # This should not throw an exception stacks = heat.stacks.list() for stack in stacks: - print stack + logger.info('Stack - %s', stack) def test_heat_connect_fail(self): """ @@ -66,7 +70,7 @@ class HeatSmokeTests(OSComponentTestCase): # This should throw an exception with self.assertRaises(Exception): for stack in stacks: - print stack + logger.info('Stack - %s', stack) class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): @@ -93,7 +97,7 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): # Create Flavor self.flavor_creator = OpenStackFlavor( self.os_creds, - FlavorSettings(name=guid + '-flavor', ram=256, disk=10, vcpus=1)) + FlavorConfig(name=guid + '-flavor', ram=256, disk=10, vcpus=1)) self.flavor_creator.create() env_values = {'image_name': self.image_creator.image_settings.name, @@ -103,19 +107,20 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): 'inst_name': self.vm_inst_name} heat_tmplt_path = pkg_resources.resource_filename( 'snaps.openstack.tests.heat', 'test_heat_template.yaml') - self.stack_settings1 = StackSettings( + self.stack_settings1 = StackConfig( name=stack_name1, template_path=heat_tmplt_path, env_values=env_values) - self.stack_settings2 = StackSettings( + self.stack_settings2 = StackConfig( name=stack_name2, template_path=heat_tmplt_path, env_values=env_values) self.stack1 = None self.stack2 = None - self.heat_client = heat_utils.heat_client(self.os_creds) + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) def tearDown(self): """ - Cleans the image and downloaded image file + Cleans the stack and image """ if self.stack1: try: @@ -141,6 +146,8 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): except: pass + super(self.__class__, self).__clean__() + def test_create_stack(self): """ Tests the creation of an OpenStack Heat stack1 that does not exist. @@ -160,7 +167,7 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): self.stack1.id) self.assertEqual(self.stack1, stack_query_3) - resources = heat_utils.get_resources(self.heat_client, self.stack1) + resources = heat_utils.get_resources(self.heat_client, self.stack1.id) self.assertIsNotNone(resources) self.assertEqual(4, len(resources)) @@ -168,24 +175,9 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): self.assertIsNotNone(outputs) self.assertEqual(0, len(outputs)) - # Wait until stack deployment has completed - end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT - is_active = False - while time.time() < end_time: - status = heat_utils.get_stack_status(self.heat_client, - self.stack1.id) - if status == create_stack.STATUS_CREATE_COMPLETE: - is_active = True - break - elif status == create_stack.STATUS_CREATE_FAILED: - is_active = False - break - - time.sleep(3) - - self.assertTrue(is_active) + self.assertTrue(stack_active(self.heat_client, self.stack1)) - neutron = neutron_utils.neutron_client(self.os_creds) + neutron = neutron_utils.neutron_client(self.os_creds, self.os_session) networks = heat_utils.get_stack_networks( self.heat_client, neutron, self.stack1) self.assertIsNotNone(networks) @@ -196,9 +188,12 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): self.assertEqual(1, len(subnets)) self.assertEqual(self.subnet_name, subnets[0].name) - nova = nova_utils.nova_client(self.os_creds) + nova = nova_utils.nova_client(self.os_creds, self.os_session) + keystone = keystone_utils.keystone_client( + self.os_creds, self.os_session) servers = heat_utils.get_stack_servers( - self.heat_client, nova, self.stack1) + self.heat_client, nova, neutron, keystone, self.stack1, + self.os_creds.project_name) self.assertIsNotNone(servers) self.assertEqual(1, len(servers)) self.assertEqual(self.vm_inst_name, servers[0].name) @@ -222,21 +217,7 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): self.stack1.id) self.assertEqual(self.stack1, stack1_query_3) - end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT - is_active = False - while time.time() < end_time: - status = heat_utils.get_stack_status(self.heat_client, - self.stack1.id) - if status == create_stack.STATUS_CREATE_COMPLETE: - is_active = True - break - elif status == create_stack.STATUS_CREATE_FAILED: - is_active = False - break - - time.sleep(3) - - self.assertTrue(is_active) + self.assertTrue(stack_active(self.heat_client, self.stack1)) self.stack2 = heat_utils.create_stack(self.heat_client, self.stack_settings2) @@ -253,22 +234,7 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase): self.stack2.id) self.assertEqual(self.stack2, stack2_query_3) - end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT - - is_active = False - while time.time() < end_time: - status = heat_utils.get_stack_status(self.heat_client, - self.stack2.id) - if status == create_stack.STATUS_CREATE_COMPLETE: - is_active = True - break - elif status == create_stack.STATUS_CREATE_FAILED: - is_active = False - break - - time.sleep(3) - - self.assertTrue(is_active) + self.assertTrue(stack_active(self.heat_client, self.stack2)) class HeatUtilsCreateComplexStackTests(OSComponentTestCase): @@ -312,60 +278,59 @@ class HeatUtilsCreateComplexStackTests(OSComponentTestCase): 'external_net_name': self.ext_net_name} heat_tmplt_path = pkg_resources.resource_filename( 'snaps.openstack.tests.heat', 'floating_ip_heat_template.yaml') - stack_settings = StackSettings( + stack_settings = StackConfig( name=stack_name, template_path=heat_tmplt_path, env_values=env_values) - self.heat_client = heat_utils.heat_client(self.os_creds) + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) self.stack = heat_utils.create_stack(self.heat_client, stack_settings) - # Wait until stack deployment has completed - end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT - is_active = False - while time.time() < end_time: - status = heat_utils.get_stack_status(self.heat_client, - self.stack.id) - if status == create_stack.STATUS_CREATE_COMPLETE: - is_active = True - break - elif status == create_stack.STATUS_CREATE_FAILED: - is_active = False - break + self.assertTrue(stack_active(self.heat_client, self.stack)) - time.sleep(3) - self.assertTrue(is_active) + self.keypair1_settings = None + self.keypair2_settings = None def tearDown(self): """ - Cleans the image and downloaded image file + Cleans the stack and image """ if self.stack: try: heat_utils.delete_stack(self.heat_client, self.stack) # Wait until stack deployment has completed - end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT + end_time = (time.time() + + stack_config.STACK_COMPLETE_TIMEOUT) is_deleted = False while time.time() < end_time: status = heat_utils.get_stack_status(self.heat_client, self.stack.id) - if status == create_stack.STATUS_DELETE_COMPLETE: + if status == stack_config.STATUS_DELETE_COMPLETE: is_deleted = True break - elif status == create_stack.STATUS_DELETE_FAILED: + elif status == stack_config.STATUS_DELETE_FAILED: is_deleted = False break time.sleep(3) if not is_deleted: - nova = nova_utils.nova_client(self.os_creds) - neutron = neutron_utils.neutron_client(self.os_creds) - glance = glance_utils.glance_client(self.os_creds) + nova = nova_utils.nova_client( + self.os_creds, self.os_session) + keystone = keystone_utils.keystone_client( + self.os_creds, self.os_session) + neutron = neutron_utils.neutron_client( + self.os_creds, self.os_session) + glance = glance_utils.glance_client( + self.os_creds, self.os_session) + servers = heat_utils.get_stack_servers( - self.heat_client, nova, self.stack) + self.heat_client, nova, neutron, keystone, self.stack, + self.os_creds.project_name) for server in servers: - vm_settings = settings_utils.create_vm_inst_settings( - nova, neutron, server) - img_settings = settings_utils.determine_image_settings( + vm_settings = settings_utils.create_vm_inst_config( + nova, keystone, neutron, server, + self.os_creds.project_name) + img_settings = settings_utils.determine_image_config( glance, server, [self.image_creator1.image_settings, self.image_creator2.image_settings]) @@ -392,40 +357,56 @@ class HeatUtilsCreateComplexStackTests(OSComponentTestCase): except: pass + if self.keypair1_settings: + expanded_path = os.path.expanduser( + self.keypair1_settings.private_filepath) + os.chmod(expanded_path, 0o755) + os.remove(expanded_path) + + if self.keypair2_settings: + expanded_path = os.path.expanduser( + self.keypair2_settings.private_filepath) + os.chmod(expanded_path, 0o755) + os.remove(expanded_path) + + super(self.__class__, self).__clean__() + def test_get_settings_from_stack(self): """ Tests that a heat template with floating IPs and can have the proper settings derived from settings_utils.py. """ - resources = heat_utils.get_resources(self.heat_client, self.stack) + resources = heat_utils.get_resources(self.heat_client, self.stack.id) self.assertIsNotNone(resources) - self.assertEqual(11, len(resources)) + self.assertEqual(13, len(resources)) options = heat_utils.get_outputs(self.heat_client, self.stack) self.assertIsNotNone(options) self.assertEqual(1, len(options)) - neutron = neutron_utils.neutron_client(self.os_creds) + neutron = neutron_utils.neutron_client(self.os_creds, self.os_session) networks = heat_utils.get_stack_networks( self.heat_client, neutron, self.stack) self.assertIsNotNone(networks) self.assertEqual(1, len(networks)) self.assertEqual(self.network_name, networks[0].name) - network_settings = settings_utils.create_network_settings( + network_settings = settings_utils.create_network_config( neutron, networks[0]) self.assertIsNotNone(network_settings) self.assertEqual(self.network_name, network_settings.name) - nova = nova_utils.nova_client(self.os_creds) - glance = glance_utils.glance_client(self.os_creds) - + nova = nova_utils.nova_client(self.os_creds, self.os_session) + glance = glance_utils.glance_client(self.os_creds, self.os_session) + keystone = keystone_utils.keystone_client( + self.os_creds, self.os_session) servers = heat_utils.get_stack_servers( - self.heat_client, nova, self.stack) + self.heat_client, nova, neutron, keystone, self.stack, + self.os_creds.project_name) self.assertIsNotNone(servers) self.assertEqual(2, len(servers)) - image_settings = settings_utils.determine_image_settings( + image_settings = settings_utils.determine_image_config( glance, servers[0], [self.image_creator1.image_settings, self.image_creator2.image_settings]) @@ -438,7 +419,7 @@ class HeatUtilsCreateComplexStackTests(OSComponentTestCase): self.assertEqual( self.image_creator2.image_settings.name, image_settings.name) - image_settings = settings_utils.determine_image_settings( + image_settings = settings_utils.determine_image_config( glance, servers[1], [self.image_creator1.image_settings, self.image_creator2.image_settings]) @@ -449,14 +430,420 @@ class HeatUtilsCreateComplexStackTests(OSComponentTestCase): self.assertEqual( self.image_creator2.image_settings.name, image_settings.name) - keypair1_settings = settings_utils.determine_keypair_settings( + self.keypair1_settings = settings_utils.determine_keypair_config( self.heat_client, self.stack, servers[0], priv_key_key='private_key') - self.assertIsNotNone(keypair1_settings) - self.assertEqual(self.keypair_name, keypair1_settings.name) + self.assertIsNotNone(self.keypair1_settings) + self.assertEqual(self.keypair_name, self.keypair1_settings.name) - keypair2_settings = settings_utils.determine_keypair_settings( + self.keypair2_settings = settings_utils.determine_keypair_config( self.heat_client, self.stack, servers[1], priv_key_key='private_key') - self.assertIsNotNone(keypair2_settings) - self.assertEqual(self.keypair_name, keypair2_settings.name) + self.assertIsNotNone(self.keypair2_settings) + self.assertEqual(self.keypair_name, self.keypair2_settings.name) + + +class HeatUtilsRouterTests(OSComponentTestCase): + """ + Test Heat volume functionality + """ + + def setUp(self): + """ + Instantiates OpenStack instances that cannot be spawned by Heat + """ + guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + stack_name = guid + '-stack' + + self.net_name = guid + '-net' + self.subnet_name = guid + '-subnet' + self.router_name = guid + '-router' + + env_values = { + 'net_name': self.net_name, + 'subnet_name': self.subnet_name, + 'router_name': self.router_name, + 'external_net_name': self.ext_net_name} + + heat_tmplt_path = pkg_resources.resource_filename( + 'snaps.openstack.tests.heat', 'router_heat_template.yaml') + self.stack_settings = StackConfig( + name=stack_name, template_path=heat_tmplt_path, + env_values=env_values) + self.stack = None + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) + self.neutron = neutron_utils.neutron_client( + self.os_creds, self.os_session) + + def tearDown(self): + """ + Cleans the image and downloaded image file + """ + if self.stack: + try: + heat_utils.delete_stack(self.heat_client, self.stack) + except: + pass + + super(self.__class__, self).__clean__() + + def test_create_router_with_stack(self): + """ + Tests the creation of an OpenStack router with Heat and the retrieval + of the Router Domain objects from heat_utils#get_stack_routers(). + """ + self.stack = heat_utils.create_stack( + self.heat_client, self.stack_settings) + + # Wait until stack deployment has completed + end_time = time.time() + stack_config.STACK_COMPLETE_TIMEOUT + is_active = False + while time.time() < end_time: + status = heat_utils.get_stack_status(self.heat_client, + self.stack.id) + if status == stack_config.STATUS_CREATE_COMPLETE: + is_active = True + break + elif status == stack_config.STATUS_CREATE_FAILED: + is_active = False + break + + time.sleep(3) + + self.assertTrue(is_active) + + routers = heat_utils.get_stack_routers( + self.heat_client, self.neutron, self.stack) + + self.assertEqual(1, len(routers)) + + router = routers[0] + self.assertEqual(self.router_name, router.name) + + keystone = keystone_utils.keystone_client( + self.os_creds, self.os_session) + ext_net = neutron_utils.get_network( + self.neutron, keystone, network_name=self.ext_net_name) + self.assertEqual(ext_net.id, router.external_network_id) + + +class HeatUtilsVolumeTests(OSComponentTestCase): + """ + Test Heat volume functionality + """ + + def setUp(self): + """ + Instantiates OpenStack instances that cannot be spawned by Heat + """ + guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + stack_name = guid + '-stack' + self.volume_name = guid + '-vol' + self.volume_type_name = guid + '-vol-type' + + env_values = { + 'volume_name': self.volume_name, + 'volume_type_name': self.volume_type_name} + + heat_tmplt_path = pkg_resources.resource_filename( + 'snaps.openstack.tests.heat', 'volume_heat_template.yaml') + self.stack_settings = StackConfig( + name=stack_name, template_path=heat_tmplt_path, + env_values=env_values) + self.stack = None + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) + self.cinder = cinder_utils.cinder_client( + self.os_creds, self.os_session) + + def tearDown(self): + """ + Cleans the stack + """ + if self.stack: + try: + heat_utils.delete_stack(self.heat_client, self.stack) + except: + pass + + super(self.__class__, self).__clean__() + + def test_create_vol_with_stack(self): + """ + Tests the creation of an OpenStack volume with Heat. + """ + self.stack = heat_utils.create_stack( + self.heat_client, self.stack_settings) + self.assertTrue(stack_active(self.heat_client, self.stack)) + + volumes = heat_utils.get_stack_volumes( + self.heat_client, self.cinder, self.stack) + + self.assertEqual(1, len(volumes)) + + volume = volumes[0] + self.assertEqual(self.volume_name, volume.name) + self.assertEqual(self.volume_type_name, volume.type) + self.assertEqual(1, volume.size) + self.assertEqual(False, volume.multi_attach) + + def test_create_vol_types_with_stack(self): + """ + Tests the creation of an OpenStack volume with Heat. + """ + self.stack = heat_utils.create_stack( + self.heat_client, self.stack_settings) + self.assertTrue(stack_active(self.heat_client, self.stack)) + + volume_types = heat_utils.get_stack_volume_types( + self.heat_client, self.cinder, self.stack) + + self.assertEqual(1, len(volume_types)) + + volume_type = volume_types[0] + + self.assertEqual(self.volume_type_name, volume_type.name) + self.assertTrue(volume_type.public) + self.assertIsNone(volume_type.qos_spec) + + # TODO - Add encryption back and find out why it broke in Pike + # encryption = volume_type.encryption + # self.assertIsNotNone(encryption) + # self.assertIsNone(encryption.cipher) + # self.assertEqual('front-end', encryption.control_location) + # self.assertIsNone(encryption.key_size) + # self.assertEqual(u'nova.volume.encryptors.luks.LuksEncryptor', + # encryption.provider) + # self.assertEqual(volume_type.id, encryption.volume_type_id) + + +class HeatUtilsFlavorTests(OSComponentTestCase): + """ + Test Heat volume functionality + """ + + def setUp(self): + """ + Instantiates OpenStack instances that cannot be spawned by Heat + """ + guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + self.name_prefix = guid + stack_name = guid + '-stack' + + heat_tmplt_path = pkg_resources.resource_filename( + 'snaps.openstack.tests.heat', 'flavor_heat_template.yaml') + self.stack_settings = StackConfig( + name=stack_name, template_path=heat_tmplt_path) + self.stack = None + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) + self.nova = nova_utils.nova_client( + self.os_creds, self.os_session) + + def tearDown(self): + """ + Cleans the stack + """ + if self.stack: + try: + heat_utils.delete_stack(self.heat_client, self.stack) + except: + pass + + super(self.__class__, self).__clean__() + + def test_create_flavor_with_stack(self): + """ + Tests the creation of an OpenStack volume with Heat. + """ + self.stack = heat_utils.create_stack( + self.heat_client, self.stack_settings) + + self.assertTrue(stack_active(self.heat_client, self.stack)) + + flavors = heat_utils.get_stack_flavors( + self.heat_client, self.nova, self.stack) + + self.assertEqual(1, len(flavors)) + + flavor = flavors[0] + self.assertTrue(flavor.name.startswith(self.name_prefix)) + self.assertEqual(1024, flavor.ram) + self.assertEqual(200, flavor.disk) + self.assertEqual(8, flavor.vcpus) + self.assertEqual(0, flavor.ephemeral) + self.assertIsNone(flavor.swap) + self.assertEqual(1.0, flavor.rxtx_factor) + self.assertTrue(flavor.is_public) + + +class HeatUtilsKeypairTests(OSComponentTestCase): + """ + Test Heat volume functionality + """ + + def setUp(self): + """ + Instantiates OpenStack instances that cannot be spawned by Heat + """ + guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + stack_name = guid + '-stack' + self.keypair_name = guid + '-kp' + + env_values = {'keypair_name': self.keypair_name} + + heat_tmplt_path = pkg_resources.resource_filename( + 'snaps.openstack.tests.heat', 'keypair_heat_template.yaml') + self.stack_settings = StackConfig( + name=stack_name, template_path=heat_tmplt_path, + env_values=env_values) + self.stack = None + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) + self.nova = nova_utils.nova_client( + self.os_creds, self.os_session) + + def tearDown(self): + """ + Cleans the stack + """ + if self.stack: + try: + heat_utils.delete_stack(self.heat_client, self.stack) + except: + pass + + super(self.__class__, self).__clean__() + + def test_create_keypair_with_stack(self): + """ + Tests the creation of an OpenStack keypair with Heat. + """ + self.stack = heat_utils.create_stack( + self.heat_client, self.stack_settings) + self.assertTrue(stack_active(self.heat_client, self.stack)) + + keypairs = heat_utils.get_stack_keypairs( + self.heat_client, self.nova, self.stack) + + self.assertEqual(1, len(keypairs)) + keypair = keypairs[0] + + self.assertEqual(self.keypair_name, keypair.name) + + outputs = heat_utils.get_outputs(self.heat_client, self.stack) + + for output in outputs: + if output.key == 'private_key': + self.assertTrue(output.value.startswith( + '-----BEGIN RSA PRIVATE KEY-----')) + + keypair = nova_utils.get_keypair_by_id(self.nova, keypair.id) + self.assertIsNotNone(keypair) + + self.assertEqual(self.keypair_name, keypair.name) + + +class HeatUtilsSecurityGroupTests(OSComponentTestCase): + """ + Test Heat volume functionality + """ + + def setUp(self): + """ + Instantiates OpenStack instances that cannot be spawned by Heat + """ + guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + stack_name = guid + '-stack' + self.sec_grp_name = guid + '-sec-grp' + + env_values = {'security_group_name': self.sec_grp_name} + + heat_tmplt_path = pkg_resources.resource_filename( + 'snaps.openstack.tests.heat', 'security_group_heat_template.yaml') + self.stack_settings = StackConfig( + name=stack_name, template_path=heat_tmplt_path, + env_values=env_values) + self.stack = None + self.heat_client = heat_utils.heat_client( + self.os_creds, self.os_session) + self.neutron = neutron_utils.neutron_client( + self.os_creds, self.os_session) + + def tearDown(self): + """ + Cleans the stack + """ + if self.stack: + try: + heat_utils.delete_stack(self.heat_client, self.stack) + except: + pass + + super(self.__class__, self).__clean__() + + def test_create_security_group_with_stack(self): + """ + Tests the creation of an OpenStack SecurityGroup with Heat. + """ + self.stack = heat_utils.create_stack( + self.heat_client, self.stack_settings) + self.assertTrue(stack_active(self.heat_client, self.stack)) + + sec_grp = heat_utils.get_stack_security_groups( + self.heat_client, self.neutron, self.stack)[0] + + self.assertEqual(self.sec_grp_name, sec_grp.name) + self.assertEqual('Test description', sec_grp.description) + self.assertEqual(2, len(sec_grp.rules)) + + has_ssh_rule = False + has_icmp_rule = False + + for rule in sec_grp.rules: + if (rule.security_group_id == sec_grp.id + and rule.direction == 'egress' + and rule.ethertype == 'IPv4' + and rule.port_range_min == 22 + and rule.port_range_max == 22 + and rule.protocol == 'tcp' + and rule.remote_group_id is None + and rule.remote_ip_prefix == '0.0.0.0/0'): + has_ssh_rule = True + if (rule.security_group_id == sec_grp.id + and rule.direction == 'ingress' + and rule.ethertype == 'IPv4' + and rule.port_range_min is None + and rule.port_range_max is None + and rule.protocol == 'icmp' + and rule.remote_group_id is None + and rule.remote_ip_prefix == '0.0.0.0/0'): + has_icmp_rule = True + + self.assertTrue(has_ssh_rule) + self.assertTrue(has_icmp_rule) + + +def stack_active(heat_cli, stack): + """ + Blocks until stack application has successfully completed or failed + :param heat_cli: the Heat client + :param stack: the Stack domain object + :return: T/F + """ + # Wait until stack deployment has completed + end_time = time.time() + stack_config.STACK_COMPLETE_TIMEOUT + is_active = False + while time.time() < end_time: + status = heat_utils.get_stack_status(heat_cli, stack.id) + if status == stack_config.STATUS_CREATE_COMPLETE: + is_active = True + break + elif status == stack_config.STATUS_CREATE_FAILED: + is_active = False + break + + time.sleep(3) + + return is_active |