1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
22 from snaps.openstack.create_instance import VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings
23 from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
24 from snaps.openstack.create_keypairs import OpenStackKeypair, KeypairSettings
25 from snaps.openstack.create_network import OpenStackNetwork, PortSettings
26 from snaps.openstack.create_router import OpenStackRouter
27 from snaps.openstack.create_image import OpenStackImage
28 from snaps.openstack.create_security_group import SecurityGroupSettings, OpenStackSecurityGroup
29 from snaps.openstack.tests import openstack_tests, validation_utils
30 from snaps.openstack.utils import nova_utils
31 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
33 __author__ = 'spisarski'
37 logger = logging.getLogger('create_instance_tests')
40 class VmInstanceSettingsUnitTests(unittest.TestCase):
42 Tests the construction of the VmInstanceSettings class
45 def test_no_params(self):
46 with self.assertRaises(Exception):
49 def test_empty_config(self):
50 with self.assertRaises(Exception):
51 VmInstanceSettings(config=dict())
53 def test_name_only(self):
54 with self.assertRaises(Exception):
55 VmInstanceSettings(name='foo')
57 def test_config_with_name_only(self):
58 with self.assertRaises(Exception):
59 VmInstanceSettings(config={'name': 'foo'})
61 def test_name_flavor_only(self):
62 with self.assertRaises(Exception):
63 VmInstanceSettings(name='foo', flavor='bar')
65 def test_config_with_name_flavor_only(self):
66 with self.assertRaises(Exception):
67 VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
69 def test_name_flavor_port_only(self):
70 port_settings = PortSettings(name='foo-port', network_name='bar-net')
71 settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings])
72 self.assertEquals('foo', settings.name)
73 self.assertEquals('bar', settings.flavor)
74 self.assertEquals(1, len(settings.port_settings))
75 self.assertEquals('foo-port', settings.port_settings[0].name)
76 self.assertEquals('bar-net', settings.port_settings[0].network_name)
77 self.assertEquals(0, len(settings.security_group_names))
78 self.assertEquals(0, len(settings.floating_ip_settings))
79 self.assertIsNone(settings.sudo_user)
80 self.assertEquals(900, settings.vm_boot_timeout)
81 self.assertEquals(300, settings.vm_delete_timeout)
82 self.assertEquals(180, settings.ssh_connect_timeout)
83 self.assertIsNone(settings.availability_zone)
85 def test_config_with_name_flavor_port_only(self):
86 port_settings = PortSettings(name='foo-port', network_name='bar-net')
87 settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
88 self.assertEquals('foo', settings.name)
89 self.assertEquals('bar', settings.flavor)
90 self.assertEquals(1, len(settings.port_settings))
91 self.assertEquals('foo-port', settings.port_settings[0].name)
92 self.assertEquals('bar-net', settings.port_settings[0].network_name)
93 self.assertEquals(0, len(settings.security_group_names))
94 self.assertEquals(0, len(settings.floating_ip_settings))
95 self.assertIsNone(settings.sudo_user)
96 self.assertEquals(900, settings.vm_boot_timeout)
97 self.assertEquals(300, settings.vm_delete_timeout)
98 self.assertEquals(180, settings.ssh_connect_timeout)
99 self.assertIsNone(settings.availability_zone)
102 port_settings = PortSettings(name='foo-port', network_name='bar-net')
103 fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router')
105 settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings],
106 security_group_names=['sec_grp_1'], floating_ip_settings=[fip_settings],
107 sudo_user='joe', vm_boot_timeout=999, vm_delete_timeout=333,
108 ssh_connect_timeout=111, availability_zone='server name')
109 self.assertEquals('foo', settings.name)
110 self.assertEquals('bar', settings.flavor)
111 self.assertEquals(1, len(settings.port_settings))
112 self.assertEquals('foo-port', settings.port_settings[0].name)
113 self.assertEquals('bar-net', settings.port_settings[0].network_name)
114 self.assertEquals(1, len(settings.security_group_names))
115 self.assertEquals('sec_grp_1', settings.security_group_names[0])
116 self.assertEquals(1, len(settings.floating_ip_settings))
117 self.assertEquals('foo-fip', settings.floating_ip_settings[0].name)
118 self.assertEquals('bar-port', settings.floating_ip_settings[0].port_name)
119 self.assertEquals('foo-bar-router', settings.floating_ip_settings[0].router_name)
120 self.assertEquals('joe', settings.sudo_user)
121 self.assertEquals(999, settings.vm_boot_timeout)
122 self.assertEquals(333, settings.vm_delete_timeout)
123 self.assertEquals(111, settings.ssh_connect_timeout)
124 self.assertEquals('server name', settings.availability_zone)
126 def test_config_all(self):
127 port_settings = PortSettings(name='foo-port', network_name='bar-net')
128 fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router')
130 settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings],
131 'security_group_names': ['sec_grp_1'],
132 'floating_ips': [fip_settings], 'sudo_user': 'joe',
133 'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
134 'ssh_connect_timeout': 111, 'availability_zone': 'server name'})
135 self.assertEquals('foo', settings.name)
136 self.assertEquals('bar', settings.flavor)
137 self.assertEquals(1, len(settings.port_settings))
138 self.assertEquals('foo-port', settings.port_settings[0].name)
139 self.assertEquals('bar-net', settings.port_settings[0].network_name)
140 self.assertEquals(1, len(settings.security_group_names))
141 self.assertEquals(1, len(settings.floating_ip_settings))
142 self.assertEquals('foo-fip', settings.floating_ip_settings[0].name)
143 self.assertEquals('bar-port', settings.floating_ip_settings[0].port_name)
144 self.assertEquals('foo-bar-router', settings.floating_ip_settings[0].router_name)
145 self.assertEquals('joe', settings.sudo_user)
146 self.assertEquals(999, settings.vm_boot_timeout)
147 self.assertEquals(333, settings.vm_delete_timeout)
148 self.assertEquals(111, settings.ssh_connect_timeout)
149 self.assertEquals('server name', settings.availability_zone)
152 class FloatingIpSettingsUnitTests(unittest.TestCase):
154 Tests the construction of the FloatingIpSettings class
157 def test_no_params(self):
158 with self.assertRaises(Exception):
161 def test_empty_config(self):
162 with self.assertRaises(Exception):
163 FloatingIpSettings(config=dict())
165 def test_name_only(self):
166 with self.assertRaises(Exception):
167 FloatingIpSettings(name='foo')
169 def test_config_with_name_only(self):
170 with self.assertRaises(Exception):
171 FloatingIpSettings(config={'name': 'foo'})
173 def test_name_port_only(self):
174 with self.assertRaises(Exception):
175 FloatingIpSettings(name='foo', port_name='bar')
177 def test_config_with_name_port_only(self):
178 with self.assertRaises(Exception):
179 FloatingIpSettings(config={'name': 'foo', 'port_name': 'bar'})
181 def test_name_router_only(self):
182 with self.assertRaises(Exception):
183 FloatingIpSettings(name='foo', router_name='bar')
185 def test_config_with_name_router_only(self):
186 with self.assertRaises(Exception):
187 FloatingIpSettings(config={'name': 'foo', 'router_name': 'bar'})
189 def test_name_port_router_only(self):
190 settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router')
191 self.assertEquals('foo', settings.name)
192 self.assertEquals('foo-port', settings.port_name)
193 self.assertEquals('bar-router', settings.router_name)
194 self.assertIsNone(settings.subnet_name)
195 self.assertTrue(settings.provisioning)
197 def test_config_with_name_port_router_only(self):
198 settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router'})
199 self.assertEquals('foo', settings.name)
200 self.assertEquals('foo-port', settings.port_name)
201 self.assertEquals('bar-router', settings.router_name)
202 self.assertIsNone(settings.subnet_name)
203 self.assertTrue(settings.provisioning)
206 settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router',
207 subnet_name='bar-subnet', provisioning=False)
208 self.assertEquals('foo', settings.name)
209 self.assertEquals('foo-port', settings.port_name)
210 self.assertEquals('bar-router', settings.router_name)
211 self.assertEquals('bar-subnet', settings.subnet_name)
212 self.assertFalse(settings.provisioning)
214 def test_config_all(self):
215 settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router',
216 'subnet_name': 'bar-subnet', 'provisioning': False})
217 self.assertEquals('foo', settings.name)
218 self.assertEquals('foo-port', settings.port_name)
219 self.assertEquals('bar-router', settings.router_name)
220 self.assertEquals('bar-subnet', settings.subnet_name)
221 self.assertFalse(settings.provisioning)
224 class SimpleHealthCheck(OSIntegrationTestCase):
226 Test for the CreateInstance class with a single NIC/Port with Floating IPs
231 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
234 super(self.__class__, self).__start__()
236 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
237 self.keypair_priv_filepath = 'tmp/' + guid
238 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
239 self.keypair_name = guid + '-kp'
240 self.vm_inst_name = guid + '-inst'
241 self.port_1_name = guid + 'port-1'
242 self.port_2_name = guid + 'port-2'
243 self.floating_ip_name = guid + 'fip1'
245 # Initialize for tearDown()
246 self.image_creators = list()
247 self.network_creator = None
248 self.flavor_creator = None
249 self.inst_creator = None
251 self.priv_net_config = openstack_tests.get_priv_net_config(
252 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
253 self.port_settings = PortSettings(
254 name=self.port_1_name, network_name=self.priv_net_config.network_settings.name)
256 # set the default image settings, then set any custom parameters sent from the app
257 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
259 if self.image_metadata:
260 if self.image_metadata['disk_url']:
261 self.os_image_settings.url = self.image_metadata['disk_url']
262 if self.image_metadata['extra_properties']:
263 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
266 # Create Image; if this is a 3-part image create the kernel and ramdisk images first
267 if self.image_metadata:
268 if self.image_metadata['kernel_url']:
269 kernel_image_settings = openstack_tests.cirros_url_image(
270 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
271 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
272 kernel_image = self.image_creators[-1].create()
273 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
275 if self.image_metadata['ramdisk_url']:
276 ramdisk_image_settings = openstack_tests.cirros_url_image(
277 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
278 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
279 ramdisk_image = self.image_creators[-1].create()
280 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
282 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
283 self.image_creators[-1].create()
286 self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
287 self.network_creator.create()
290 self.flavor_creator = OpenStackFlavor(
292 FlavorSettings(name=guid + '-flavor-name', ram=1024, disk=10, vcpus=1, metadata=self.flavor_metadata))
293 self.flavor_creator.create()
294 except Exception as e:
300 Cleans the created object
302 if self.inst_creator:
304 self.inst_creator.clean()
305 except Exception as e:
306 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
308 if os.path.isfile(self.keypair_pub_filepath):
309 os.remove(self.keypair_pub_filepath)
311 if os.path.isfile(self.keypair_priv_filepath):
312 os.remove(self.keypair_priv_filepath)
314 if self.flavor_creator:
316 self.flavor_creator.clean()
317 except Exception as e:
318 logger.error('Unexpected exception cleaning network with message - ' + e.message)
320 if self.image_creators:
322 while self.image_creators:
323 self.image_creators[-1].clean()
324 self.image_creators.pop()
325 except Exception as e:
326 logger.error('Unexpected exception cleaning image with message - ' + e.message)
328 super(self.__class__, self).__clean__()
330 def test_check_vm_ip_dhcp(self):
332 Tests the creation of an OpenStack instance with a single port and ensures that it's assigned IP address is
335 instance_settings = VmInstanceSettings(
336 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
338 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
339 vm = self.inst_creator.create()
341 ip = self.inst_creator.get_port_ip(self.port_settings.name)
342 self.assertIsNotNone(ip)
344 self.assertTrue(self.inst_creator.vm_active(block=True))
348 start_time = time.time()
349 match_value = 'Lease of.*obtained'
351 logger.info("Looking for expression %s in the console log" % match_value)
352 while timeout > time.time() - start_time:
353 output = vm.get_console_output()
354 if re.search(match_value, output):
355 logger.info('DHCP lease obtained logged in console')
357 logger.info('With correct IP address')
360 logger.error('With incorrect IP address')
363 self.assertTrue(found)
366 class CreateInstanceSimpleTests(OSIntegrationTestCase):
368 Simple instance creation tests without any other objects
372 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
375 super(self.__class__, self).__start__()
377 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
378 self.vm_inst_name = guid + '-inst'
379 self.nova = nova_utils.nova_client(self.os_creds)
380 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
382 net_config = openstack_tests.get_priv_net_config(
383 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
384 router_name=guid + '-pub-router', external_net=self.ext_net_name)
386 # Initialize for tearDown()
387 self.image_creator = None
388 self.flavor_creator = None
390 self.net_creator = None
391 self.inst_creator = None
395 self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
396 self.image_creator.create()
399 self.flavor_creator = OpenStackFlavor(
401 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
402 self.flavor_creator.create()
405 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
406 self.network_creator.create()
408 self.port_settings = PortSettings(name=guid + '-port',
409 network_name=net_config.network_settings.name)
411 except Exception as e:
417 Cleans the created object
419 if self.inst_creator:
421 self.inst_creator.clean()
422 except Exception as e:
423 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
425 if self.flavor_creator:
427 self.flavor_creator.clean()
428 except Exception as e:
429 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
433 self.net_creator.clean()
434 except Exception as e:
435 logger.error('Unexpected exception cleaning network with message - ' + e.message)
437 if self.image_creator:
439 self.image_creator.clean()
440 except Exception as e:
441 logger.error('Unexpected exception cleaning image with message - ' + e.message)
443 super(self.__class__, self).__clean__()
445 def test_create_delete_instance(self):
447 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
449 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
450 port_settings=[self.port_settings])
452 self.inst_creator = OpenStackVmInstance(
453 self.os_creds, instance_settings, self.image_creator.image_settings)
455 vm_inst = self.inst_creator.create()
456 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
459 nova_utils.delete_vm_instance(self.nova, vm_inst)
461 self.assertTrue(self.inst_creator.vm_deleted(block=True))
462 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
464 # Exception should not be thrown
465 self.inst_creator.clean()
468 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
470 Test for the CreateInstance class with a single NIC/Port with Floating IPs
475 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
478 super(self.__class__, self).__start__()
480 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
481 self.keypair_priv_filepath = 'tmp/' + guid
482 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
483 self.keypair_name = guid + '-kp'
484 self.vm_inst_name = guid + '-inst'
485 self.port_1_name = guid + 'port-1'
486 self.port_2_name = guid + 'port-2'
487 self.floating_ip_name = guid + 'fip1'
489 # Initialize for tearDown()
490 self.image_creator = None
491 self.network_creator = None
492 self.router_creator = None
493 self.flavor_creator = None
494 self.keypair_creator = None
495 self.inst_creators = list()
497 self.pub_net_config = openstack_tests.get_pub_net_config(
498 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
499 router_name=guid + '-pub-router', external_net=self.ext_net_name)
500 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
504 self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
505 self.image_creator.create()
508 self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
509 self.network_creator.create()
512 self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
513 self.router_creator.create()
516 self.flavor_creator = OpenStackFlavor(
518 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
519 self.flavor_creator.create()
521 self.keypair_creator = OpenStackKeypair(
522 self.os_creds, KeypairSettings(
523 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
524 private_filepath=self.keypair_priv_filepath))
525 self.keypair_creator.create()
526 except Exception as e:
532 Cleans the created object
534 for inst_creator in self.inst_creators:
537 except Exception as e:
538 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
540 if self.keypair_creator:
542 self.keypair_creator.clean()
543 except Exception as e:
544 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
546 if os.path.isfile(self.keypair_pub_filepath):
547 os.remove(self.keypair_pub_filepath)
549 if os.path.isfile(self.keypair_priv_filepath):
550 os.remove(self.keypair_priv_filepath)
552 if self.flavor_creator:
554 self.flavor_creator.clean()
555 except Exception as e:
556 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
558 if self.router_creator:
560 self.router_creator.clean()
561 except Exception as e:
562 logger.error('Unexpected exception cleaning router with message - ' + e.message)
564 if self.network_creator:
566 self.network_creator.clean()
567 except Exception as e:
568 logger.error('Unexpected exception cleaning network with message - ' + e.message)
570 if self.image_creator:
572 self.image_creator.clean()
573 except Exception as e:
574 logger.error('Unexpected exception cleaning image with message - ' + e.message)
576 super(self.__class__, self).__clean__()
578 def test_single_port_static(self):
580 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
584 port_settings = PortSettings(
585 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name,
586 ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}])
588 instance_settings = VmInstanceSettings(
589 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
590 floating_ip_settings=[FloatingIpSettings(
591 name=self.floating_ip_name, port_name=self.port_1_name,
592 router_name=self.pub_net_config.router_settings.name)])
594 inst_creator = OpenStackVmInstance(
595 self.os_creds, instance_settings, self.image_creator.image_settings,
596 keypair_settings=self.keypair_creator.keypair_settings)
597 self.inst_creators.append(inst_creator)
598 vm_inst = inst_creator.create()
600 self.assertEquals(ip_1, inst_creator.get_port_ip(self.port_1_name))
601 self.assertTrue(inst_creator.vm_active(block=True))
602 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
604 def test_ssh_client_fip_before_active(self):
606 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
608 port_settings = PortSettings(
609 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
611 instance_settings = VmInstanceSettings(
612 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
613 floating_ip_settings=[FloatingIpSettings(
614 name=self.floating_ip_name, port_name=self.port_1_name,
615 router_name=self.pub_net_config.router_settings.name)])
617 inst_creator = OpenStackVmInstance(
618 self.os_creds, instance_settings, self.image_creator.image_settings,
619 keypair_settings=self.keypair_creator.keypair_settings)
620 self.inst_creators.append(inst_creator)
621 vm_inst = inst_creator.create()
622 self.assertIsNotNone(vm_inst)
624 self.assertTrue(inst_creator.vm_active(block=True))
625 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
627 self.assertTrue(validate_ssh_client(inst_creator))
629 def test_ssh_client_fip_after_active(self):
631 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
633 port_settings = PortSettings(
634 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
636 instance_settings = VmInstanceSettings(
637 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
638 floating_ip_settings=[FloatingIpSettings(
639 name=self.floating_ip_name, port_name=self.port_1_name,
640 router_name=self.pub_net_config.router_settings.name)])
642 inst_creator = OpenStackVmInstance(
643 self.os_creds, instance_settings, self.image_creator.image_settings,
644 keypair_settings=self.keypair_creator.keypair_settings)
645 self.inst_creators.append(inst_creator)
647 # block=True will force the create() method to block until the
648 vm_inst = inst_creator.create(block=True)
649 self.assertIsNotNone(vm_inst)
651 self.assertTrue(inst_creator.vm_active(block=True))
652 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
654 self.assertTrue(validate_ssh_client(inst_creator))
656 # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
657 # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
658 # def test_allowed_address_port_access(self):
660 # Tests to ensure that setting allowed_address_pairs on a port functions as designed
662 # port_settings_1 = PortSettings(
663 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
665 # instance_settings_1 = VmInstanceSettings(
666 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
667 # floating_ip_settings=[FloatingIpSettings(
668 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
669 # router_name=self.pub_net_config.router_settings.name)])
671 # inst_creator_1 = OpenStackVmInstance(
672 # self.os_creds, instance_settings_1, self.image_creator.image_settings,
673 # keypair_settings=self.keypair_creator.keypair_settings)
674 # self.inst_creators.append(inst_creator_1)
676 # # block=True will force the create() method to block until the
677 # vm_inst_1 = inst_creator_1.create(block=True)
678 # self.assertIsNotNone(vm_inst_1)
680 # port_settings_1 = PortSettings(
681 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
683 # instance_settings_1 = VmInstanceSettings(
684 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
685 # floating_ip_settings=[FloatingIpSettings(
686 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
687 # router_name=self.pub_net_config.router_settings.name)])
689 # inst_creator_1 = OpenStackVmInstance(
690 # self.os_creds, instance_settings_1, self.image_creator.image_settings,
691 # keypair_settings=self.keypair_creator.keypair_settings)
692 # self.inst_creators.append(inst_creator_1)
693 # inst_creator_1.create(block=True)
695 # ip = inst_creator_1.get_port_ip(port_settings_1.name,
696 # subnet_name=self.pub_net_config.network_settings.subnet_settings[0].name)
697 # self.assertIsNotNone(ip)
698 # mac_addr = inst_creator_1.get_port_mac(port_settings_1.name)
699 # self.assertIsNotNone(mac_addr)
701 # allowed_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
703 # # Create VM that can be accessed by vm_inst_1
704 # port_settings_2 = PortSettings(
705 # name=self.port_1_name + '-2', network_name=self.pub_net_config.network_settings.name,
706 # allowed_address_pairs=allowed_address_pairs)
708 # instance_settings_2 = VmInstanceSettings(
709 # name=self.vm_inst_name + '-2', flavor=self.flavor_creator.flavor_settings.name,
710 # port_settings=[port_settings_2])
712 # inst_creator_2 = OpenStackVmInstance(
713 # self.os_creds, instance_settings_2, self.image_creator.image_settings)
714 # self.inst_creators.append(inst_creator_2)
715 # inst_creator_2.create(block=True)
717 # # Create VM that cannot be accessed by vm_inst_1
719 # mac_addr = '0a:1b:2c:3d:4e:5f'
720 # invalid_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
722 # port_settings_3 = PortSettings(
723 # name=self.port_1_name + '-3', network_name=self.pub_net_config.network_settings.name,
724 # allowed_address_pairs=invalid_address_pairs)
726 # instance_settings_3 = VmInstanceSettings(
727 # name=self.vm_inst_name + '-3', flavor=self.flavor_creator.flavor_settings.name,
728 # port_settings=[port_settings_3])
730 # inst_creator_3 = OpenStackVmInstance(
731 # self.os_creds, instance_settings_3, self.image_creator.image_settings)
732 # self.inst_creators.append(inst_creator_3)
733 # inst_creator_3.create(block=True)
736 # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would expect
737 # inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
738 # TODO - Add validation
741 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
743 Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set
748 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
751 super(self.__class__, self).__start__()
753 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
754 self.vm_inst_name = guid + '-inst'
755 self.port_1_name = guid + 'port-1'
756 self.port_2_name = guid + 'port-2'
757 self.floating_ip_name = guid + 'fip1'
759 # Initialize for tearDown()
760 self.image_creator = None
761 self.network_creator = None
762 self.flavor_creator = None
763 self.inst_creator = None
765 self.net_config = openstack_tests.get_priv_net_config(
766 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
767 router_name=guid + '-pub-router', external_net=self.ext_net_name)
768 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
772 self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
773 self.image_creator.create()
776 self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
777 self.network_creator.create()
780 self.flavor_creator = OpenStackFlavor(
782 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
783 self.flavor_creator.create()
784 except Exception as e:
790 Cleans the created object
792 if self.inst_creator:
794 self.inst_creator.clean()
795 except Exception as e:
796 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
798 if self.flavor_creator:
800 self.flavor_creator.clean()
801 except Exception as e:
802 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
804 if self.network_creator:
806 self.network_creator.clean()
807 except Exception as e:
808 logger.error('Unexpected exception cleaning network with message - ' + e.message)
810 if self.image_creator:
812 self.image_creator.clean()
813 except Exception as e:
814 logger.error('Unexpected exception cleaning image with message - ' + e.message)
816 super(self.__class__, self).__clean__()
818 def test_set_custom_valid_ip_one_subnet(self):
820 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
823 port_settings = PortSettings(
824 name=self.port_1_name, network_name=self.net_config.network_settings.name,
825 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
827 instance_settings = VmInstanceSettings(
828 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
830 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
831 self.inst_creator.create()
833 self.assertEquals(ip, self.inst_creator.get_port_ip(
834 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
836 def test_set_custom_invalid_ip_one_subnet(self):
838 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
841 port_settings = PortSettings(
842 name=self.port_1_name, network_name=self.net_config.network_settings.name,
843 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
845 instance_settings = VmInstanceSettings(
846 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
848 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
850 with self.assertRaises(Exception):
851 self.inst_creator.create()
853 def test_set_custom_valid_mac(self):
855 Tests the creation of an OpenStack instance with a single port where the MAC address is assigned.
857 mac_addr = '0a:1b:2c:3d:4e:5f'
858 port_settings = PortSettings(
859 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr)
861 instance_settings = VmInstanceSettings(
862 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
864 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
865 self.inst_creator.create()
867 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
869 def test_set_custom_invalid_mac(self):
871 Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being
872 assigned. This should raise an Exception
874 port_settings = PortSettings(
875 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo')
877 instance_settings = VmInstanceSettings(
878 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
880 self.inst_creator = OpenStackVmInstance(
881 self.os_creds, instance_settings, self.image_creator.image_settings)
883 with self.assertRaises(Exception):
884 self.inst_creator.create()
886 def test_set_custom_mac_and_ip(self):
888 Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned.
891 mac_addr = '0a:1b:2c:3d:4e:5f'
892 port_settings = PortSettings(
893 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr,
894 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
896 instance_settings = VmInstanceSettings(
897 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
899 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
900 self.inst_creator.create()
902 self.assertEquals(ip, self.inst_creator.get_port_ip(
903 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
904 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
906 def test_set_allowed_address_pairs(self):
908 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set.
911 mac_addr = '0a:1b:2c:3d:4e:5f'
912 pair = {'ip_address': ip, 'mac_address': mac_addr}
913 port_settings = PortSettings(
914 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
916 instance_settings = VmInstanceSettings(
917 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
919 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
920 self.inst_creator.create()
922 port = self.inst_creator.get_port_by_name(port_settings.name)
923 self.assertIsNotNone(port)
924 self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
925 self.assertEquals(1, len(port['port']['allowed_address_pairs']))
926 validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0])
928 def test_set_allowed_address_pairs_bad_mac(self):
930 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
935 pair = {'ip_address': ip, 'mac_address': mac_addr}
937 pairs.add((ip, mac_addr))
938 port_settings = PortSettings(
939 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
941 instance_settings = VmInstanceSettings(
942 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
944 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
945 with self.assertRaises(Exception):
946 self.inst_creator.create()
948 def test_set_allowed_address_pairs_bad_ip(self):
950 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
954 mac_addr = '0a:1b:2c:3d:4e:5f'
955 pair = {'ip_address': ip, 'mac_address': mac_addr}
957 pairs.add((ip, mac_addr))
958 port_settings = PortSettings(
959 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
961 instance_settings = VmInstanceSettings(
962 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
964 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
965 with self.assertRaises(Exception):
966 self.inst_creator.create()
969 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
971 Test for the CreateInstance where one VM is deployed to each compute node
976 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
979 super(self.__class__, self).__start__()
981 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
982 self.vm_inst_name = guid + '-inst'
983 self.port_base_name = guid + 'port'
985 # Initialize for tearDown()
986 self.image_creator = None
987 self.flavor_creator = None
988 self.network_creator = None
989 self.inst_creators = list()
991 self.priv_net_config = openstack_tests.get_priv_net_config(
992 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
994 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
998 self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
999 self.network_creator.create()
1002 self.flavor_creator = OpenStackFlavor(
1003 self.admin_os_creds,
1004 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
1005 self.flavor_creator.create()
1008 self.image_creator = OpenStackImage(self.admin_os_creds, self.os_image_settings)
1009 self.image_creator.create()
1011 except Exception as e:
1017 Cleans the created object
1019 for inst_creator in self.inst_creators:
1021 inst_creator.clean()
1022 except Exception as e:
1023 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1025 if self.flavor_creator:
1027 self.flavor_creator.clean()
1028 except Exception as e:
1029 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1031 if self.network_creator:
1033 self.network_creator.clean()
1034 except Exception as e:
1035 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1037 if self.image_creator:
1039 self.image_creator.clean()
1040 except Exception as e:
1041 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1043 super(self.__class__, self).__clean__()
1045 def test_deploy_vm_to_each_compute_node(self):
1047 Tests the creation of OpenStack VM instances to each compute node.
1049 from snaps.openstack.utils import nova_utils
1050 nova = nova_utils.nova_client(self.admin_os_creds)
1051 zones = nova_utils.get_nova_availability_zones(nova)
1053 # Create Instance on each server/zone
1056 inst_name = self.vm_inst_name + '-' + zone
1058 port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr),
1059 network_name=self.priv_net_config.network_settings.name)
1061 instance_settings = VmInstanceSettings(
1062 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
1063 port_settings=[port_settings])
1064 inst_creator = OpenStackVmInstance(
1065 self.admin_os_creds, instance_settings, self.image_creator.image_settings)
1066 self.inst_creators.append(inst_creator)
1067 inst_creator.create()
1069 # Validate instances to ensure they've been deployed to the correct server
1072 creator = self.inst_creators[index]
1073 self.assertTrue(creator.vm_active(block=True))
1074 vm = creator.get_vm_inst()
1075 deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
1076 deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
1077 self.assertEquals(zone, deployed_zone + ':' + deployed_host)
1081 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1083 Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o
1084 These tests require a Centos image
1089 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1092 super(self.__class__, self).__start__()
1094 # Initialize for tearDown()
1095 self.image_creator = None
1096 self.network_creators = list()
1097 self.router_creators = list()
1098 self.flavor_creator = None
1099 self.keypair_creator = None
1100 self.inst_creator = None
1102 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1103 self.keypair_priv_filepath = 'tmp/' + self.guid
1104 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1105 self.keypair_name = self.guid + '-kp'
1106 self.vm_inst_name = self.guid + '-inst'
1107 self.port_1_name = self.guid + '-port-1'
1108 self.port_2_name = self.guid + '-port-2'
1109 self.floating_ip_name = self.guid + 'fip1'
1110 self.priv_net_config = openstack_tests.get_priv_net_config(
1111 net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet',
1112 router_name=self.guid + '-priv-router', external_net=self.ext_net_name)
1113 self.pub_net_config = openstack_tests.get_pub_net_config(
1114 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1115 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1116 image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1117 self.os_image_settings = openstack_tests.centos_url_image(name=image_name)
1121 self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
1122 self.image_creator.create()
1124 # First network is public
1125 self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
1126 # Second network is private
1127 self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings))
1128 for network_creator in self.network_creators:
1129 network_creator.create()
1131 self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings))
1132 self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings))
1135 for router_creator in self.router_creators:
1136 router_creator.create()
1139 self.flavor_creator = OpenStackFlavor(
1140 self.admin_os_creds,
1141 FlavorSettings(name=self.guid + '-flavor-name', ram=2048, disk=10, vcpus=2,
1142 metadata=self.flavor_metadata))
1143 self.flavor_creator.create()
1146 self.keypair_creator = OpenStackKeypair(
1147 self.os_creds, KeypairSettings(
1148 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
1149 private_filepath=self.keypair_priv_filepath))
1150 self.keypair_creator.create()
1151 except Exception as e:
1153 raise Exception(e.message)
1157 Cleans the created objects
1159 if self.inst_creator:
1161 self.inst_creator.clean()
1162 except Exception as e:
1163 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1165 if self.keypair_creator:
1167 self.keypair_creator.clean()
1168 except Exception as e:
1169 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
1171 if os.path.isfile(self.keypair_pub_filepath):
1172 os.remove(self.keypair_pub_filepath)
1174 if os.path.isfile(self.keypair_priv_filepath):
1175 os.remove(self.keypair_priv_filepath)
1177 if self.flavor_creator:
1179 self.flavor_creator.clean()
1180 except Exception as e:
1181 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1183 for router_creator in self.router_creators:
1185 router_creator.clean()
1186 except Exception as e:
1187 logger.error('Unexpected exception cleaning router with message - ' + e.message)
1189 for network_creator in self.network_creators:
1191 network_creator.clean()
1192 except Exception as e:
1193 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1195 if self.image_creator:
1197 self.image_creator.clean()
1198 except Exception as e:
1199 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1201 super(self.__class__, self).__clean__()
1203 def test_dual_ports_dhcp(self):
1205 Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP.
1206 NOTE: This test and any others that call ansible will most likely fail unless you do one of
1208 1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False
1209 2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False
1210 Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail.
1212 # Create ports/NICs for instance
1215 for network_creator in self.network_creators:
1216 ports_settings.append(PortSettings(
1217 name=self.guid + '-port-' + str(ctr),
1218 network_name=network_creator.network_settings.name))
1222 instance_settings = VmInstanceSettings(
1223 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings,
1224 floating_ip_settings=[FloatingIpSettings(
1225 name=self.floating_ip_name, port_name=self.port_1_name,
1226 router_name=self.pub_net_config.router_settings.name)])
1228 self.inst_creator = OpenStackVmInstance(
1229 self.os_creds, instance_settings, self.image_creator.image_settings,
1230 keypair_settings=self.keypair_creator.keypair_settings)
1232 vm_inst = self.inst_creator.create(block=True)
1234 self.assertEquals(vm_inst, self.inst_creator.get_vm_inst())
1236 # Effectively blocks until VM has been properly activated
1237 self.assertTrue(self.inst_creator.vm_active(block=True))
1239 # Effectively blocks until VM's ssh port has been opened
1240 self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1242 self.inst_creator.config_nics()
1244 # TODO - *** ADD VALIDATION HERE ***
1245 # TODO - Add validation that both floating IPs work
1246 # TODO - Add tests where only one NIC has a floating IP
1247 # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway
1250 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1252 Tests that include, add, and remove security groups from VM instances
1256 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1259 super(self.__class__, self).__start__()
1261 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1262 self.vm_inst_name = self.guid + '-inst'
1263 self.nova = nova_utils.nova_client(self.os_creds)
1264 self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
1266 self.vm_inst_name = self.guid + '-inst'
1267 self.port_1_name = self.guid + 'port-1'
1268 self.port_2_name = self.guid + 'port-2'
1269 self.floating_ip_name = self.guid + 'fip1'
1271 net_config = openstack_tests.get_priv_net_config(
1272 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1273 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1275 # Initialize for tearDown()
1276 self.image_creator = None
1277 self.flavor_creator = None
1278 self.network_creator = None
1279 self.router_creator = None
1280 self.inst_creator = None
1281 self.sec_grp_creators = list()
1285 self.image_creator = OpenStackImage(self.os_creds, self.os_image_settings)
1286 self.image_creator.create()
1289 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1290 self.network_creator.create()
1293 self.flavor_creator = OpenStackFlavor(
1294 self.admin_os_creds,
1295 FlavorSettings(name=self.guid + '-flavor-name', ram=2048, disk=10, vcpus=2,
1296 metadata=self.flavor_metadata))
1297 self.flavor_creator.create()
1299 self.port_settings = PortSettings(name=self.guid + '-port',
1300 network_name=net_config.network_settings.name)
1301 except Exception as e:
1307 Cleans the created object
1309 if self.inst_creator:
1311 self.inst_creator.clean()
1312 except Exception as e:
1313 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1315 for sec_grp_creator in self.sec_grp_creators:
1317 sec_grp_creator.clean()
1318 except Exception as e:
1319 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
1321 if self.flavor_creator:
1323 self.flavor_creator.clean()
1324 except Exception as e:
1325 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1327 if self.network_creator:
1329 self.network_creator.clean()
1330 except Exception as e:
1331 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1333 if self.image_creator:
1335 self.image_creator.clean()
1336 except Exception as e:
1337 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1339 super(self.__class__, self).__clean__()
1341 def test_add_security_group(self):
1343 Tests the addition of a security group created after the instance.
1346 instance_settings = VmInstanceSettings(
1347 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1348 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
1349 vm_inst = self.inst_creator.create(block=True)
1350 self.assertIsNotNone(vm_inst)
1352 # Create security group object to add to instance
1353 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1354 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1355 sec_grp = sec_grp_creator.create()
1356 self.sec_grp_creators.append(sec_grp_creator)
1358 # Check that group has not been added
1359 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1361 # Add security group to instance after activated
1362 self.inst_creator.add_security_group(sec_grp)
1364 # Validate that security group has been added
1365 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1367 def test_add_invalid_security_group(self):
1369 Tests the addition of a security group that no longer exists.
1372 instance_settings = VmInstanceSettings(
1373 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1374 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
1375 vm_inst = self.inst_creator.create(block=True)
1376 self.assertIsNotNone(vm_inst)
1378 # Create security group object to add to instance
1379 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1380 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1381 sec_grp = sec_grp_creator.create()
1382 sec_grp_creator.clean()
1383 self.sec_grp_creators.append(sec_grp_creator)
1385 # Check that group has not been added
1386 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1388 # Add security group to instance after activated
1389 self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1391 # Validate that security group has been added
1392 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1394 def test_remove_security_group(self):
1396 Tests the removal of a security group created before and added to the instance.
1398 # Create security group object to add to instance
1399 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1400 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1401 sec_grp = sec_grp_creator.create()
1402 self.sec_grp_creators.append(sec_grp_creator)
1405 instance_settings = VmInstanceSettings(
1406 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1407 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1408 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
1409 vm_inst = self.inst_creator.create(block=True)
1410 self.assertIsNotNone(vm_inst)
1412 # Check that group has been added
1413 self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
1415 # Add security group to instance after activated
1416 self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1418 # Validate that security group has been added
1419 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1421 def test_remove_security_group_never_added(self):
1423 Tests the removal of a security group that was never added in the first place.
1425 # Create security group object to add to instance
1426 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1427 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1428 sec_grp = sec_grp_creator.create()
1429 self.sec_grp_creators.append(sec_grp_creator)
1432 instance_settings = VmInstanceSettings(
1433 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1434 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
1435 vm_inst = self.inst_creator.create(block=True)
1436 self.assertIsNotNone(vm_inst)
1438 # Check that group has been added
1439 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1441 # Add security group to instance after activated
1442 self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1444 # Validate that security group has been added
1445 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1447 def test_add_same_security_group(self):
1449 Tests the addition of a security group created before add added to the instance.
1451 # Create security group object to add to instance
1452 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1453 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1454 sec_grp = sec_grp_creator.create()
1455 self.sec_grp_creators.append(sec_grp_creator)
1458 instance_settings = VmInstanceSettings(
1459 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1460 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1461 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings)
1462 vm_inst = self.inst_creator.create(block=True)
1463 self.assertIsNotNone(vm_inst)
1465 # Check that group has been added
1466 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1468 # Add security group to instance after activated
1469 self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1471 # Validate that security group has been added
1472 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1475 def inst_has_sec_grp(vm_inst, sec_grp_name):
1477 Returns true if instance has a security group of a given name
1480 if not hasattr(vm_inst, 'security_groups'):
1484 for sec_grp_dict in vm_inst.security_groups:
1485 if sec_grp_name in sec_grp_dict['name']:
1491 def validate_ssh_client(instance_creator):
1493 Returns True if instance_creator returns an SSH client that is valid
1494 :param instance_creator: the object responsible for creating the VM instance
1497 ssh_active = instance_creator.vm_ssh_active(block=True)
1500 ssh_client = instance_creator.ssh_client()
1502 out = ssh_client.exec_command('pwd')[1]
1506 channel = out.channel
1507 in_buffer = channel.in_buffer
1508 pwd_out = in_buffer.read(1024)
1509 if not pwd_out or len(pwd_out) < 10:
1516 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1518 Test for the CreateInstance class for creating an image from a 3-part image
1523 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1526 super(self.__class__, self).__start__()
1528 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1529 self.image_name = guid
1530 self.vm_inst_name = guid + '-inst'
1531 self.nova = nova_utils.nova_client(self.os_creds)
1533 net_config = openstack_tests.get_priv_net_config(
1534 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1535 router_name=guid + '-pub-router', external_net=self.ext_net_name)
1537 # Initialize for tearDown()
1538 self.image_creators = list()
1539 self.network_creator = None
1540 self.flavor_creator = None
1541 self.inst_creator = None
1545 # Create the kernel image
1546 kernel_image_settings = openstack_tests.cirros_url_image(
1547 name=self.image_name+'_kernel',
1548 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
1549 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1550 kernel_image = self.image_creators[-1].create()
1552 # Create the ramdisk image
1553 ramdisk_image_settings = openstack_tests.cirros_url_image(
1554 name=self.image_name+'_ramdisk',
1555 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
1556 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1557 ramdisk_image = self.image_creators[-1].create()
1558 self.assertIsNotNone(ramdisk_image)
1560 # Create the main image
1561 os_image_settings = openstack_tests.cirros_url_image(
1562 name=self.image_name,
1563 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
1565 properties['kernel_id'] = kernel_image.id
1566 properties['ramdisk_id'] = ramdisk_image.id
1567 os_image_settings.extra_properties = properties
1568 self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
1569 created_image = self.image_creators[-1].create()
1570 self.assertIsNotNone(created_image)
1573 self.flavor_creator = OpenStackFlavor(
1574 self.admin_os_creds,
1575 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
1576 self.flavor_creator.create()
1579 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1580 self.network_creator.create()
1582 self.port_settings = PortSettings(name=guid + '-port',
1583 network_name=net_config.network_settings.name)
1584 except Exception as e:
1590 Cleans the created object
1592 if self.inst_creator:
1594 self.inst_creator.clean()
1595 except Exception as e:
1596 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1598 if self.flavor_creator:
1600 self.flavor_creator.clean()
1601 except Exception as e:
1602 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1604 if self.network_creator:
1606 self.network_creator.clean()
1607 except Exception as e:
1608 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1610 if self.image_creators:
1612 while self.image_creators:
1613 self.image_creators[0].clean()
1614 self.image_creators.pop(0)
1615 except Exception as e:
1616 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1618 super(self.__class__, self).__clean__()
1620 def test_create_delete_instance_from_three_part_image(self):
1622 Tests the creation of an OpenStack instance from a 3-part image.
1624 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1625 port_settings=[self.port_settings])
1627 # The last created image is the main image from which we create the instance
1628 self.inst_creator = OpenStackVmInstance(
1629 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1631 vm_inst = self.inst_creator.create()
1632 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1635 nova_utils.delete_vm_instance(self.nova, vm_inst)
1637 self.assertTrue(self.inst_creator.vm_deleted(block=True))
1638 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1640 # Exception should not be thrown
1641 self.inst_creator.clean()