summaryrefslogtreecommitdiffstats
path: root/snaps/openstack/tests
diff options
context:
space:
mode:
authorspisarski <s.pisarski@cablelabs.com>2017-08-17 15:21:37 -0600
committerSteven Pisarski <s.pisarski@cablelabs.com>2017-08-24 21:12:02 +0000
commit1342eb17df248ec75cc57e9c380a7753fc432194 (patch)
tree72a3b065394b7bcaaddb801e3321edc1ba4b8818 /snaps/openstack/tests
parent49aaa5d61e87e11c5d5b9ce7dd2fa598f16b82a7 (diff)
Added method to return OpenStackVmInstance from Heat.
OpenStackHeatStack now can introspect the VMs that the template was responsible for deploying and return an instanitated instance of OpenStackVmInstance for each VM deployed. When the VM has a Floating IP, these instances have the ability to connect via SSH just like one created from scratch. JIRA: SNAPS-172 Change-Id: I5a7ed3a09bb871afc55c718aa80a9069b1eb4da7 Signed-off-by: spisarski <s.pisarski@cablelabs.com>
Diffstat (limited to 'snaps/openstack/tests')
-rw-r--r--snaps/openstack/tests/create_instance_tests.py26
-rw-r--r--snaps/openstack/tests/create_keypairs_tests.py6
-rw-r--r--snaps/openstack/tests/create_stack_tests.py149
-rw-r--r--snaps/openstack/tests/heat/floating_ip_heat_template.yaml161
-rw-r--r--snaps/openstack/tests/heat/test_heat_template.yaml22
5 files changed, 339 insertions, 25 deletions
diff --git a/snaps/openstack/tests/create_instance_tests.py b/snaps/openstack/tests/create_instance_tests.py
index 19173d2..9c872bc 100644
--- a/snaps/openstack/tests/create_instance_tests.py
+++ b/snaps/openstack/tests/create_instance_tests.py
@@ -210,11 +210,22 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
with self.assertRaises(FloatingIpSettingsError):
FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'})
- def test_name_port_router_only(self):
+ def test_name_port_router_name_only(self):
settings = FloatingIpSettings(name='foo', port_name='foo-port',
router_name='bar-router')
self.assertEqual('foo', settings.name)
self.assertEqual('foo-port', settings.port_name)
+ self.assertIsNone(settings.port_id)
+ self.assertEqual('bar-router', settings.router_name)
+ self.assertIsNone(settings.subnet_name)
+ self.assertTrue(settings.provisioning)
+
+ def test_name_port_router_id_only(self):
+ settings = FloatingIpSettings(name='foo', port_id='foo-port',
+ router_name='bar-router')
+ self.assertEqual('foo', settings.name)
+ self.assertEqual('foo-port', settings.port_id)
+ self.assertIsNone(settings.port_name)
self.assertEqual('bar-router', settings.router_name)
self.assertIsNone(settings.subnet_name)
self.assertTrue(settings.provisioning)
@@ -225,6 +236,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
'router_name': 'bar-router'})
self.assertEqual('foo', settings.name)
self.assertEqual('foo-port', settings.port_name)
+ self.assertIsNone(settings.port_id)
self.assertEqual('bar-router', settings.router_name)
self.assertIsNone(settings.subnet_name)
self.assertTrue(settings.provisioning)
@@ -236,6 +248,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
provisioning=False)
self.assertEqual('foo', settings.name)
self.assertEqual('foo-port', settings.port_name)
+ self.assertIsNone(settings.port_id)
self.assertEqual('bar-router', settings.router_name)
self.assertEqual('bar-subnet', settings.subnet_name)
self.assertFalse(settings.provisioning)
@@ -247,6 +260,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase):
'provisioning': False})
self.assertEqual('foo', settings.name)
self.assertEqual('foo-port', settings.port_name)
+ self.assertIsNone(settings.port_id)
self.assertEqual('bar-router', settings.router_name)
self.assertEqual('bar-subnet', settings.subnet_name)
self.assertFalse(settings.provisioning)
@@ -672,7 +686,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
self.assertEqual(ip_1, inst_creator.get_port_ip(self.port_1_name))
self.assertTrue(inst_creator.vm_active(block=True))
- self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+ self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
def test_ssh_client_fip_before_active(self):
"""
@@ -706,7 +720,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
inst_creator.add_security_group(
self.sec_grp_creator.get_security_group())
- self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+ self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
self.assertTrue(validate_ssh_client(inst_creator))
@@ -744,7 +758,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
inst_creator.add_security_group(
self.sec_grp_creator.get_security_group())
- self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+ self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
self.assertTrue(validate_ssh_client(inst_creator))
@@ -782,7 +796,7 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
inst_creator.add_security_group(
self.sec_grp_creator.get_security_group())
- self.assertEqual(vm_inst, inst_creator.get_vm_inst())
+ self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
self.assertTrue(validate_ssh_client(inst_creator))
@@ -1434,7 +1448,7 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
vm_inst = self.inst_creator.create(block=True)
- self.assertEqual(vm_inst, self.inst_creator.get_vm_inst())
+ self.assertEqual(vm_inst.id, self.inst_creator.get_vm_inst().id)
# Effectively blocks until VM has been properly activated
self.assertTrue(self.inst_creator.vm_active(block=True))
diff --git a/snaps/openstack/tests/create_keypairs_tests.py b/snaps/openstack/tests/create_keypairs_tests.py
index 7b75d05..d2de6fe 100644
--- a/snaps/openstack/tests/create_keypairs_tests.py
+++ b/snaps/openstack/tests/create_keypairs_tests.py
@@ -332,7 +332,7 @@ class CreateKeypairsTests(OSIntegrationTestCase):
:return:
"""
keys = nova_utils.create_keys()
- nova_utils.save_keys_to_files(keys=keys,
+ file_utils.save_keys_to_files(keys=keys,
pub_file_path=self.pub_file_path)
self.keypair_creator = OpenStackKeypair(
self.os_creds, KeypairSettings(name=self.keypair_name,
@@ -448,7 +448,7 @@ class CreateKeypairsCleanupTests(OSIntegrationTestCase):
:return:
"""
keys = nova_utils.create_keys()
- nova_utils.save_keys_to_files(
+ file_utils.save_keys_to_files(
keys=keys, pub_file_path=self.pub_file_path,
priv_file_path=self.priv_file_path)
self.keypair_creator = OpenStackKeypair(
@@ -468,7 +468,7 @@ class CreateKeypairsCleanupTests(OSIntegrationTestCase):
:return:
"""
keys = nova_utils.create_keys()
- nova_utils.save_keys_to_files(
+ file_utils.save_keys_to_files(
keys=keys, pub_file_path=self.pub_file_path,
priv_file_path=self.priv_file_path)
self.keypair_creator = OpenStackKeypair(
diff --git a/snaps/openstack/tests/create_stack_tests.py b/snaps/openstack/tests/create_stack_tests.py
index 967e803..d2b138e 100644
--- a/snaps/openstack/tests/create_stack_tests.py
+++ b/snaps/openstack/tests/create_stack_tests.py
@@ -31,9 +31,9 @@ import uuid
from snaps.openstack import create_stack
from snaps.openstack.create_stack import StackSettings, StackSettingsError
-from snaps.openstack.tests import openstack_tests
+from snaps.openstack.tests import openstack_tests, create_instance_tests
from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
-from snaps.openstack.utils import heat_utils, neutron_utils
+from snaps.openstack.utils import heat_utils, neutron_utils, nova_utils
__author__ = 'spisarski'
@@ -122,7 +122,7 @@ class StackSettingsUnitTests(unittest.TestCase):
class CreateStackSuccessTests(OSIntegrationTestCase):
"""
- Test for the CreateStack class defined in create_stack.py
+ Tests for the CreateStack class defined in create_stack.py
"""
def setUp(self):
@@ -155,11 +155,14 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.network_name = self.guid + '-net'
self.subnet_name = self.guid + '-subnet'
+ self.vm_inst_name = self.guid + '-inst'
+
self.env_values = {
'image_name': self.image_creator.image_settings.name,
'flavor_name': self.flavor_creator.flavor_settings.name,
'net_name': self.network_name,
- 'subnet_name': self.subnet_name}
+ 'subnet_name': self.subnet_name,
+ 'inst_name': self.vm_inst_name}
self.heat_tmplt_path = pkg_resources.resource_filename(
'snaps.openstack.tests.heat', 'test_heat_template.yaml')
@@ -209,13 +212,7 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack.name, retrieved_stack.name)
self.assertEqual(created_stack.id, retrieved_stack.id)
- self.assertIsNotNone(self.stack_creator.get_outputs())
- self.assertEquals(0, len(self.stack_creator.get_outputs()))
-
- resources = heat_utils.get_resources(
- self.heat_cli, self.stack_creator.get_stack())
- self.assertIsNotNone(resources)
- self.assertEqual(4, len(resources))
+ self.assertEqual(0, len(self.stack_creator.get_outputs()))
def test_create_stack_template_dict(self):
"""
@@ -240,8 +237,7 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack.name, retrieved_stack.name)
self.assertEqual(created_stack.id, retrieved_stack.id)
- self.assertIsNotNone(self.stack_creator.get_outputs())
- self.assertEquals(0, len(self.stack_creator.get_outputs()))
+ self.assertEqual(0, len(self.stack_creator.get_outputs()))
def test_create_delete_stack(self):
"""
@@ -265,8 +261,7 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack.name, retrieved_stack.name)
self.assertEqual(created_stack.id, retrieved_stack.id)
- self.assertIsNotNone(self.stack_creator.get_outputs())
- self.assertEquals(0, len(self.stack_creator.get_outputs()))
+ self.assertEqual(0, len(self.stack_creator.get_outputs()))
self.assertEqual(create_stack.STATUS_CREATE_COMPLETE,
self.stack_creator.get_status())
@@ -309,7 +304,6 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack1.name, retrieved_stack.name)
self.assertEqual(created_stack1.id, retrieved_stack.id)
- self.assertIsNotNone(self.stack_creator.get_outputs())
self.assertEqual(0, len(self.stack_creator.get_outputs()))
# Should be retrieving the instance data
@@ -354,6 +348,129 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.assertIsNotNone(subnet_by_id)
self.assertEqual(subnet_by_name, subnet_by_id)
+ def test_retrieve_vm_inst_creators(self):
+ """
+ Tests the creation of an OpenStack stack from Heat template file and
+ the retrieval of the network creator.
+ """
+ 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)
+ created_stack = self.stack_creator.create()
+ self.assertIsNotNone(created_stack)
+
+ vm_inst_creators = self.stack_creator.get_vm_inst_creators()
+ self.assertIsNotNone(vm_inst_creators)
+ self.assertEqual(1, len(vm_inst_creators))
+ self.assertEqual(self.vm_inst_name,
+ vm_inst_creators[0].get_vm_inst().name)
+
+ nova = nova_utils.nova_client(self.admin_os_creds)
+ vm_inst_by_name = nova_utils.get_server(
+ nova, server_name=vm_inst_creators[0].get_vm_inst().name)
+ self.assertEqual(vm_inst_creators[0].get_vm_inst(), vm_inst_by_name)
+ self.assertIsNotNone(nova_utils.get_server_object_by_id(
+ nova, vm_inst_creators[0].get_vm_inst().id))
+
+
+class CreateComplexStackTests(OSIntegrationTestCase):
+ """
+ Tests for the CreateStack class defined in create_stack.py
+ """
+
+ 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.stack_creator = None
+
+ self.image_creator = OpenStackImage(
+ self.heat_creds, openstack_tests.cirros_image_settings(
+ name=self.guid + '-image',
+ image_metadata=self.image_metadata))
+ self.image_creator.create()
+
+ self.network_name = self.guid + '-net'
+ self.subnet_name = self.guid + '-subnet'
+ self.flavor1_name = self.guid + '-flavor1'
+ self.flavor2_name = self.guid + '-flavor2'
+ self.vm_inst1_name = self.guid + '-inst1'
+ self.vm_inst2_name = self.guid + '-inst2'
+ self.keypair_name = self.guid + '-kp'
+
+ self.env_values = {
+ 'image1_name': self.image_creator.image_settings.name,
+ 'image2_name': self.image_creator.image_settings.name,
+ 'flavor1_name': self.flavor1_name,
+ 'flavor2_name': self.flavor2_name,
+ 'net_name': self.network_name,
+ 'subnet_name': self.subnet_name,
+ 'inst1_name': self.vm_inst1_name,
+ 'inst2_name': self.vm_inst2_name,
+ 'keypair_name': self.keypair_name}
+
+ self.heat_tmplt_path = pkg_resources.resource_filename(
+ 'snaps.openstack.tests.heat', 'floating_ip_heat_template.yaml')
+
+ def tearDown(self):
+ """
+ Cleans the stack and downloaded stack file
+ """
+ if self.stack_creator:
+ try:
+ self.stack_creator.clean()
+ except:
+ pass
+
+ if self.image_creator:
+ try:
+ self.image_creator.clean()
+ except:
+ pass
+
+ super(self.__class__, self).__clean__()
+
+ def test_connect_via_ssh_heat_vm(self):
+ """
+ Tests the creation of an OpenStack stack from Heat template file and
+ the retrieval of two VM instance creators and attempt to connect via
+ SSH to the first one with a floating IP.
+ """
+ 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.image_creator.image_settings])
+ created_stack = self.stack_creator.create()
+ self.assertIsNotNone(created_stack)
+
+ vm_inst_creators = self.stack_creator.get_vm_inst_creators(
+ heat_keypair_option='private_key')
+ self.assertIsNotNone(vm_inst_creators)
+ self.assertEqual(2, len(vm_inst_creators))
+
+ for vm_inst_creator in vm_inst_creators:
+ if vm_inst_creator.get_vm_inst().name == self.vm_inst1_name:
+ self.assertTrue(
+ create_instance_tests.validate_ssh_client(vm_inst_creator))
+ else:
+ vm_settings = vm_inst_creator.instance_settings
+ self.assertEqual(0, len(vm_settings.floating_ip_settings))
+
class CreateStackNegativeTests(OSIntegrationTestCase):
"""
diff --git a/snaps/openstack/tests/heat/floating_ip_heat_template.yaml b/snaps/openstack/tests/heat/floating_ip_heat_template.yaml
new file mode 100644
index 0000000..9da1cb7
--- /dev/null
+++ b/snaps/openstack/tests/heat/floating_ip_heat_template.yaml
@@ -0,0 +1,161 @@
+##############################################################################
+# 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 with two VMs instantiated against different images and
+ flavors on the same network and the first one has a floating IP
+
+parameters:
+ image1_name:
+ type: string
+ label: Image ID for first VM
+ description: Image name to be used for first instance
+ default: image_1
+ image2_name:
+ type: string
+ label: Image ID for second VM
+ description: Image name to be used for second instance
+ default: image_2
+ flavor1_name:
+ type: string
+ label: Instance Flavor for first VM
+ description: Flavor name for the first instance
+ default: m1.small
+ flavor2_name:
+ type: string
+ label: Instance Flavor for second VM
+ description: Flavor name for the second instance
+ default: m1.med
+ net_name:
+ type: string
+ label: Test network name
+ description: The name of the stack's network
+ default: test_net
+ subnet_name:
+ type: string
+ label: Test subnet name
+ description: The name of the stack's subnet
+ default: test_subnet
+ router_name:
+ type: string
+ label: Test router name
+ description: The name of the stack's router
+ default: mgmt_router
+ keypair_name:
+ type: string
+ label: Keypair name
+ description: The name of the stack's keypair
+ default: keypair_name
+ inst1_name:
+ type: string
+ label: First VM name
+ description: The name of the first VM to be spawned
+ default: test_vm1
+ inst2_name:
+ type: string
+ label: Second VM name
+ description: The name of the second VM to be spawned
+ default: test_vm2
+ external_net_name:
+ type: string
+ description: Name of the external network which management network will connect to
+ default: external
+
+resources:
+ flavor1:
+ type: OS::Nova::Flavor
+ properties:
+ ram: 4096
+ vcpus: 4
+ disk: 4
+ flavor2:
+ type: OS::Nova::Flavor
+ properties:
+ ram: 4096
+ vcpus: 4
+ disk: 4
+
+ network:
+ type: OS::Neutron::Net
+ properties:
+ name: { get_param: net_name }
+
+ subnet:
+ type: OS::Neutron::Subnet
+ properties:
+ name: { get_param: subnet_name }
+ ip_version: 4
+ cidr: 10.1.2.0/24
+ network: { get_resource: network }
+
+ management_router:
+ type: OS::Neutron::Router
+ properties:
+ name: { get_param: router_name }
+ external_gateway_info:
+ network: { get_param: external_net_name }
+
+ management_router_interface:
+ type: OS::Neutron::RouterInterface
+ properties:
+ router: { get_resource: management_router }
+ subnet: { get_resource: subnet }
+
+ floating_ip:
+ type: OS::Neutron::FloatingIP
+ properties:
+ floating_network: { get_param: external_net_name }
+
+ floating_ip_association:
+ type: OS::Nova::FloatingIPAssociation
+ properties:
+ floating_ip: { get_resource: floating_ip }
+ server_id: {get_resource: vm1}
+
+ keypair:
+ type: OS::Nova::KeyPair
+ properties:
+ name: { get_param: keypair_name }
+ save_private_key: True
+
+ vm1:
+ type: OS::Nova::Server
+ depends_on: [subnet, keypair, flavor1]
+ properties:
+ name: { get_param: inst1_name }
+ image: { get_param: image1_name }
+ flavor: { get_resource: flavor1 }
+ key_name: {get_resource: keypair}
+ networks:
+ - network: { get_resource: network }
+
+ vm2:
+ type: OS::Nova::Server
+ depends_on: [subnet, flavor2]
+ properties:
+ name: { get_param: inst2_name }
+ image: { get_param: image2_name }
+ flavor: { get_resource: flavor2 }
+ key_name: {get_resource: keypair}
+ networks:
+ - network: { get_resource: network }
+
+outputs:
+ private_key:
+ description: "SSH Private Key"
+ value: { get_attr: [ keypair, private_key ]}
diff --git a/snaps/openstack/tests/heat/test_heat_template.yaml b/snaps/openstack/tests/heat/test_heat_template.yaml
index ffb82d6..03a34d8 100644
--- a/snaps/openstack/tests/heat/test_heat_template.yaml
+++ b/snaps/openstack/tests/heat/test_heat_template.yaml
@@ -1,3 +1,19 @@
+##############################################################################
+# 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: Simple template to deploy a single compute instance
@@ -23,6 +39,11 @@ parameters:
label: Test subnet name
description: The name of the stack's subnet
default: test_subnet
+ inst_name:
+ type: string
+ label: Test VM name
+ description: The name of the spawned vm
+ default: test_vm
resources:
private_net:
@@ -47,6 +68,7 @@ resources:
my_instance:
type: OS::Nova::Server
properties:
+ name: { get_param: inst_name }
image: { get_param: image_name }
flavor: { get_param: flavor_name }
networks: