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)
257 # Set the default image settings, then set any custom parameters sent from the app
258 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
260 if self.image_metadata:
261 if self.image_metadata['disk_url']:
262 self.os_image_settings.url = self.image_metadata['disk_url']
263 if self.image_metadata['extra_properties']:
264 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
267 # If this is a 3-part image create the kernel and ramdisk images first
268 if self.image_metadata:
269 if self.image_metadata['kernel_url']:
270 kernel_image_settings = openstack_tests.cirros_url_image(
271 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
272 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
273 kernel_image = self.image_creators[-1].create()
274 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
276 if self.image_metadata['ramdisk_url']:
277 ramdisk_image_settings = openstack_tests.cirros_url_image(
278 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
279 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
280 ramdisk_image = self.image_creators[-1].create()
281 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
283 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
284 self.image_creators[-1].create()
287 self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
288 self.network_creator.create()
291 self.flavor_creator = OpenStackFlavor(
293 FlavorSettings(name=guid + '-flavor-name', ram=1024, disk=10, vcpus=1, metadata=self.flavor_metadata))
294 self.flavor_creator.create()
295 except Exception as e:
301 Cleans the created object
303 if self.inst_creator:
305 self.inst_creator.clean()
306 except Exception as e:
307 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
309 if os.path.isfile(self.keypair_pub_filepath):
310 os.remove(self.keypair_pub_filepath)
312 if os.path.isfile(self.keypair_priv_filepath):
313 os.remove(self.keypair_priv_filepath)
315 if self.flavor_creator:
317 self.flavor_creator.clean()
318 except Exception as e:
319 logger.error('Unexpected exception cleaning network with message - ' + e.message)
321 if self.image_creators:
323 while self.image_creators:
324 self.image_creators[-1].clean()
325 self.image_creators.pop()
326 except Exception as e:
327 logger.error('Unexpected exception cleaning image with message - ' + e.message)
329 super(self.__class__, self).__clean__()
331 def test_check_vm_ip_dhcp(self):
333 Tests the creation of an OpenStack instance with a single port and ensures that it's assigned IP address is
336 instance_settings = VmInstanceSettings(
337 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
339 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
340 vm = self.inst_creator.create()
342 ip = self.inst_creator.get_port_ip(self.port_settings.name)
343 self.assertIsNotNone(ip)
345 self.assertTrue(self.inst_creator.vm_active(block=True))
349 start_time = time.time()
350 match_value = 'Lease of.*obtained'
352 logger.info("Looking for expression %s in the console log" % match_value)
353 while timeout > time.time() - start_time:
354 output = vm.get_console_output()
355 if re.search(match_value, output):
356 logger.info('DHCP lease obtained logged in console')
358 logger.info('With correct IP address')
361 logger.error('With incorrect IP address')
364 self.assertTrue(found)
367 class CreateInstanceSimpleTests(OSIntegrationTestCase):
369 Simple instance creation tests without any other objects
373 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
376 super(self.__class__, self).__start__()
378 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
379 self.vm_inst_name = guid + '-inst'
380 self.nova = nova_utils.nova_client(self.os_creds)
381 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
383 net_config = openstack_tests.get_priv_net_config(
384 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
385 router_name=guid + '-pub-router', external_net=self.ext_net_name)
387 # Initialize for tearDown()
388 self.image_creators = list()
389 self.flavor_creator = None
391 self.net_creator = None
392 self.inst_creator = None
396 # Set any custom parameters sent from the app
397 if self.image_metadata:
398 if self.image_metadata['disk_url']:
399 self.os_image_settings.url = self.image_metadata['disk_url']
400 if self.image_metadata['extra_properties']:
401 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
403 # If this is a 3-part image create the kernel and ramdisk images first
404 if self.image_metadata:
405 if self.image_metadata['kernel_url']:
406 kernel_image_settings = openstack_tests.cirros_url_image(
407 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
408 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
409 kernel_image = self.image_creators[-1].create()
410 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
412 if self.image_metadata['ramdisk_url']:
413 ramdisk_image_settings = openstack_tests.cirros_url_image(
414 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
415 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
416 ramdisk_image = self.image_creators[-1].create()
417 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
419 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
420 self.image_creators[-1].create()
423 self.flavor_creator = OpenStackFlavor(
425 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
426 self.flavor_creator.create()
429 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
430 self.network_creator.create()
432 self.port_settings = PortSettings(name=guid + '-port',
433 network_name=net_config.network_settings.name)
435 except Exception as e:
441 Cleans the created object
443 if self.inst_creator:
445 self.inst_creator.clean()
446 except Exception as e:
447 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
449 if self.flavor_creator:
451 self.flavor_creator.clean()
452 except Exception as e:
453 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
457 self.net_creator.clean()
458 except Exception as e:
459 logger.error('Unexpected exception cleaning network with message - ' + e.message)
461 if self.image_creators:
463 while self.image_creators:
464 self.image_creators[-1].clean()
465 self.image_creators.pop()
466 except Exception as e:
467 logger.error('Unexpected exception cleaning image with message - ' + e.message)
469 super(self.__class__, self).__clean__()
471 def test_create_delete_instance(self):
473 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
475 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
476 port_settings=[self.port_settings])
478 self.inst_creator = OpenStackVmInstance(
479 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
481 vm_inst = self.inst_creator.create()
482 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
485 nova_utils.delete_vm_instance(self.nova, vm_inst)
487 self.assertTrue(self.inst_creator.vm_deleted(block=True))
488 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
490 # Exception should not be thrown
491 self.inst_creator.clean()
494 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
496 Test for the CreateInstance class with a single NIC/Port with Floating IPs
501 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
504 super(self.__class__, self).__start__()
506 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
507 self.keypair_priv_filepath = 'tmp/' + guid
508 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
509 self.keypair_name = guid + '-kp'
510 self.vm_inst_name = guid + '-inst'
511 self.port_1_name = guid + 'port-1'
512 self.port_2_name = guid + 'port-2'
513 self.floating_ip_name = guid + 'fip1'
515 # Initialize for tearDown()
516 self.image_creators = list()
517 self.network_creator = None
518 self.router_creator = None
519 self.flavor_creator = None
520 self.keypair_creator = None
521 self.inst_creators = list()
523 self.pub_net_config = openstack_tests.get_pub_net_config(
524 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
525 router_name=guid + '-pub-router', external_net=self.ext_net_name)
526 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
530 # Set any custom parameters sent from the app
531 if self.image_metadata:
532 if self.image_metadata['disk_url']:
533 self.os_image_settings.url = self.image_metadata['disk_url']
534 if self.image_metadata['extra_properties']:
535 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
537 # If this is a 3-part image create the kernel and ramdisk images first
538 if self.image_metadata:
539 if self.image_metadata['kernel_url']:
540 kernel_image_settings = openstack_tests.cirros_url_image(
541 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
542 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
543 kernel_image = self.image_creators[-1].create()
544 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
546 if self.image_metadata['ramdisk_url']:
547 ramdisk_image_settings = openstack_tests.cirros_url_image(
548 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
549 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
550 ramdisk_image = self.image_creators[-1].create()
551 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
553 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
554 self.image_creators[-1].create()
557 self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
558 self.network_creator.create()
561 self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
562 self.router_creator.create()
565 self.flavor_creator = OpenStackFlavor(
567 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
568 self.flavor_creator.create()
570 self.keypair_creator = OpenStackKeypair(
571 self.os_creds, KeypairSettings(
572 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
573 private_filepath=self.keypair_priv_filepath))
574 self.keypair_creator.create()
575 except Exception as e:
581 Cleans the created object
583 for inst_creator in self.inst_creators:
586 except Exception as e:
587 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
589 if self.keypair_creator:
591 self.keypair_creator.clean()
592 except Exception as e:
593 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
595 if os.path.isfile(self.keypair_pub_filepath):
596 os.remove(self.keypair_pub_filepath)
598 if os.path.isfile(self.keypair_priv_filepath):
599 os.remove(self.keypair_priv_filepath)
601 if self.flavor_creator:
603 self.flavor_creator.clean()
604 except Exception as e:
605 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
607 if self.router_creator:
609 self.router_creator.clean()
610 except Exception as e:
611 logger.error('Unexpected exception cleaning router with message - ' + e.message)
613 if self.network_creator:
615 self.network_creator.clean()
616 except Exception as e:
617 logger.error('Unexpected exception cleaning network with message - ' + e.message)
619 if self.image_creators:
621 while self.image_creators:
622 self.image_creators[-1].clean()
623 self.image_creators.pop()
624 except Exception as e:
625 logger.error('Unexpected exception cleaning image with message - ' + e.message)
627 super(self.__class__, self).__clean__()
629 def test_single_port_static(self):
631 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
635 port_settings = PortSettings(
636 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name,
637 ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}])
639 instance_settings = VmInstanceSettings(
640 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
641 floating_ip_settings=[FloatingIpSettings(
642 name=self.floating_ip_name, port_name=self.port_1_name,
643 router_name=self.pub_net_config.router_settings.name)])
645 inst_creator = OpenStackVmInstance(
646 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
647 keypair_settings=self.keypair_creator.keypair_settings)
648 self.inst_creators.append(inst_creator)
649 vm_inst = inst_creator.create()
651 self.assertEquals(ip_1, inst_creator.get_port_ip(self.port_1_name))
652 self.assertTrue(inst_creator.vm_active(block=True))
653 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
655 def test_ssh_client_fip_before_active(self):
657 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
659 port_settings = PortSettings(
660 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
662 instance_settings = VmInstanceSettings(
663 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
664 floating_ip_settings=[FloatingIpSettings(
665 name=self.floating_ip_name, port_name=self.port_1_name,
666 router_name=self.pub_net_config.router_settings.name)])
668 inst_creator = OpenStackVmInstance(
669 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
670 keypair_settings=self.keypair_creator.keypair_settings)
671 self.inst_creators.append(inst_creator)
672 vm_inst = inst_creator.create()
673 self.assertIsNotNone(vm_inst)
675 self.assertTrue(inst_creator.vm_active(block=True))
676 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
678 validate_ssh_client(inst_creator)
680 def test_ssh_client_fip_after_active(self):
682 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
684 port_settings = PortSettings(
685 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
687 instance_settings = VmInstanceSettings(
688 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
689 floating_ip_settings=[FloatingIpSettings(
690 name=self.floating_ip_name, port_name=self.port_1_name,
691 router_name=self.pub_net_config.router_settings.name)])
693 inst_creator = OpenStackVmInstance(
694 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
695 keypair_settings=self.keypair_creator.keypair_settings)
696 self.inst_creators.append(inst_creator)
698 # block=True will force the create() method to block until the
699 vm_inst = inst_creator.create(block=True)
700 self.assertIsNotNone(vm_inst)
702 self.assertTrue(inst_creator.vm_active(block=True))
703 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
705 validate_ssh_client(inst_creator)
707 # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
708 # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
709 # def test_allowed_address_port_access(self):
711 # Tests to ensure that setting allowed_address_pairs on a port functions as designed
713 # port_settings_1 = PortSettings(
714 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
716 # instance_settings_1 = VmInstanceSettings(
717 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
718 # floating_ip_settings=[FloatingIpSettings(
719 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
720 # router_name=self.pub_net_config.router_settings.name)])
722 # inst_creator_1 = OpenStackVmInstance(
723 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
724 # keypair_settings=self.keypair_creator.keypair_settings)
725 # self.inst_creators.append(inst_creator_1)
727 # # block=True will force the create() method to block until the
728 # vm_inst_1 = inst_creator_1.create(block=True)
729 # self.assertIsNotNone(vm_inst_1)
731 # port_settings_1 = PortSettings(
732 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
734 # instance_settings_1 = VmInstanceSettings(
735 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
736 # floating_ip_settings=[FloatingIpSettings(
737 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
738 # router_name=self.pub_net_config.router_settings.name)])
740 # inst_creator_1 = OpenStackVmInstance(
741 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
742 # keypair_settings=self.keypair_creator.keypair_settings)
743 # self.inst_creators.append(inst_creator_1)
744 # inst_creator_1.create(block=True)
746 # ip = inst_creator_1.get_port_ip(port_settings_1.name,
747 # subnet_name=self.pub_net_config.network_settings.subnet_settings[0].name)
748 # self.assertIsNotNone(ip)
749 # mac_addr = inst_creator_1.get_port_mac(port_settings_1.name)
750 # self.assertIsNotNone(mac_addr)
752 # allowed_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
754 # # Create VM that can be accessed by vm_inst_1
755 # port_settings_2 = PortSettings(
756 # name=self.port_1_name + '-2', network_name=self.pub_net_config.network_settings.name,
757 # allowed_address_pairs=allowed_address_pairs)
759 # instance_settings_2 = VmInstanceSettings(
760 # name=self.vm_inst_name + '-2', flavor=self.flavor_creator.flavor_settings.name,
761 # port_settings=[port_settings_2])
763 # inst_creator_2 = OpenStackVmInstance(
764 # self.os_creds, instance_settings_2, self.image_creators[-1].image_settings)
765 # self.inst_creators.append(inst_creator_2)
766 # inst_creator_2.create(block=True)
768 # # Create VM that cannot be accessed by vm_inst_1
770 # mac_addr = '0a:1b:2c:3d:4e:5f'
771 # invalid_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
773 # port_settings_3 = PortSettings(
774 # name=self.port_1_name + '-3', network_name=self.pub_net_config.network_settings.name,
775 # allowed_address_pairs=invalid_address_pairs)
777 # instance_settings_3 = VmInstanceSettings(
778 # name=self.vm_inst_name + '-3', flavor=self.flavor_creator.flavor_settings.name,
779 # port_settings=[port_settings_3])
781 # inst_creator_3 = OpenStackVmInstance(
782 # self.os_creds, instance_settings_3, self.image_creators[-1].image_settings)
783 # self.inst_creators.append(inst_creator_3)
784 # inst_creator_3.create(block=True)
787 # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would expect
788 # inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
789 # TODO - Add validation
792 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
794 Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set
799 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
802 super(self.__class__, self).__start__()
804 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
805 self.vm_inst_name = guid + '-inst'
806 self.port_1_name = guid + 'port-1'
807 self.port_2_name = guid + 'port-2'
808 self.floating_ip_name = guid + 'fip1'
810 # Initialize for tearDown()
811 self.image_creators = list()
812 self.network_creator = None
813 self.flavor_creator = None
814 self.inst_creator = None
816 self.net_config = openstack_tests.get_priv_net_config(
817 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
818 router_name=guid + '-pub-router', external_net=self.ext_net_name)
819 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
823 # Set any custom parameters sent from the app
824 if self.image_metadata:
825 if self.image_metadata['disk_url']:
826 self.os_image_settings.url = self.image_metadata['disk_url']
827 if self.image_metadata['extra_properties']:
828 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
830 # If this is a 3-part image create the kernel and ramdisk images first
831 if self.image_metadata:
832 if self.image_metadata['kernel_url']:
833 kernel_image_settings = openstack_tests.cirros_url_image(
834 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
835 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
836 kernel_image = self.image_creators[-1].create()
837 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
839 if self.image_metadata['ramdisk_url']:
840 ramdisk_image_settings = openstack_tests.cirros_url_image(
841 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
842 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
843 ramdisk_image = self.image_creators[-1].create()
844 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
846 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
847 self.image_creators[-1].create()
850 self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
851 self.network_creator.create()
854 self.flavor_creator = OpenStackFlavor(
856 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
857 self.flavor_creator.create()
858 except Exception as e:
864 Cleans the created object
866 if self.inst_creator:
868 self.inst_creator.clean()
869 except Exception as e:
870 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
872 if self.flavor_creator:
874 self.flavor_creator.clean()
875 except Exception as e:
876 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
878 if self.network_creator:
880 self.network_creator.clean()
881 except Exception as e:
882 logger.error('Unexpected exception cleaning network with message - ' + e.message)
884 if self.image_creators:
886 while self.image_creators:
887 self.image_creators[-1].clean()
888 self.image_creators.pop()
889 except Exception as e:
890 logger.error('Unexpected exception cleaning image with message - ' + e.message)
892 super(self.__class__, self).__clean__()
894 def test_set_custom_valid_ip_one_subnet(self):
896 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
899 port_settings = PortSettings(
900 name=self.port_1_name, network_name=self.net_config.network_settings.name,
901 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
903 instance_settings = VmInstanceSettings(
904 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
906 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
907 self.inst_creator.create()
909 self.assertEquals(ip, self.inst_creator.get_port_ip(
910 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
912 def test_set_custom_invalid_ip_one_subnet(self):
914 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
917 port_settings = PortSettings(
918 name=self.port_1_name, network_name=self.net_config.network_settings.name,
919 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
921 instance_settings = VmInstanceSettings(
922 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
924 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
926 with self.assertRaises(Exception):
927 self.inst_creator.create()
929 def test_set_custom_valid_mac(self):
931 Tests the creation of an OpenStack instance with a single port where the MAC address is assigned.
933 mac_addr = '0a:1b:2c:3d:4e:5f'
934 port_settings = PortSettings(
935 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr)
937 instance_settings = VmInstanceSettings(
938 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
940 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
941 self.inst_creator.create()
943 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
945 def test_set_custom_invalid_mac(self):
947 Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being
948 assigned. This should raise an Exception
950 port_settings = PortSettings(
951 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo')
953 instance_settings = VmInstanceSettings(
954 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
956 self.inst_creator = OpenStackVmInstance(
957 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
959 with self.assertRaises(Exception):
960 self.inst_creator.create()
962 def test_set_custom_mac_and_ip(self):
964 Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned.
967 mac_addr = '0a:1b:2c:3d:4e:5f'
968 port_settings = PortSettings(
969 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr,
970 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
972 instance_settings = VmInstanceSettings(
973 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
975 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
976 self.inst_creator.create()
978 self.assertEquals(ip, self.inst_creator.get_port_ip(
979 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
980 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
982 def test_set_allowed_address_pairs(self):
984 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set.
987 mac_addr = '0a:1b:2c:3d:4e:5f'
988 pair = {'ip_address': ip, 'mac_address': mac_addr}
989 port_settings = PortSettings(
990 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
992 instance_settings = VmInstanceSettings(
993 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
995 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
996 self.inst_creator.create()
998 port = self.inst_creator.get_port_by_name(port_settings.name)
999 self.assertIsNotNone(port)
1000 self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
1001 self.assertEquals(1, len(port['port']['allowed_address_pairs']))
1002 validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0])
1004 def test_set_allowed_address_pairs_bad_mac(self):
1006 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1007 invalid MAC address.
1011 pair = {'ip_address': ip, 'mac_address': mac_addr}
1013 pairs.add((ip, mac_addr))
1014 port_settings = PortSettings(
1015 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1017 instance_settings = VmInstanceSettings(
1018 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1020 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1021 with self.assertRaises(Exception):
1022 self.inst_creator.create()
1024 def test_set_allowed_address_pairs_bad_ip(self):
1026 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1027 invalid MAC address.
1030 mac_addr = '0a:1b:2c:3d:4e:5f'
1031 pair = {'ip_address': ip, 'mac_address': mac_addr}
1033 pairs.add((ip, mac_addr))
1034 port_settings = PortSettings(
1035 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1037 instance_settings = VmInstanceSettings(
1038 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1040 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1041 with self.assertRaises(Exception):
1042 self.inst_creator.create()
1045 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1047 Test for the CreateInstance where one VM is deployed to each compute node
1052 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1055 super(self.__class__, self).__start__()
1057 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1058 self.vm_inst_name = guid + '-inst'
1059 self.port_base_name = guid + 'port'
1061 # Initialize for tearDown()
1062 self.image_creators = list()
1063 self.flavor_creator = None
1064 self.network_creator = None
1065 self.inst_creators = list()
1067 self.priv_net_config = openstack_tests.get_priv_net_config(
1068 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
1070 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
1074 self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
1075 self.network_creator.create()
1078 self.flavor_creator = OpenStackFlavor(
1079 self.admin_os_creds,
1080 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
1081 self.flavor_creator.create()
1084 # Set any custom parameters sent from the app
1085 if self.image_metadata:
1086 if self.image_metadata['disk_url']:
1087 self.os_image_settings.url = self.image_metadata['disk_url']
1088 if self.image_metadata['extra_properties']:
1089 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1091 # If this is a 3-part image create the kernel and ramdisk images first
1092 if self.image_metadata:
1093 if self.image_metadata['kernel_url']:
1094 kernel_image_settings = openstack_tests.cirros_url_image(
1095 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1096 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1097 kernel_image = self.image_creators[-1].create()
1098 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1100 if self.image_metadata['ramdisk_url']:
1101 ramdisk_image_settings = openstack_tests.cirros_url_image(
1102 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1103 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1104 ramdisk_image = self.image_creators[-1].create()
1105 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1107 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1108 self.image_creators[-1].create()
1110 except Exception as e:
1116 Cleans the created object
1118 for inst_creator in self.inst_creators:
1120 inst_creator.clean()
1121 except Exception as e:
1122 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1124 if self.flavor_creator:
1126 self.flavor_creator.clean()
1127 except Exception as e:
1128 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1130 if self.network_creator:
1132 self.network_creator.clean()
1133 except Exception as e:
1134 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1136 if self.image_creators:
1138 while self.image_creators:
1139 self.image_creators[-1].clean()
1140 self.image_creators.pop()
1141 except Exception as e:
1142 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1144 super(self.__class__, self).__clean__()
1146 def test_deploy_vm_to_each_compute_node(self):
1148 Tests the creation of OpenStack VM instances to each compute node.
1150 from snaps.openstack.utils import nova_utils
1151 nova = nova_utils.nova_client(self.admin_os_creds)
1152 zones = nova_utils.get_nova_availability_zones(nova)
1154 # Create Instance on each server/zone
1157 inst_name = self.vm_inst_name + '-' + zone
1159 port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr),
1160 network_name=self.priv_net_config.network_settings.name)
1162 instance_settings = VmInstanceSettings(
1163 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
1164 port_settings=[port_settings])
1165 inst_creator = OpenStackVmInstance(
1166 self.admin_os_creds, instance_settings, self.image_creators[-1].image_settings)
1167 self.inst_creators.append(inst_creator)
1168 inst_creator.create()
1170 # Validate instances to ensure they've been deployed to the correct server
1173 creator = self.inst_creators[index]
1174 self.assertTrue(creator.vm_active(block=True))
1175 vm = creator.get_vm_inst()
1176 deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
1177 deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
1178 self.assertEquals(zone, deployed_zone + ':' + deployed_host)
1182 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1184 Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o
1185 These tests require a Centos image
1190 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1193 super(self.__class__, self).__start__()
1195 # Initialize for tearDown()
1196 self.image_creators = list()
1197 self.network_creators = list()
1198 self.router_creators = list()
1199 self.flavor_creator = None
1200 self.keypair_creator = None
1201 self.inst_creator = None
1203 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1204 self.keypair_priv_filepath = 'tmp/' + self.guid
1205 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1206 self.keypair_name = self.guid + '-kp'
1207 self.vm_inst_name = self.guid + '-inst'
1208 self.port_1_name = self.guid + '-port-1'
1209 self.port_2_name = self.guid + '-port-2'
1210 self.floating_ip_name = self.guid + 'fip1'
1211 self.priv_net_config = openstack_tests.get_priv_net_config(
1212 net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet',
1213 router_name=self.guid + '-priv-router', external_net=self.ext_net_name)
1214 self.pub_net_config = openstack_tests.get_pub_net_config(
1215 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1216 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1217 image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1218 self.os_image_settings = openstack_tests.centos_url_image(name=image_name)
1222 # Set any custom parameters sent from the app
1223 if self.image_metadata:
1224 if self.image_metadata['disk_url']:
1225 self.os_image_settings.url = self.image_metadata['disk_url']
1226 if self.image_metadata['extra_properties']:
1227 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1229 # If this is a 3-part image create the kernel and ramdisk images first
1230 if self.image_metadata:
1231 if self.image_metadata['kernel_url']:
1232 kernel_image_settings = openstack_tests.cirros_url_image(
1233 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1234 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1235 kernel_image = self.image_creators[-1].create()
1236 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1238 if self.image_metadata['ramdisk_url']:
1239 ramdisk_image_settings = openstack_tests.cirros_url_image(
1240 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1241 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1242 ramdisk_image = self.image_creators[-1].create()
1243 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1245 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1246 self.image_creators[-1].create()
1248 # First network is public
1249 self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
1250 # Second network is private
1251 self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings))
1252 for network_creator in self.network_creators:
1253 network_creator.create()
1255 self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings))
1256 self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings))
1259 for router_creator in self.router_creators:
1260 router_creator.create()
1263 self.flavor_creator = OpenStackFlavor(
1264 self.admin_os_creds,
1265 FlavorSettings(name=self.guid + '-flavor-name', ram=2048, disk=10, vcpus=2,
1266 metadata=self.flavor_metadata))
1267 self.flavor_creator.create()
1270 self.keypair_creator = OpenStackKeypair(
1271 self.os_creds, KeypairSettings(
1272 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
1273 private_filepath=self.keypair_priv_filepath))
1274 self.keypair_creator.create()
1275 except Exception as e:
1277 raise Exception(e.message)
1281 Cleans the created objects
1283 if self.inst_creator:
1285 self.inst_creator.clean()
1286 except Exception as e:
1287 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1289 if self.keypair_creator:
1291 self.keypair_creator.clean()
1292 except Exception as e:
1293 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
1295 if os.path.isfile(self.keypair_pub_filepath):
1296 os.remove(self.keypair_pub_filepath)
1298 if os.path.isfile(self.keypair_priv_filepath):
1299 os.remove(self.keypair_priv_filepath)
1301 if self.flavor_creator:
1303 self.flavor_creator.clean()
1304 except Exception as e:
1305 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1307 for router_creator in self.router_creators:
1309 router_creator.clean()
1310 except Exception as e:
1311 logger.error('Unexpected exception cleaning router with message - ' + e.message)
1313 for network_creator in self.network_creators:
1315 network_creator.clean()
1316 except Exception as e:
1317 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1319 if self.image_creators:
1321 while self.image_creators:
1322 self.image_creators[-1].clean()
1323 self.image_creators.pop()
1324 except Exception as e:
1325 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1327 super(self.__class__, self).__clean__()
1329 def test_dual_ports_dhcp(self):
1331 Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP.
1332 NOTE: This test and any others that call ansible will most likely fail unless you do one of
1334 1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False
1335 2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False
1336 Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail.
1338 # Create ports/NICs for instance
1341 for network_creator in self.network_creators:
1342 ports_settings.append(PortSettings(
1343 name=self.guid + '-port-' + str(ctr),
1344 network_name=network_creator.network_settings.name))
1348 instance_settings = VmInstanceSettings(
1349 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings,
1350 floating_ip_settings=[FloatingIpSettings(
1351 name=self.floating_ip_name, port_name=self.port_1_name,
1352 router_name=self.pub_net_config.router_settings.name)])
1354 self.inst_creator = OpenStackVmInstance(
1355 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
1356 keypair_settings=self.keypair_creator.keypair_settings)
1358 vm_inst = self.inst_creator.create(block=True)
1360 self.assertEquals(vm_inst, self.inst_creator.get_vm_inst())
1362 # Effectively blocks until VM has been properly activated
1363 self.assertTrue(self.inst_creator.vm_active(block=True))
1365 # Effectively blocks until VM's ssh port has been opened
1366 self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1368 self.inst_creator.config_nics()
1370 # TODO - *** ADD VALIDATION HERE ***
1371 # TODO - Add validation that both floating IPs work
1372 # TODO - Add tests where only one NIC has a floating IP
1373 # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway
1376 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1378 Tests that include, add, and remove security groups from VM instances
1382 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1385 super(self.__class__, self).__start__()
1387 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1388 self.vm_inst_name = self.guid + '-inst'
1389 self.nova = nova_utils.nova_client(self.os_creds)
1390 self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
1392 self.vm_inst_name = self.guid + '-inst'
1393 self.port_1_name = self.guid + 'port-1'
1394 self.port_2_name = self.guid + 'port-2'
1395 self.floating_ip_name = self.guid + 'fip1'
1397 net_config = openstack_tests.get_priv_net_config(
1398 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1399 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1401 # Initialize for tearDown()
1402 self.image_creators = list()
1403 self.flavor_creator = None
1404 self.network_creator = None
1405 self.router_creator = None
1406 self.inst_creator = None
1407 self.sec_grp_creators = list()
1411 # Set any custom parameters sent from the app
1412 if self.image_metadata:
1413 if self.image_metadata['disk_url']:
1414 self.os_image_settings.url = self.image_metadata['disk_url']
1415 if self.image_metadata['extra_properties']:
1416 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1418 # If this is a 3-part image create the kernel and ramdisk images first
1419 if self.image_metadata:
1420 if self.image_metadata['kernel_url']:
1421 kernel_image_settings = openstack_tests.cirros_url_image(
1422 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1423 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1424 kernel_image = self.image_creators[-1].create()
1425 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1427 if self.image_metadata['ramdisk_url']:
1428 ramdisk_image_settings = openstack_tests.cirros_url_image(
1429 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1430 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1431 ramdisk_image = self.image_creators[-1].create()
1432 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1434 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1435 self.image_creators[-1].create()
1438 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1439 self.network_creator.create()
1442 self.flavor_creator = OpenStackFlavor(
1443 self.admin_os_creds,
1444 FlavorSettings(name=self.guid + '-flavor-name', ram=2048, disk=10, vcpus=2,
1445 metadata=self.flavor_metadata))
1446 self.flavor_creator.create()
1448 self.port_settings = PortSettings(name=self.guid + '-port',
1449 network_name=net_config.network_settings.name)
1450 except Exception as e:
1456 Cleans the created object
1458 if self.inst_creator:
1460 self.inst_creator.clean()
1461 except Exception as e:
1462 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1464 for sec_grp_creator in self.sec_grp_creators:
1466 sec_grp_creator.clean()
1467 except Exception as e:
1468 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
1470 if self.flavor_creator:
1472 self.flavor_creator.clean()
1473 except Exception as e:
1474 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1476 if self.network_creator:
1478 self.network_creator.clean()
1479 except Exception as e:
1480 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1482 if self.image_creators:
1484 while self.image_creators:
1485 self.image_creators[-1].clean()
1486 self.image_creators.pop()
1487 except Exception as e:
1488 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1490 super(self.__class__, self).__clean__()
1492 def test_add_security_group(self):
1494 Tests the addition of a security group created after the instance.
1497 instance_settings = VmInstanceSettings(
1498 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1499 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1500 vm_inst = self.inst_creator.create(block=True)
1501 self.assertIsNotNone(vm_inst)
1503 # Create security group object to add to instance
1504 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1505 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1506 sec_grp = sec_grp_creator.create()
1507 self.sec_grp_creators.append(sec_grp_creator)
1509 # Check that group has not been added
1510 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1512 # Add security group to instance after activated
1513 self.inst_creator.add_security_group(sec_grp)
1515 # Validate that security group has been added
1516 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1518 def test_add_invalid_security_group(self):
1520 Tests the addition of a security group that no longer exists.
1523 instance_settings = VmInstanceSettings(
1524 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1525 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1526 vm_inst = self.inst_creator.create(block=True)
1527 self.assertIsNotNone(vm_inst)
1529 # Create security group object to add to instance
1530 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1531 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1532 sec_grp = sec_grp_creator.create()
1533 sec_grp_creator.clean()
1534 self.sec_grp_creators.append(sec_grp_creator)
1536 # Check that group has not been added
1537 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1539 # Add security group to instance after activated
1540 self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1542 # Validate that security group has been added
1543 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1545 def test_remove_security_group(self):
1547 Tests the removal of a security group created before and added to the instance.
1549 # Create security group object to add to instance
1550 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1551 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1552 sec_grp = sec_grp_creator.create()
1553 self.sec_grp_creators.append(sec_grp_creator)
1556 instance_settings = VmInstanceSettings(
1557 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1558 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1559 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1560 vm_inst = self.inst_creator.create(block=True)
1561 self.assertIsNotNone(vm_inst)
1563 # Check that group has been added
1564 self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
1566 # Add security group to instance after activated
1567 self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1569 # Validate that security group has been added
1570 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1572 def test_remove_security_group_never_added(self):
1574 Tests the removal of a security group that was never added in the first place.
1576 # Create security group object to add to instance
1577 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1578 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1579 sec_grp = sec_grp_creator.create()
1580 self.sec_grp_creators.append(sec_grp_creator)
1583 instance_settings = VmInstanceSettings(
1584 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1585 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1586 vm_inst = self.inst_creator.create(block=True)
1587 self.assertIsNotNone(vm_inst)
1589 # Check that group has been added
1590 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1592 # Add security group to instance after activated
1593 self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1595 # Validate that security group has been added
1596 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1598 def test_add_same_security_group(self):
1600 Tests the addition of a security group created before add added to the instance.
1602 # Create security group object to add to instance
1603 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1604 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1605 sec_grp = sec_grp_creator.create()
1606 self.sec_grp_creators.append(sec_grp_creator)
1609 instance_settings = VmInstanceSettings(
1610 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1611 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1612 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1613 vm_inst = self.inst_creator.create(block=True)
1614 self.assertIsNotNone(vm_inst)
1616 # Check that group has been added
1617 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1619 # Add security group to instance after activated
1620 self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1622 # Validate that security group has been added
1623 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1626 def inst_has_sec_grp(vm_inst, sec_grp_name):
1628 Returns true if instance has a security group of a given name
1631 if not hasattr(vm_inst, 'security_groups'):
1635 for sec_grp_dict in vm_inst.security_groups:
1636 if sec_grp_name in sec_grp_dict['name']:
1642 def validate_ssh_client(instance_creator):
1644 Returns True if instance_creator returns an SSH client that is valid
1645 :param instance_creator: the object responsible for creating the VM instance
1648 ssh_active = instance_creator.vm_ssh_active(block=True)
1651 ssh_client = instance_creator.ssh_client()
1653 out = ssh_client.exec_command('pwd')[1]
1657 channel = out.channel
1658 in_buffer = channel.in_buffer
1659 pwd_out = in_buffer.read(1024)
1660 if not pwd_out or len(pwd_out) < 10:
1667 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1669 Test for the CreateInstance class for creating an image from a 3-part image
1674 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1677 super(self.__class__, self).__start__()
1679 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1680 self.image_name = guid
1681 self.vm_inst_name = guid + '-inst'
1682 self.nova = nova_utils.nova_client(self.os_creds)
1684 net_config = openstack_tests.get_priv_net_config(
1685 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1686 router_name=guid + '-pub-router', external_net=self.ext_net_name)
1688 # Initialize for tearDown()
1689 self.image_creators = list()
1690 self.network_creator = None
1691 self.flavor_creator = None
1692 self.inst_creator = None
1698 if self.image_metadata and self.image_metadata['extra_properties']:
1699 properties = self.image_metadata['extra_properties']
1701 # Create the kernel image
1702 kernel_image_settings = openstack_tests.cirros_url_image(
1703 name=self.image_name+'_kernel',
1704 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
1705 if self.image_metadata and self.image_metadata['kernel_url']:
1706 kernel_url = self.image_metadata['kernel_url']
1707 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1708 kernel_image = self.image_creators[-1].create()
1710 # Create the ramdisk image
1711 ramdisk_image_settings = openstack_tests.cirros_url_image(
1712 name=self.image_name+'_ramdisk',
1713 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
1714 if self.image_metadata and self.image_metadata['ramdisk_url']:
1715 ramdisk_url = self.image_metadata['ramdisk_url']
1716 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1717 ramdisk_image = self.image_creators[-1].create()
1718 self.assertIsNotNone(ramdisk_image)
1720 # Create the main image
1721 os_image_settings = openstack_tests.cirros_url_image(
1722 name=self.image_name,
1723 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
1724 if self.image_metadata and self.image_metadata['disk_url']:
1725 umage_url = self.image_metadata['disk_url']
1726 properties['kernel_id'] = kernel_image.id
1727 properties['ramdisk_id'] = ramdisk_image.id
1728 os_image_settings.extra_properties = properties
1729 self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
1730 created_image = self.image_creators[-1].create()
1731 self.assertIsNotNone(created_image)
1734 self.flavor_creator = OpenStackFlavor(
1735 self.admin_os_creds,
1736 FlavorSettings(name=guid + '-flavor-name', ram=2048, disk=10, vcpus=2, metadata=self.flavor_metadata))
1737 self.flavor_creator.create()
1740 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1741 self.network_creator.create()
1743 self.port_settings = PortSettings(name=guid + '-port',
1744 network_name=net_config.network_settings.name)
1745 except Exception as e:
1751 Cleans the created object
1753 if self.inst_creator:
1755 self.inst_creator.clean()
1756 except Exception as e:
1757 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1759 if self.flavor_creator:
1761 self.flavor_creator.clean()
1762 except Exception as e:
1763 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1765 if self.network_creator:
1767 self.network_creator.clean()
1768 except Exception as e:
1769 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1771 if self.image_creators:
1773 while self.image_creators:
1774 self.image_creators[0].clean()
1775 self.image_creators.pop(0)
1776 except Exception as e:
1777 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1779 super(self.__class__, self).__clean__()
1781 def test_create_delete_instance_from_three_part_image(self):
1783 Tests the creation of an OpenStack instance from a 3-part image.
1785 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1786 port_settings=[self.port_settings])
1788 # The last created image is the main image from which we create the instance
1789 self.inst_creator = OpenStackVmInstance(
1790 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1792 vm_inst = self.inst_creator.create()
1793 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1796 nova_utils.delete_vm_instance(self.nova, vm_inst)
1798 self.assertTrue(self.inst_creator.vm_deleted(block=True))
1799 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1801 # Exception should not be thrown
1802 self.inst_creator.clean()