diff options
author | spisarski <s.pisarski@cablelabs.com> | 2017-08-09 14:17:26 -0600 |
---|---|---|
committer | spisarski <s.pisarski@cablelabs.com> | 2017-08-09 14:37:41 -0600 |
commit | 2b9b2d64c5be98405aaaf98db58f06b35b8af983 (patch) | |
tree | 7eac6cb5a5182371b5602e53bb613234c5eff11c /snaps/openstack/utils | |
parent | 430905e7f76e4a074167a49ca2bfbf727eebcefd (diff) |
SNAPS Stack creators can now return SNAPS network creators.
As Heat Stacks are responsible for spawning objects in OpenStack,
the class OpenStackHeatStack which is responsible for applying and
managing the state of a stack now can retrieve OpenStackNetwork
objects for the networks created in the stack for clients who would
like to query the networks and subnets or update them outside of
Heat.
JIRA: SNAPS-171
Change-Id: I9bf0b81d4f7bfeb1b6392f345022c7d9a57d0415
Signed-off-by: spisarski <s.pisarski@cablelabs.com>
Diffstat (limited to 'snaps/openstack/utils')
-rw-r--r-- | snaps/openstack/utils/heat_utils.py | 52 | ||||
-rw-r--r-- | snaps/openstack/utils/neutron_utils.py | 29 | ||||
-rw-r--r-- | snaps/openstack/utils/tests/heat_utils_tests.py | 30 | ||||
-rw-r--r-- | snaps/openstack/utils/tests/neutron_utils_tests.py | 60 |
4 files changed, 154 insertions, 17 deletions
diff --git a/snaps/openstack/utils/heat_utils.py b/snaps/openstack/utils/heat_utils.py index a91a21c..c2919cb 100644 --- a/snaps/openstack/utils/heat_utils.py +++ b/snaps/openstack/utils/heat_utils.py @@ -20,9 +20,9 @@ from heatclient.common.template_format import yaml_loader from oslo_serialization import jsonutils from snaps import file_utils -from snaps.domain.stack import Stack +from snaps.domain.stack import Stack, Resource -from snaps.openstack.utils import keystone_utils +from snaps.openstack.utils import keystone_utils, neutron_utils __author__ = 'spisarski' @@ -130,6 +130,54 @@ def delete_stack(heat_cli, stack): heat_cli.stacks.delete(stack.id) +def __get_os_resources(heat_cli, stack): + """ + Returns all of the OpenStack resource objects for a given stack + :param heat_cli: the OpenStack heat client + :param stack: the SNAPS-OO Stack domain object + :return: a list + """ + return heat_cli.resources.list(stack.id) + + +def get_resources(heat_cli, stack): + """ + Returns all of the OpenStack resource objects for a given stack + :param heat_cli: the OpenStack heat client + :param stack: the SNAPS-OO Stack domain object + :return: a list + """ + os_resources = __get_os_resources(heat_cli, stack) + + if os_resources: + out = list() + for os_resource in os_resources: + out.append(Resource(resource_type=os_resource.resource_type, + resource_id=os_resource.physical_resource_id)) + return out + + +def get_stack_networks(heat_cli, neutron, stack): + """ + Returns an instance of NetworkSettings for each network owned 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 NetworkSettings + """ + + out = list() + resources = get_resources(heat_cli, stack) + for resource in resources: + if resource.type == 'OS::Neutron::Net': + network = neutron_utils.get_network_by_id( + neutron, resource.id) + if network: + out.append(network) + + return out + + def parse_heat_template_str(tmpl_str): """ Takes a heat template string, performs some simple validation and returns a diff --git a/snaps/openstack/utils/neutron_utils.py b/snaps/openstack/utils/neutron_utils.py index e7b002a..076557b 100644 --- a/snaps/openstack/utils/neutron_utils.py +++ b/snaps/openstack/utils/neutron_utils.py @@ -187,6 +187,35 @@ def get_subnet(neutron, subnet_settings=None, subnet_name=None): return Subnet(**subnet) +def get_subnet_by_id(neutron, subnet_id): + """ + Returns a SNAPS-OO Subnet domain object for a given ID + :param neutron: the OpenStack neutron client + :param subnet_id: the subnet ID + :return: a Subnet object + """ + os_subnet = neutron.show_subnet(subnet_id) + if os_subnet and 'subnet' in os_subnet: + return Subnet(**os_subnet['subnet']) + + +def get_subnets_by_network(neutron, network): + """ + Returns a list of SNAPS-OO Subnet domain objects + :param neutron: the OpenStack neutron client + :param network: the SNAPS-OO Network domain object + :return: a list of Subnet objects + """ + out = list() + + os_subnets = neutron.list_subnets(network_id=network.id) + + for os_subnet in os_subnets['subnets']: + out.append(Subnet(**os_subnet)) + + return out + + def create_router(neutron, os_creds, router_settings): """ Creates a router for OpenStack diff --git a/snaps/openstack/utils/tests/heat_utils_tests.py b/snaps/openstack/utils/tests/heat_utils_tests.py index 16ce9fb..92432f6 100644 --- a/snaps/openstack/utils/tests/heat_utils_tests.py +++ b/snaps/openstack/utils/tests/heat_utils_tests.py @@ -25,7 +25,7 @@ from snaps.openstack.create_image import OpenStackImage from snaps.openstack.create_stack import StackSettings from snaps.openstack.tests import openstack_tests from snaps.openstack.tests.os_source_file_test import OSComponentTestCase -from snaps.openstack.utils import heat_utils +from snaps.openstack.utils import heat_utils, neutron_utils __author__ = 'spisarski' @@ -77,13 +77,14 @@ class HeatUtilsCreateStackTests(OSComponentTestCase): Instantiates OpenStack instances that cannot be spawned by Heat """ guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) - stack_name1 = self.__class__.__name__ + '-' + str(guid) + '-stack1' - stack_name2 = self.__class__.__name__ + '-' + str(guid) + '-stack2' + stack_name1 = guid + '-stack1' + stack_name2 = guid + '-stack2' + self.network_name = guid + '-net' + self.subnet_name = guid + '-subnet' self.image_creator = OpenStackImage( self.os_creds, openstack_tests.cirros_image_settings( - name=self.__class__.__name__ + '-' + str(guid) + '-image', - image_metadata=self.image_metadata)) + name=guid + '-image', image_metadata=self.image_metadata)) self.image_creator.create() # Create Flavor @@ -93,7 +94,9 @@ class HeatUtilsCreateStackTests(OSComponentTestCase): self.flavor_creator.create() env_values = {'image_name': self.image_creator.image_settings.name, - 'flavor_name': self.flavor_creator.flavor_settings.name} + 'flavor_name': self.flavor_creator.flavor_settings.name, + 'net_name': self.network_name, + 'subnet_name': self.subnet_name} heat_tmplt_path = pkg_resources.resource_filename( 'snaps.openstack.tests.heat', 'test_heat_template.yaml') self.stack_settings1 = StackSettings( @@ -175,6 +178,21 @@ class HeatUtilsCreateStackTests(OSComponentTestCase): self.assertTrue(is_active) + resources = heat_utils.get_resources(self.heat_client, self.stack1) + self.assertIsNotNone(resources) + self.assertEqual(4, len(resources)) + + neutron = neutron_utils.neutron_client(self.os_creds) + networks = heat_utils.get_stack_networks( + self.heat_client, neutron, self.stack1) + self.assertIsNotNone(networks) + self.assertEqual(1, len(networks)) + self.assertEqual(self.network_name, networks[0].name) + + subnets = neutron_utils.get_subnets_by_network(neutron, networks[0]) + self.assertEqual(1, len(subnets)) + self.assertEqual(self.subnet_name, subnets[0].name) + def test_create_stack_x2(self): """ Tests the creation of an OpenStack keypair that does not exist. diff --git a/snaps/openstack/utils/tests/neutron_utils_tests.py b/snaps/openstack/utils/tests/neutron_utils_tests.py index f6fc2bb..5493f5b 100644 --- a/snaps/openstack/utils/tests/neutron_utils_tests.py +++ b/snaps/openstack/utils/tests/neutron_utils_tests.py @@ -152,9 +152,15 @@ class NeutronUtilsSubnetTests(OSComponentTestCase): Cleans the remote OpenStack objects """ if self.subnet: - neutron_utils.delete_subnet(self.neutron, self.subnet) + try: + neutron_utils.delete_subnet(self.neutron, self.subnet) + except: + pass if self.network: - neutron_utils.delete_network(self.neutron, self.network) + try: + neutron_utils.delete_network(self.neutron, self.network) + except: + pass def test_create_subnet(self): """ @@ -173,6 +179,16 @@ class NeutronUtilsSubnetTests(OSComponentTestCase): self.assertTrue(validate_subnet( self.neutron, subnet_setting.name, subnet_setting.cidr, True)) + subnet_query1 = neutron_utils.get_subnet( + self.neutron, subnet_name=subnet_setting.name) + self.assertEqual(self.subnet, subnet_query1) + + subnet_query2 = neutron_utils.get_subnets_by_network(self.neutron, + self.network) + self.assertIsNotNone(subnet_query2) + self.assertEqual(1, len(subnet_query2)) + self.assertEqual(self.subnet, subnet_query2[0]) + def test_create_subnet_null_name(self): """ Tests the neutron_utils.create_neutron_subnet() function for an @@ -201,13 +217,23 @@ class NeutronUtilsSubnetTests(OSComponentTestCase): self.neutron, self.net_config.network_settings.name, True)) subnet_setting = self.net_config.network_settings.subnet_settings[0] - neutron_utils.create_subnet( + self.subnet = neutron_utils.create_subnet( self.neutron, subnet_setting, self.os_creds, network=self.network) self.assertTrue(validate_subnet( self.neutron, subnet_setting.name, subnet_setting.cidr, True)) self.assertFalse(validate_subnet( self.neutron, '', subnet_setting.cidr, True)) + subnet_query1 = neutron_utils.get_subnet( + self.neutron, subnet_name=subnet_setting.name) + self.assertEqual(self.subnet, subnet_query1) + + subnet_query2 = neutron_utils.get_subnets_by_network(self.neutron, + self.network) + self.assertIsNotNone(subnet_query2) + self.assertEqual(1, len(subnet_query2)) + self.assertEqual(self.subnet, subnet_query2[0]) + def test_create_subnet_null_cidr(self): """ Tests the neutron_utils.create_neutron_subnet() function for an @@ -272,17 +298,29 @@ class NeutronUtilsRouterTests(OSComponentTestCase): self.subnet) if self.router: - neutron_utils.delete_router(self.neutron, self.router) - validate_router(self.neutron, self.router.name, False) + try: + neutron_utils.delete_router(self.neutron, self.router) + validate_router(self.neutron, self.router.name, False) + except: + pass if self.port: - neutron_utils.delete_port(self.neutron, self.port) + try: + neutron_utils.delete_port(self.neutron, self.port) + except: + pass if self.subnet: - neutron_utils.delete_subnet(self.neutron, self.subnet) + try: + neutron_utils.delete_subnet(self.neutron, self.subnet) + except: + pass if self.network: - neutron_utils.delete_network(self.neutron, self.network) + try: + neutron_utils.delete_network(self.neutron, self.network) + except: + pass def test_create_router_simple(self): """ @@ -757,7 +795,11 @@ class NeutronUtilsFloatingIpTests(OSComponentTestCase): Cleans the image and downloaded image file """ if self.floating_ip: - neutron_utils.delete_floating_ip(self.neutron, self.floating_ip) + try: + neutron_utils.delete_floating_ip( + self.neutron, self.floating_ip) + except: + pass def test_floating_ips(self): """ |