summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspisarski <s.pisarski@cablelabs.com>2017-11-03 10:39:24 -0600
committerspisarski <s.pisarski@cablelabs.com>2017-11-06 08:46:43 -0700
commit5ccbf950eadbe54acad6e03cc43c19e05ee4e912 (patch)
tree76da9271e5095065e1e01195287afe53b820022c
parent15b7270542288263189abebcfa4f89c0245aaf8b (diff)
Added method to OpenStackHeatStack to return OpenStackSecurityGroup objects.
Continuation of the story SNAPS-153 for adding creator/state machine instances for OpenStack objects deployed via Heat. JIRA: SNAPS-207 Change-Id: Id479b69c2b166ab38724c3886096d8483998f819 Signed-off-by: spisarski <s.pisarski@cablelabs.com>
-rw-r--r--docs/how-to-use/APITests.rst13
-rw-r--r--docs/how-to-use/IntegrationTests.rst11
-rw-r--r--snaps/domain/network.py20
-rw-r--r--snaps/domain/test/network_tests.py47
-rw-r--r--snaps/openstack/create_security_group.py3
-rw-r--r--snaps/openstack/create_stack.py23
-rw-r--r--snaps/openstack/tests/create_stack_tests.py94
-rw-r--r--snaps/openstack/tests/heat/security_group_heat_template.yaml45
-rw-r--r--snaps/openstack/utils/heat_utils.py20
-rw-r--r--snaps/openstack/utils/neutron_utils.py34
-rw-r--r--snaps/openstack/utils/settings_utils.py26
-rw-r--r--snaps/openstack/utils/tests/heat_utils_tests.py89
-rw-r--r--snaps/test_suite_builder.py14
13 files changed, 418 insertions, 21 deletions
diff --git a/docs/how-to-use/APITests.rst b/docs/how-to-use/APITests.rst
index 4c1f885..c11a6b5 100644
--- a/docs/how-to-use/APITests.rst
+++ b/docs/how-to-use/APITests.rst
@@ -480,10 +480,21 @@ heat_utils_tests.py - HeatUtilsKeypairTests
| Test Name | Heat API | Description |
+=======================================+===============+===========================================================+
| test_create_keypair_with_stack | 1-3 | Tests ability of the function |
-| | | heat_utils.create_stack() to return the correct |
+| | | heat_utils.get_stack_keypairs() to return the correct |
| | | Keypair domain objects deployed with Heat |
+---------------------------------------+---------------+-----------------------------------------------------------+
+heat_utils_tests.py - HeatUtilsSecurityGroupTests
+-------------------------------------------------
+
++---------------------------------------+---------------+-----------------------------------------------------------+
+| Test Name | Heat API | Description |
++=======================================+===============+===========================================================+
+| test_create_security_group_with_stack | 1-3 | Tests ability of the function |
+| | | heat_utils.get_stack_security_groups() to return the |
+| | | correct SecurityGroup domain objects deployed with Heat |
++---------------------------------------+---------------+-----------------------------------------------------------+
+
heat_utils_tests.py - HeatUtilsFlavorTests
------------------------------------------
diff --git a/docs/how-to-use/IntegrationTests.rst b/docs/how-to-use/IntegrationTests.rst
index a3031d0..a901fac 100644
--- a/docs/how-to-use/IntegrationTests.rst
+++ b/docs/how-to-use/IntegrationTests.rst
@@ -440,6 +440,17 @@ create_stack_tests.py - CreateStackKeypairTests
| | | deploying |
+---------------------------------------+---------------+-----------------------------------------------------------+
+create_stack_tests.py - CreateStackSecurityGroupTests
+-----------------------------------------------------
+
++---------------------------------------+---------------+-----------------------------------------------------------+
+| Test Name | Heat API | Description |
++=======================================+===============+===========================================================+
+| test_retrieve_security_group_creator | 1-3 | Ensures that an OpenStackHeatStack instance can return a |
+| | | OpenStackSecurityGroup instance that it was responsible |
+| | | for deploying |
++---------------------------------------+---------------+-----------------------------------------------------------+
+
create_stack_tests.py - CreateComplexStackTests
-----------------------------------------------
diff --git a/snaps/domain/network.py b/snaps/domain/network.py
index 448ee89..1f1b67c 100644
--- a/snaps/domain/network.py
+++ b/snaps/domain/network.py
@@ -206,15 +206,29 @@ class SecurityGroup:
Constructor
:param name: the security group's name
:param id: the security group's id
+ :param description: the security group's description
+ :param project_id: the security group's project_id
+ :param rules: list of SecurityGroupRule objects associated to this
"""
self.name = kwargs.get('name')
self.id = kwargs.get('id')
self.description = kwargs.get('description')
self.project_id = kwargs.get('project_id', kwargs.get('tenant_id'))
+ self.rules = list()
+ if kwargs.get('rules') and isinstance(kwargs.get('rules'), list):
+ for rule in kwargs.get('rules'):
+ if isinstance(rule, SecurityGroupRule):
+ self.rules.append(rule)
+ else:
+ self.rules.append(SecurityGroupRule(**rule))
+
def __eq__(self, other):
- return (self.name == other.name and self.id == other.id and
- self.project_id == other.project_id)
+ return (self.name == other.name and
+ self.id == other.id and
+ self.description == other.description and
+ self.project_id == other.project_id and
+ self.rules == other.rules)
class SecurityGroupRule:
@@ -226,7 +240,7 @@ class SecurityGroupRule:
"""
Constructor
:param id: the security group rule's id
- :param sec_grp_id: the ID of the associated security group
+ :param security_group_id: the ID of the associated security group
:param description: the security group rule's description
:param direction: the security group rule's direction
:param ethertype: the security group rule's ethertype
diff --git a/snaps/domain/test/network_tests.py b/snaps/domain/test/network_tests.py
index 3e449b4..04dc5a3 100644
--- a/snaps/domain/test/network_tests.py
+++ b/snaps/domain/test/network_tests.py
@@ -286,12 +286,33 @@ class SecurityGroupDomainObjectTests(unittest.TestCase):
def test_construction_proj_id_kwargs(self):
sec_grp = SecurityGroup(
**{'name': 'name', 'id': 'id', 'project_id': 'foo',
- 'description': 'test desc'})
+ 'description': 'test desc',
+ 'rules': [
+ {'id': 'id', 'security_group_id': 'grp_id',
+ 'description': 'desc', 'direction': 'dir',
+ 'ethertype': 'eType', 'port_range_min': '10.0.0.100',
+ 'port_range_max': '10.0.0.200', 'protocol': 'proto',
+ 'remote_group_id': 'group_id',
+ 'remote_ip_prefix': 'ip_prefix'}
+ ]})
self.assertEqual('name', sec_grp.name)
self.assertEqual('id', sec_grp.id)
self.assertEqual('test desc', sec_grp.description)
self.assertEqual('foo', sec_grp.project_id)
+ self.assertEqual(1, len(sec_grp.rules))
+ rule = sec_grp.rules[0]
+ self.assertEqual('id', rule.id)
+ self.assertEqual('grp_id', rule.security_group_id)
+ self.assertEqual('desc', rule.description)
+ self.assertEqual('dir', rule.direction)
+ self.assertEqual('eType', rule.ethertype)
+ self.assertEqual('10.0.0.100', rule.port_range_min)
+ self.assertEqual('10.0.0.200', rule.port_range_max)
+ self.assertEqual('proto', rule.protocol)
+ self.assertEqual('group_id', rule.remote_group_id)
+ self.assertEqual('ip_prefix', rule.remote_ip_prefix)
+
def test_construction_tenant_id_kwargs(self):
sec_grp = SecurityGroup(
**{'name': 'name', 'id': 'id',
@@ -300,15 +321,37 @@ class SecurityGroupDomainObjectTests(unittest.TestCase):
self.assertEqual('id', sec_grp.id)
self.assertEqual('foo', sec_grp.project_id)
self.assertIsNone(sec_grp.description)
+ self.assertEqual(0, len(sec_grp.rules))
def test_construction_named(self):
+ rules = [SecurityGroupRule(
+ **{'id': 'id', 'security_group_id': 'grp_id',
+ 'description': 'desc', 'direction': 'dir',
+ 'ethertype': 'eType', 'port_range_min': '10.0.0.100',
+ 'port_range_max': '10.0.0.200', 'protocol': 'proto',
+ 'remote_group_id': 'group_id',
+ 'remote_ip_prefix': 'ip_prefix'}
+ )]
sec_grp = SecurityGroup(description='test desc', tenant_id='foo',
- id='id', name='name')
+ id='id', name='name', rules=rules)
self.assertEqual('name', sec_grp.name)
self.assertEqual('id', sec_grp.id)
self.assertEqual('test desc', sec_grp.description)
self.assertEqual('foo', sec_grp.project_id)
+ self.assertEqual(1, len(sec_grp.rules))
+ rule = sec_grp.rules[0]
+ self.assertEqual('id', rule.id)
+ self.assertEqual('grp_id', rule.security_group_id)
+ self.assertEqual('desc', rule.description)
+ self.assertEqual('dir', rule.direction)
+ self.assertEqual('eType', rule.ethertype)
+ self.assertEqual('10.0.0.100', rule.port_range_min)
+ self.assertEqual('10.0.0.200', rule.port_range_max)
+ self.assertEqual('proto', rule.protocol)
+ self.assertEqual('group_id', rule.remote_group_id)
+ self.assertEqual('ip_prefix', rule.remote_ip_prefix)
+
class SecurityGroupRuleDomainObjectTests(unittest.TestCase):
"""
diff --git a/snaps/openstack/create_security_group.py b/snaps/openstack/create_security_group.py
index 6386e7f..5df33f3 100644
--- a/snaps/openstack/create_security_group.py
+++ b/snaps/openstack/create_security_group.py
@@ -66,6 +66,9 @@ class OpenStackSecurityGroup(OpenStackNetworkObject):
rule_setting = self.__get_setting_from_rule(existing_rule)
self.__rules[rule_setting] = existing_rule
+ self.__security_group = neutron_utils.get_security_group_by_id(
+ self._neutron, self.__security_group.id)
+
return self.__security_group
def create(self):
diff --git a/snaps/openstack/create_stack.py b/snaps/openstack/create_stack.py
index e230873..6075e7f 100644
--- a/snaps/openstack/create_stack.py
+++ b/snaps/openstack/create_stack.py
@@ -21,6 +21,7 @@ from heatclient.exc import HTTPNotFound
from snaps.openstack.create_flavor import OpenStackFlavor
from snaps.openstack.create_instance import OpenStackVmInstance
from snaps.openstack.create_keypairs import OpenStackKeypair
+from snaps.openstack.create_security_group import OpenStackSecurityGroup
from snaps.openstack.create_router import OpenStackRouter
from snaps.openstack.create_volume import OpenStackVolume
from snaps.openstack.create_volume_type import OpenStackVolumeType
@@ -235,6 +236,28 @@ class OpenStackHeatStack(OpenStackCloudObject, object):
return out
+ def get_security_group_creators(self):
+ """
+ Returns a list of security group creator objects as configured by the
+ heat template
+ :return: list() of OpenStackNetwork objects
+ """
+
+ neutron = neutron_utils.neutron_client(self._os_creds)
+
+ out = list()
+ stack_security_groups = heat_utils.get_stack_security_groups(
+ self.__heat_cli, neutron, self.__stack)
+
+ for stack_security_group in stack_security_groups:
+ settings = settings_utils.create_security_group_settings(
+ neutron, stack_security_group)
+ creator = OpenStackSecurityGroup(self._os_creds, settings)
+ out.append(creator)
+ creator.initialize()
+
+ return out
+
def get_router_creators(self):
"""
Returns a list of router creator objects as configured by the heat
diff --git a/snaps/openstack/tests/create_stack_tests.py b/snaps/openstack/tests/create_stack_tests.py
index 78f357a..690f3c8 100644
--- a/snaps/openstack/tests/create_stack_tests.py
+++ b/snaps/openstack/tests/create_stack_tests.py
@@ -789,6 +789,100 @@ class CreateStackKeypairTests(OSIntegrationTestCase):
self.assertEqual(creator.get_keypair(), keypair)
+class CreateStackSecurityGroupTests(OSIntegrationTestCase):
+ """
+ Tests for the OpenStackHeatStack class to ensure it returns an
+ OpenStackSecurityGroup object
+ """
+
+ def setUp(self):
+ """
+ Instantiates the CreateStack object that is responsible for downloading
+ and creating an OS stack file within OpenStack
+ """
+ super(self.__class__, self).__start__()
+
+ self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
+
+ self.heat_creds = self.admin_os_creds
+ self.heat_creds.project_name = self.admin_os_creds.project_name
+
+ self.heat_cli = heat_utils.heat_client(self.heat_creds)
+ self.nova = nova_utils.nova_client(self.heat_creds)
+ self.stack_creator = None
+
+ self.security_group_name = self.guid + '-sec-grp'
+
+ self.env_values = {
+ 'security_group_name': self.security_group_name}
+
+ self.heat_tmplt_path = pkg_resources.resource_filename(
+ 'snaps.openstack.tests.heat', 'security_group_heat_template.yaml')
+
+ stack_settings = StackSettings(
+ name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
+ template_path=self.heat_tmplt_path,
+ env_values=self.env_values)
+ self.stack_creator = create_stack.OpenStackHeatStack(
+ self.heat_creds, stack_settings)
+ self.created_stack = self.stack_creator.create()
+ self.assertIsNotNone(self.created_stack)
+
+ def tearDown(self):
+ """
+ Cleans the stack and downloaded stack file
+ """
+ if self.stack_creator:
+ try:
+ self.stack_creator.clean()
+ except:
+ pass
+
+ super(self.__class__, self).__clean__()
+
+ def test_retrieve_security_group_creator(self):
+ """
+ Tests the creation of an OpenStack stack from Heat template file and
+ the retrieval of an OpenStackSecurityGroup creator/state machine
+ instance
+ """
+ sec_grp_creators = self.stack_creator.get_security_group_creators()
+ self.assertEqual(1, len(sec_grp_creators))
+
+ creator = sec_grp_creators[0]
+ sec_grp = creator.get_security_group()
+
+ self.assertEqual(self.security_group_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)
+
+
class CreateStackNegativeTests(OSIntegrationTestCase):
"""
Negative test cases for the OpenStackHeatStack class with poor
diff --git a/snaps/openstack/tests/heat/security_group_heat_template.yaml b/snaps/openstack/tests/heat/security_group_heat_template.yaml
new file mode 100644
index 0000000..0c4f07b
--- /dev/null
+++ b/snaps/openstack/tests/heat/security_group_heat_template.yaml
@@ -0,0 +1,45 @@
+##############################################################################
+# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
+# and others. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+heat_template_version: 2015-04-30
+
+description: >
+ Sample template for creating a single SecurityGroup
+
+parameters:
+ security_group_name:
+ type: string
+ label: Security Group name
+ description: The name of the stack's security group
+ default: security_group_name
+
+resources:
+ server_security_group:
+ type: OS::Neutron::SecurityGroup
+ properties:
+ description: Test description
+ name: { get_param: security_group_name }
+ rules:
+ - direction: egress
+ ethertype: IPv4
+ port_range_min: 22
+ port_range_max: 22
+ protocol: tcp
+ remote_ip_prefix: 0.0.0.0/0
+ - direction: ingress
+ ethertype: IPv4
+ protocol: icmp
+ remote_ip_prefix: 0.0.0.0/0
diff --git a/snaps/openstack/utils/heat_utils.py b/snaps/openstack/utils/heat_utils.py
index 5b47280..be7e2f5 100644
--- a/snaps/openstack/utils/heat_utils.py
+++ b/snaps/openstack/utils/heat_utils.py
@@ -226,6 +226,26 @@ def get_stack_routers(heat_cli, neutron, stack):
return out
+def get_stack_security_groups(heat_cli, neutron, stack):
+ """
+ Returns a list of SecurityGroup domain objects deployed by this stack
+ :param heat_cli: the OpenStack heat client object
+ :param neutron: the OpenStack neutron client object
+ :param stack: the SNAPS-OO Stack domain object
+ :return: a list of SecurityGroup objects
+ """
+
+ out = list()
+ resources = get_resources(heat_cli, stack, 'OS::Neutron::SecurityGroup')
+ for resource in resources:
+ security_group = neutron_utils.get_security_group_by_id(
+ neutron, resource.id)
+ if security_group:
+ out.append(security_group)
+
+ return out
+
+
def get_stack_servers(heat_cli, nova, stack):
"""
Returns a list of VMInst domain objects associated with a Stack
diff --git a/snaps/openstack/utils/neutron_utils.py b/snaps/openstack/utils/neutron_utils.py
index 24c4afd..cce53a6 100644
--- a/snaps/openstack/utils/neutron_utils.py
+++ b/snaps/openstack/utils/neutron_utils.py
@@ -496,7 +496,7 @@ def create_security_group(neutron, keystone, sec_grp_settings):
sec_grp_settings.name)
os_group = neutron.create_security_group(
sec_grp_settings.dict_for_neutron(keystone))
- return SecurityGroup(**os_group['security_group'])
+ return __map_os_security_group(neutron, os_group['security_group'])
def delete_security_group(neutron, sec_grp):
@@ -540,7 +540,20 @@ def get_security_group(neutron, sec_grp_settings=None, sec_grp_name=None,
groups = neutron.list_security_groups(**sec_grp_filter)
for group in groups['security_groups']:
- return SecurityGroup(**group)
+ return __map_os_security_group(neutron, group)
+
+
+def __map_os_security_group(neutron, os_sec_grp):
+ """
+ Creates a SecurityGroup SNAPS domain object from an OpenStack Security
+ Group dict
+ :param neutron: the neutron client for performing rule lookups
+ :param os_sec_grp: the OpenStack Security Group dict object
+ :return: a SecurityGroup object
+ """
+ os_sec_grp['rules'] = get_rules_by_security_group_id(
+ neutron, os_sec_grp['id'])
+ return SecurityGroup(**os_sec_grp)
def get_security_group_by_id(neutron, sec_grp_id):
@@ -555,7 +568,7 @@ def get_security_group_by_id(neutron, sec_grp_id):
groups = neutron.list_security_groups(**{'id': sec_grp_id})
for group in groups['security_groups']:
if group['id'] == sec_grp_id:
- return SecurityGroup(**group)
+ return __map_os_security_group(neutron, group)
return None
@@ -590,13 +603,22 @@ def get_rules_by_security_group(neutron, sec_grp):
:param neutron: the client
:param sec_grp: a list of SNAPS SecurityGroupRule domain objects
"""
+ return get_rules_by_security_group_id(neutron, sec_grp.id)
+
+
+def get_rules_by_security_group_id(neutron, sec_grp_id):
+ """
+ Retrieves all of the rules for a given security group
+ :param neutron: the client
+ :param sec_grp_id: the ID of the associated security group
+ """
logger.info('Retrieving security group rules associate with the '
- 'security group - %s', sec_grp.name)
+ 'security group with ID - %s', sec_grp_id)
out = list()
rules = neutron.list_security_group_rules(
- **{'security_group_id': sec_grp.id})
+ **{'security_group_id': sec_grp_id})
for rule in rules['security_group_rules']:
- if rule['security_group_id'] == sec_grp.id:
+ if rule['security_group_id'] == sec_grp_id:
out.append(SecurityGroupRule(**rule))
return out
diff --git a/snaps/openstack/utils/settings_utils.py b/snaps/openstack/utils/settings_utils.py
index 2e29063..ea1d018 100644
--- a/snaps/openstack/utils/settings_utils.py
+++ b/snaps/openstack/utils/settings_utils.py
@@ -21,6 +21,8 @@ from snaps.openstack.create_instance import (
from snaps.openstack.create_keypairs import KeypairSettings
from snaps.openstack.create_network import (
PortSettings, SubnetSettings, NetworkSettings)
+from snaps.openstack.create_security_group import (
+ SecurityGroupSettings, SecurityGroupRuleSettings)
from snaps.openstack.create_router import RouterSettings
from snaps.openstack.create_volume import VolumeSettings
from snaps.openstack.create_volume_type import (
@@ -41,6 +43,30 @@ def create_network_settings(neutron, network):
subnet_settings=create_subnet_settings(neutron, network))
+def create_security_group_settings(neutron, security_group):
+ """
+ Returns a NetworkSettings object
+ :param neutron: the neutron client
+ :param security_group: a SNAPS-OO SecurityGroup domain object
+ :return:
+ """
+ rules = neutron_utils.get_rules_by_security_group(neutron, security_group)
+
+ rule_settings = list()
+ for rule in rules:
+ rule_settings.append(SecurityGroupRuleSettings(
+ sec_grp_name=security_group.name, description=rule.description,
+ direction=rule.direction, ethertype=rule.ethertype,
+ port_range_min=rule.port_range_min,
+ port_range_max=rule.port_range_max, protocol=rule.protocol,
+ remote_group_id=rule.remote_group_id,
+ remote_ip_prefix=rule.remote_ip_prefix))
+
+ return SecurityGroupSettings(
+ name=security_group.name, description=security_group.description,
+ rule_settings=rule_settings)
+
+
def create_subnet_settings(neutron, network):
"""
Returns a list of SubnetSettings objects for a given network
diff --git a/snaps/openstack/utils/tests/heat_utils_tests.py b/snaps/openstack/utils/tests/heat_utils_tests.py
index 56bed6b..4373b8a 100644
--- a/snaps/openstack/utils/tests/heat_utils_tests.py
+++ b/snaps/openstack/utils/tests/heat_utils_tests.py
@@ -116,7 +116,7 @@ class HeatUtilsCreateSimpleStackTests(OSComponentTestCase):
def tearDown(self):
"""
- Cleans the image and downloaded image file
+ Cleans the stack and image
"""
if self.stack1:
try:
@@ -279,7 +279,7 @@ class HeatUtilsCreateComplexStackTests(OSComponentTestCase):
def tearDown(self):
"""
- Cleans the image and downloaded image file
+ Cleans the stack and image
"""
if self.stack:
try:
@@ -513,7 +513,7 @@ class HeatUtilsVolumeTests(OSComponentTestCase):
def tearDown(self):
"""
- Cleans the image and downloaded image file
+ Cleans the stack
"""
if self.stack:
try:
@@ -592,7 +592,7 @@ class HeatUtilsFlavorTests(OSComponentTestCase):
def tearDown(self):
"""
- Cleans the image and downloaded image file
+ Cleans the stack
"""
if self.stack:
try:
@@ -638,8 +638,7 @@ class HeatUtilsKeypairTests(OSComponentTestCase):
stack_name = guid + '-stack'
self.keypair_name = guid + '-kp'
- env_values = {
- 'keypair_name': self.keypair_name}
+ env_values = {'keypair_name': self.keypair_name}
heat_tmplt_path = pkg_resources.resource_filename(
'snaps.openstack.tests.heat', 'keypair_heat_template.yaml')
@@ -652,7 +651,7 @@ class HeatUtilsKeypairTests(OSComponentTestCase):
def tearDown(self):
"""
- Cleans the image and downloaded image file
+ Cleans the stack
"""
if self.stack:
try:
@@ -689,6 +688,82 @@ class HeatUtilsKeypairTests(OSComponentTestCase):
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 = StackSettings(
+ 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.neutron = neutron_utils.neutron_client(self.os_creds)
+
+ def tearDown(self):
+ """
+ Cleans the stack
+ """
+ if self.stack:
+ try:
+ heat_utils.delete_stack(self.heat_client, self.stack)
+ except:
+ pass
+
+ 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
diff --git a/snaps/test_suite_builder.py b/snaps/test_suite_builder.py
index 6d2ba5f..e0d6ce8 100644
--- a/snaps/test_suite_builder.py
+++ b/snaps/test_suite_builder.py
@@ -69,7 +69,8 @@ from snaps.openstack.tests.create_security_group_tests import (
from snaps.openstack.tests.create_stack_tests import (
StackSettingsUnitTests, CreateStackSuccessTests, CreateStackNegativeTests,
CreateStackFlavorTests, CreateStackFloatingIpTests,
- CreateStackKeypairTests, CreateStackVolumeTests)
+ CreateStackKeypairTests, CreateStackVolumeTests,
+ CreateStackSecurityGroupTests)
from snaps.openstack.tests.create_user_tests import (
UserSettingsUnitTests, CreateUserSuccessTests)
from snaps.openstack.tests.create_volume_tests import (
@@ -90,7 +91,7 @@ from snaps.openstack.utils.tests.glance_utils_tests import (
from snaps.openstack.utils.tests.heat_utils_tests import (
HeatSmokeTests, HeatUtilsCreateSimpleStackTests,
HeatUtilsCreateComplexStackTests, HeatUtilsFlavorTests,
- HeatUtilsKeypairTests, HeatUtilsVolumeTests)
+ HeatUtilsKeypairTests, HeatUtilsVolumeTests, HeatUtilsSecurityGroupTests)
from snaps.openstack.utils.tests.keystone_utils_tests import (
KeystoneSmokeTests, KeystoneUtilsTests)
from snaps.openstack.utils.tests.neutron_utils_tests import (
@@ -340,6 +341,10 @@ def add_openstack_api_tests(suite, os_creds, ext_net_name, use_keystone=True,
ext_net_name=ext_net_name, log_level=log_level,
image_metadata=image_metadata))
suite.addTest(OSComponentTestCase.parameterize(
+ HeatUtilsSecurityGroupTests, os_creds=os_creds,
+ ext_net_name=ext_net_name, log_level=log_level,
+ image_metadata=image_metadata))
+ suite.addTest(OSComponentTestCase.parameterize(
CinderUtilsQoSTests, os_creds=os_creds,
ext_net_name=ext_net_name, log_level=log_level,
image_metadata=image_metadata))
@@ -536,6 +541,11 @@ def add_openstack_integration_tests(suite, os_creds, ext_net_name,
flavor_metadata=flavor_metadata, image_metadata=image_metadata,
log_level=log_level))
suite.addTest(OSIntegrationTestCase.parameterize(
+ CreateStackSecurityGroupTests, os_creds=os_creds,
+ ext_net_name=ext_net_name, use_keystone=use_keystone,
+ flavor_metadata=flavor_metadata, image_metadata=image_metadata,
+ log_level=log_level))
+ suite.addTest(OSIntegrationTestCase.parameterize(
CreateStackNegativeTests, os_creds=os_creds, ext_net_name=ext_net_name,
use_keystone=use_keystone,
flavor_metadata=flavor_metadata, image_metadata=image_metadata,