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 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
262 self.os_image_settings.url = self.image_metadata['disk_url']
263 if 'extra_properties' in self.image_metadata and 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 'kernel_url' in self.image_metadata and 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 'ramdisk_url' in self.image_metadata and 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=128, 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.network_creator:
317 self.network_creator.clean()
318 except Exception as e:
319 logger.error('Unexpected exception cleaning network with message - ' + e.message)
321 if self.flavor_creator:
323 self.flavor_creator.clean()
324 except Exception as e:
325 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
327 if self.image_creators:
329 while self.image_creators:
330 self.image_creators[-1].clean()
331 self.image_creators.pop()
332 except Exception as e:
333 logger.error('Unexpected exception cleaning image with message - ' + e.message)
335 super(self.__class__, self).__clean__()
337 def test_check_vm_ip_dhcp(self):
339 Tests the creation of an OpenStack instance with a single port and ensures that it's assigned IP address is
342 instance_settings = VmInstanceSettings(
343 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
345 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
346 self.image_creators[-1].image_settings)
347 vm = self.inst_creator.create()
349 ip = self.inst_creator.get_port_ip(self.port_settings.name)
350 self.assertIsNotNone(ip)
352 self.assertTrue(self.inst_creator.vm_active(block=True))
356 start_time = time.time()
358 logger.info("Looking for IP %s in the console log" % ip)
360 while timeout > time.time() - start_time:
361 output = vm.get_console_output()
362 full_log = full_log + output
363 if re.search(ip, output):
364 logger.info('DHCP lease obtained logged in console')
369 logger.error('Full console output -\n' + full_log)
371 logger.debug('Full console output -\n' + full_log)
373 self.assertTrue(found)
376 class CreateInstanceSimpleTests(OSIntegrationTestCase):
378 Simple instance creation tests without any other objects
382 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
385 super(self.__class__, self).__start__()
387 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
388 self.vm_inst_name = guid + '-inst'
389 self.nova = nova_utils.nova_client(self.os_creds)
390 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
392 net_config = openstack_tests.get_priv_net_config(
393 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
394 router_name=guid + '-pub-router', external_net=self.ext_net_name)
396 # Initialize for tearDown()
397 self.image_creators = list()
398 self.flavor_creator = None
400 self.network_creator = None
401 self.inst_creator = None
405 # Set any custom parameters sent from the app
406 if self.image_metadata:
407 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
408 self.os_image_settings.url = self.image_metadata['disk_url']
409 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
410 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
412 # If this is a 3-part image create the kernel and ramdisk images first
413 if self.image_metadata:
414 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
415 kernel_image_settings = openstack_tests.cirros_url_image(
416 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
417 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
418 kernel_image = self.image_creators[-1].create()
419 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
421 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
422 ramdisk_image_settings = openstack_tests.cirros_url_image(
423 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
424 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
425 ramdisk_image = self.image_creators[-1].create()
426 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
428 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
429 self.image_creators[-1].create()
432 self.flavor_creator = OpenStackFlavor(
434 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
435 self.flavor_creator.create()
438 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
439 self.network_creator.create()
441 self.port_settings = PortSettings(name=guid + '-port',
442 network_name=net_config.network_settings.name)
444 except Exception as e:
450 Cleans the created object
452 if self.inst_creator:
454 self.inst_creator.clean()
455 except Exception as e:
456 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
458 if self.flavor_creator:
460 self.flavor_creator.clean()
461 except Exception as e:
462 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
464 if self.network_creator:
466 self.network_creator.clean()
467 except Exception as e:
468 logger.error('Unexpected exception cleaning network with message - ' + e.message)
470 if self.image_creators:
472 while self.image_creators:
473 self.image_creators[-1].clean()
474 self.image_creators.pop()
475 except Exception as e:
476 logger.error('Unexpected exception cleaning image with message - ' + e.message)
478 super(self.__class__, self).__clean__()
480 def test_create_delete_instance(self):
482 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
484 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
485 port_settings=[self.port_settings])
487 self.inst_creator = OpenStackVmInstance(
488 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
490 vm_inst = self.inst_creator.create()
491 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
494 nova_utils.delete_vm_instance(self.nova, vm_inst)
496 self.assertTrue(self.inst_creator.vm_deleted(block=True))
497 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
499 # Exception should not be thrown
500 self.inst_creator.clean()
503 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
505 Test for the CreateInstance class with a single NIC/Port with Floating IPs
510 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
513 super(self.__class__, self).__start__()
515 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
516 self.keypair_priv_filepath = 'tmp/' + guid
517 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
518 self.keypair_name = guid + '-kp'
519 self.vm_inst_name = guid + '-inst'
520 self.port_1_name = guid + 'port-1'
521 self.port_2_name = guid + 'port-2'
522 self.floating_ip_name = guid + 'fip1'
524 # Initialize for tearDown()
525 self.image_creators = list()
526 self.network_creator = None
527 self.router_creator = None
528 self.flavor_creator = None
529 self.keypair_creator = None
530 self.inst_creators = list()
532 self.pub_net_config = openstack_tests.get_pub_net_config(
533 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
534 router_name=guid + '-pub-router', external_net=self.ext_net_name)
535 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
539 # Set any custom parameters sent from the app
540 if self.image_metadata:
541 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
542 self.os_image_settings.url = self.image_metadata['disk_url']
543 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
544 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
546 # If this is a 3-part image create the kernel and ramdisk images first
547 if self.image_metadata:
548 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
549 kernel_image_settings = openstack_tests.cirros_url_image(
550 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
551 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
552 kernel_image = self.image_creators[-1].create()
553 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
555 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
556 ramdisk_image_settings = openstack_tests.cirros_url_image(
557 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
558 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
559 ramdisk_image = self.image_creators[-1].create()
560 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
562 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
563 self.image_creators[-1].create()
566 self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
567 self.network_creator.create()
570 self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
571 self.router_creator.create()
574 self.flavor_creator = OpenStackFlavor(
576 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
577 self.flavor_creator.create()
579 self.keypair_creator = OpenStackKeypair(
580 self.os_creds, KeypairSettings(
581 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
582 private_filepath=self.keypair_priv_filepath))
583 self.keypair_creator.create()
584 except Exception as e:
590 Cleans the created object
592 for inst_creator in self.inst_creators:
595 except Exception as e:
596 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
598 if self.keypair_creator:
600 self.keypair_creator.clean()
601 except Exception as e:
602 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
604 if os.path.isfile(self.keypair_pub_filepath):
605 os.remove(self.keypair_pub_filepath)
607 if os.path.isfile(self.keypair_priv_filepath):
608 os.remove(self.keypair_priv_filepath)
610 if self.flavor_creator:
612 self.flavor_creator.clean()
613 except Exception as e:
614 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
616 if self.router_creator:
618 self.router_creator.clean()
619 except Exception as e:
620 logger.error('Unexpected exception cleaning router with message - ' + e.message)
622 if self.network_creator:
624 self.network_creator.clean()
625 except Exception as e:
626 logger.error('Unexpected exception cleaning network with message - ' + e.message)
628 if self.image_creators:
630 while self.image_creators:
631 self.image_creators[-1].clean()
632 self.image_creators.pop()
633 except Exception as e:
634 logger.error('Unexpected exception cleaning image with message - ' + e.message)
636 super(self.__class__, self).__clean__()
638 def test_single_port_static(self):
640 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
644 port_settings = PortSettings(
645 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name,
646 ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}])
648 instance_settings = VmInstanceSettings(
649 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
650 floating_ip_settings=[FloatingIpSettings(
651 name=self.floating_ip_name, port_name=self.port_1_name,
652 router_name=self.pub_net_config.router_settings.name)])
654 inst_creator = OpenStackVmInstance(
655 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
656 keypair_settings=self.keypair_creator.keypair_settings)
657 self.inst_creators.append(inst_creator)
658 vm_inst = inst_creator.create()
660 self.assertEquals(ip_1, inst_creator.get_port_ip(self.port_1_name))
661 self.assertTrue(inst_creator.vm_active(block=True))
662 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
664 def test_ssh_client_fip_before_active(self):
666 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
668 port_settings = PortSettings(
669 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
671 instance_settings = VmInstanceSettings(
672 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
673 floating_ip_settings=[FloatingIpSettings(
674 name=self.floating_ip_name, port_name=self.port_1_name,
675 router_name=self.pub_net_config.router_settings.name)])
677 inst_creator = OpenStackVmInstance(
678 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
679 keypair_settings=self.keypair_creator.keypair_settings)
680 self.inst_creators.append(inst_creator)
681 vm_inst = inst_creator.create()
682 self.assertIsNotNone(vm_inst)
684 self.assertTrue(inst_creator.vm_active(block=True))
685 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
687 self.assertTrue(validate_ssh_client(inst_creator))
689 def test_ssh_client_fip_after_active(self):
691 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
693 port_settings = PortSettings(
694 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
696 instance_settings = VmInstanceSettings(
697 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
698 floating_ip_settings=[FloatingIpSettings(
699 name=self.floating_ip_name, port_name=self.port_1_name,
700 router_name=self.pub_net_config.router_settings.name)])
702 inst_creator = OpenStackVmInstance(
703 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
704 keypair_settings=self.keypair_creator.keypair_settings)
705 self.inst_creators.append(inst_creator)
707 # block=True will force the create() method to block until the
708 vm_inst = inst_creator.create(block=True)
709 self.assertIsNotNone(vm_inst)
711 self.assertTrue(inst_creator.vm_active(block=True))
712 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
714 self.assertTrue(validate_ssh_client(inst_creator))
716 # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
717 # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
718 # def test_allowed_address_port_access(self):
720 # Tests to ensure that setting allowed_address_pairs on a port functions as designed
722 # port_settings_1 = PortSettings(
723 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
725 # instance_settings_1 = VmInstanceSettings(
726 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
727 # floating_ip_settings=[FloatingIpSettings(
728 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
729 # router_name=self.pub_net_config.router_settings.name)])
731 # inst_creator_1 = OpenStackVmInstance(
732 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
733 # keypair_settings=self.keypair_creator.keypair_settings)
734 # self.inst_creators.append(inst_creator_1)
736 # # block=True will force the create() method to block until the
737 # vm_inst_1 = inst_creator_1.create(block=True)
738 # self.assertIsNotNone(vm_inst_1)
740 # port_settings_1 = PortSettings(
741 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
743 # instance_settings_1 = VmInstanceSettings(
744 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
745 # floating_ip_settings=[FloatingIpSettings(
746 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
747 # router_name=self.pub_net_config.router_settings.name)])
749 # inst_creator_1 = OpenStackVmInstance(
750 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
751 # keypair_settings=self.keypair_creator.keypair_settings)
752 # self.inst_creators.append(inst_creator_1)
753 # inst_creator_1.create(block=True)
755 # ip = inst_creator_1.get_port_ip(port_settings_1.name,
756 # subnet_name=self.pub_net_config.network_settings.subnet_settings[0].name)
757 # self.assertIsNotNone(ip)
758 # mac_addr = inst_creator_1.get_port_mac(port_settings_1.name)
759 # self.assertIsNotNone(mac_addr)
761 # allowed_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
763 # # Create VM that can be accessed by vm_inst_1
764 # port_settings_2 = PortSettings(
765 # name=self.port_1_name + '-2', network_name=self.pub_net_config.network_settings.name,
766 # allowed_address_pairs=allowed_address_pairs)
768 # instance_settings_2 = VmInstanceSettings(
769 # name=self.vm_inst_name + '-2', flavor=self.flavor_creator.flavor_settings.name,
770 # port_settings=[port_settings_2])
772 # inst_creator_2 = OpenStackVmInstance(
773 # self.os_creds, instance_settings_2, self.image_creators[-1].image_settings)
774 # self.inst_creators.append(inst_creator_2)
775 # inst_creator_2.create(block=True)
777 # # Create VM that cannot be accessed by vm_inst_1
779 # mac_addr = '0a:1b:2c:3d:4e:5f'
780 # invalid_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
782 # port_settings_3 = PortSettings(
783 # name=self.port_1_name + '-3', network_name=self.pub_net_config.network_settings.name,
784 # allowed_address_pairs=invalid_address_pairs)
786 # instance_settings_3 = VmInstanceSettings(
787 # name=self.vm_inst_name + '-3', flavor=self.flavor_creator.flavor_settings.name,
788 # port_settings=[port_settings_3])
790 # inst_creator_3 = OpenStackVmInstance(
791 # self.os_creds, instance_settings_3, self.image_creators[-1].image_settings)
792 # self.inst_creators.append(inst_creator_3)
793 # inst_creator_3.create(block=True)
796 # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would
797 # expect inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
798 # TODO - Add validation
801 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
803 Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set
808 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
811 super(self.__class__, self).__start__()
813 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
814 self.vm_inst_name = guid + '-inst'
815 self.port_1_name = guid + 'port-1'
816 self.port_2_name = guid + 'port-2'
817 self.floating_ip_name = guid + 'fip1'
819 # Initialize for tearDown()
820 self.image_creators = list()
821 self.network_creator = None
822 self.flavor_creator = None
823 self.inst_creator = None
825 self.net_config = openstack_tests.get_priv_net_config(
826 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
827 router_name=guid + '-pub-router', external_net=self.ext_net_name)
828 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
832 # Set any custom parameters sent from the app
833 if self.image_metadata:
834 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
835 self.os_image_settings.url = self.image_metadata['disk_url']
836 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
837 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
839 # If this is a 3-part image create the kernel and ramdisk images first
840 if self.image_metadata:
841 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
842 kernel_image_settings = openstack_tests.cirros_url_image(
843 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
844 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
845 kernel_image = self.image_creators[-1].create()
846 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
848 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
849 ramdisk_image_settings = openstack_tests.cirros_url_image(
850 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
851 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
852 ramdisk_image = self.image_creators[-1].create()
853 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
855 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
856 self.image_creators[-1].create()
859 self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
860 self.network_creator.create()
863 self.flavor_creator = OpenStackFlavor(
865 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
866 self.flavor_creator.create()
867 except Exception as e:
873 Cleans the created object
875 if self.inst_creator:
877 self.inst_creator.clean()
878 except Exception as e:
879 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
881 if self.flavor_creator:
883 self.flavor_creator.clean()
884 except Exception as e:
885 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
887 if self.network_creator:
889 self.network_creator.clean()
890 except Exception as e:
891 logger.error('Unexpected exception cleaning network with message - ' + e.message)
893 if self.image_creators:
895 while self.image_creators:
896 self.image_creators[-1].clean()
897 self.image_creators.pop()
898 except Exception as e:
899 logger.error('Unexpected exception cleaning image with message - ' + e.message)
901 super(self.__class__, self).__clean__()
903 def test_set_custom_valid_ip_one_subnet(self):
905 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
908 port_settings = PortSettings(
909 name=self.port_1_name, network_name=self.net_config.network_settings.name,
910 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
912 instance_settings = VmInstanceSettings(
913 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
915 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
916 self.image_creators[-1].image_settings)
917 self.inst_creator.create(block=True)
919 self.assertEquals(ip, self.inst_creator.get_port_ip(
920 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
922 def test_set_custom_invalid_ip_one_subnet(self):
924 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
927 port_settings = PortSettings(
928 name=self.port_1_name, network_name=self.net_config.network_settings.name,
929 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
931 instance_settings = VmInstanceSettings(
932 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
934 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
935 self.image_creators[-1].image_settings)
937 with self.assertRaises(Exception):
938 self.inst_creator.create()
940 def test_set_custom_valid_mac(self):
942 Tests the creation of an OpenStack instance with a single port where the MAC address is assigned.
944 mac_addr = '0a:1b:2c:3d:4e:5f'
945 port_settings = PortSettings(
946 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr)
948 instance_settings = VmInstanceSettings(
949 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
951 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
952 self.image_creators[-1].image_settings)
953 self.inst_creator.create(block=True)
955 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
957 def test_set_custom_invalid_mac(self):
959 Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being
960 assigned. This should raise an Exception
962 port_settings = PortSettings(
963 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo')
965 instance_settings = VmInstanceSettings(
966 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
968 self.inst_creator = OpenStackVmInstance(
969 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
971 with self.assertRaises(Exception):
972 self.inst_creator.create()
974 def test_set_custom_mac_and_ip(self):
976 Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned.
979 mac_addr = '0a:1b:2c:3d:4e:5f'
980 port_settings = PortSettings(
981 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr,
982 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
984 instance_settings = VmInstanceSettings(
985 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
987 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
988 self.image_creators[-1].image_settings)
989 self.inst_creator.create(block=True)
991 self.assertEquals(ip, self.inst_creator.get_port_ip(
992 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
993 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
995 def test_set_allowed_address_pairs(self):
997 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set.
1000 mac_addr = '0a:1b:2c:3d:4e:5f'
1001 pair = {'ip_address': ip, 'mac_address': mac_addr}
1002 port_settings = PortSettings(
1003 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1005 instance_settings = VmInstanceSettings(
1006 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1008 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1009 self.image_creators[-1].image_settings)
1010 self.inst_creator.create(block=True)
1012 port = self.inst_creator.get_port_by_name(port_settings.name)
1013 self.assertIsNotNone(port)
1014 self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
1015 self.assertEquals(1, len(port['port']['allowed_address_pairs']))
1016 validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0])
1018 def test_set_allowed_address_pairs_bad_mac(self):
1020 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1021 invalid MAC address.
1025 pair = {'ip_address': ip, 'mac_address': mac_addr}
1027 pairs.add((ip, mac_addr))
1028 port_settings = PortSettings(
1029 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1031 instance_settings = VmInstanceSettings(
1032 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1034 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1035 self.image_creators[-1].image_settings)
1036 with self.assertRaises(Exception):
1037 self.inst_creator.create()
1039 def test_set_allowed_address_pairs_bad_ip(self):
1041 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1042 invalid MAC address.
1045 mac_addr = '0a:1b:2c:3d:4e:5f'
1046 pair = {'ip_address': ip, 'mac_address': mac_addr}
1048 pairs.add((ip, mac_addr))
1049 port_settings = PortSettings(
1050 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1052 instance_settings = VmInstanceSettings(
1053 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1055 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1056 self.image_creators[-1].image_settings)
1057 with self.assertRaises(Exception):
1058 self.inst_creator.create()
1061 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1063 Test for the CreateInstance where one VM is deployed to each compute node
1068 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1071 super(self.__class__, self).__start__()
1073 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1074 self.vm_inst_name = guid + '-inst'
1075 self.port_base_name = guid + 'port'
1077 # Initialize for tearDown()
1078 self.image_creators = list()
1079 self.flavor_creator = None
1080 self.network_creator = None
1081 self.inst_creators = list()
1083 self.priv_net_config = openstack_tests.get_priv_net_config(
1084 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
1086 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
1090 self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
1091 self.network_creator.create()
1094 self.flavor_creator = OpenStackFlavor(
1095 self.admin_os_creds,
1096 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
1097 self.flavor_creator.create()
1100 # Set any custom parameters sent from the app
1101 if self.image_metadata:
1102 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1103 self.os_image_settings.url = self.image_metadata['disk_url']
1104 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1105 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1107 # If this is a 3-part image create the kernel and ramdisk images first
1108 if self.image_metadata:
1109 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1110 kernel_image_settings = openstack_tests.cirros_url_image(
1111 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1112 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1113 kernel_image = self.image_creators[-1].create()
1114 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1116 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1117 ramdisk_image_settings = openstack_tests.cirros_url_image(
1118 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1119 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1120 ramdisk_image = self.image_creators[-1].create()
1121 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1123 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1124 self.image_creators[-1].create()
1126 except Exception as e:
1132 Cleans the created object
1134 for inst_creator in self.inst_creators:
1136 inst_creator.clean()
1137 except Exception as e:
1138 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1140 if self.flavor_creator:
1142 self.flavor_creator.clean()
1143 except Exception as e:
1144 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1146 if self.network_creator:
1148 self.network_creator.clean()
1149 except Exception as e:
1150 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1152 if self.image_creators:
1154 while self.image_creators:
1155 self.image_creators[-1].clean()
1156 self.image_creators.pop()
1157 except Exception as e:
1158 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1160 super(self.__class__, self).__clean__()
1162 def test_deploy_vm_to_each_compute_node(self):
1164 Tests the creation of OpenStack VM instances to each compute node.
1166 from snaps.openstack.utils import nova_utils
1167 nova = nova_utils.nova_client(self.admin_os_creds)
1168 zones = nova_utils.get_nova_availability_zones(nova)
1170 # Create Instance on each server/zone
1173 inst_name = self.vm_inst_name + '-' + zone
1175 port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr),
1176 network_name=self.priv_net_config.network_settings.name)
1178 instance_settings = VmInstanceSettings(
1179 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
1180 port_settings=[port_settings])
1181 inst_creator = OpenStackVmInstance(
1182 self.admin_os_creds, instance_settings, self.image_creators[-1].image_settings)
1183 self.inst_creators.append(inst_creator)
1184 inst_creator.create()
1186 # Validate instances to ensure they've been deployed to the correct server
1189 creator = self.inst_creators[index]
1190 self.assertTrue(creator.vm_active(block=True))
1191 vm = creator.get_vm_inst()
1192 deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
1193 deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
1194 self.assertEquals(zone, deployed_zone + ':' + deployed_host)
1198 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1200 Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o
1201 These tests require a Centos image
1206 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1209 super(self.__class__, self).__start__()
1211 # Initialize for tearDown()
1212 self.image_creators = list()
1213 self.network_creators = list()
1214 self.router_creators = list()
1215 self.flavor_creator = None
1216 self.keypair_creator = None
1217 self.inst_creator = None
1219 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1220 self.keypair_priv_filepath = 'tmp/' + self.guid
1221 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1222 self.keypair_name = self.guid + '-kp'
1223 self.vm_inst_name = self.guid + '-inst'
1224 self.port_1_name = self.guid + '-port-1'
1225 self.port_2_name = self.guid + '-port-2'
1226 self.floating_ip_name = self.guid + 'fip1'
1227 self.priv_net_config = openstack_tests.get_priv_net_config(
1228 net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet',
1229 router_name=self.guid + '-priv-router', external_net=self.ext_net_name)
1230 self.pub_net_config = openstack_tests.get_pub_net_config(
1231 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1232 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1233 image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1234 self.os_image_settings = openstack_tests.centos_url_image(name=image_name)
1238 # Set any custom parameters sent from the app
1239 if self.image_metadata:
1240 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1241 self.os_image_settings.url = self.image_metadata['disk_url']
1242 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1243 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1245 # If this is a 3-part image create the kernel and ramdisk images first
1246 if self.image_metadata:
1247 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1248 kernel_image_settings = openstack_tests.cirros_url_image(
1249 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1250 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1251 kernel_image = self.image_creators[-1].create()
1252 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1254 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1255 ramdisk_image_settings = openstack_tests.cirros_url_image(
1256 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1257 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1258 ramdisk_image = self.image_creators[-1].create()
1259 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1261 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1262 self.image_creators[-1].create()
1264 # First network is public
1265 self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
1266 # Second network is private
1267 self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings))
1268 for network_creator in self.network_creators:
1269 network_creator.create()
1271 self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings))
1272 self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings))
1275 for router_creator in self.router_creators:
1276 router_creator.create()
1279 self.flavor_creator = OpenStackFlavor(
1280 self.admin_os_creds,
1281 FlavorSettings(name=self.guid + '-flavor-name', ram=512, disk=10, vcpus=2,
1282 metadata=self.flavor_metadata))
1283 self.flavor_creator.create()
1286 self.keypair_creator = OpenStackKeypair(
1287 self.os_creds, KeypairSettings(
1288 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
1289 private_filepath=self.keypair_priv_filepath))
1290 self.keypair_creator.create()
1291 except Exception as e:
1293 raise Exception(e.message)
1297 Cleans the created objects
1299 if self.inst_creator:
1301 self.inst_creator.clean()
1302 except Exception as e:
1303 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1305 if self.keypair_creator:
1307 self.keypair_creator.clean()
1308 except Exception as e:
1309 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
1311 if os.path.isfile(self.keypair_pub_filepath):
1312 os.remove(self.keypair_pub_filepath)
1314 if os.path.isfile(self.keypair_priv_filepath):
1315 os.remove(self.keypair_priv_filepath)
1317 if self.flavor_creator:
1319 self.flavor_creator.clean()
1320 except Exception as e:
1321 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1323 for router_creator in self.router_creators:
1325 router_creator.clean()
1326 except Exception as e:
1327 logger.error('Unexpected exception cleaning router with message - ' + e.message)
1329 for network_creator in self.network_creators:
1331 network_creator.clean()
1332 except Exception as e:
1333 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1335 if self.image_creators:
1337 while self.image_creators:
1338 self.image_creators[-1].clean()
1339 self.image_creators.pop()
1340 except Exception as e:
1341 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1343 super(self.__class__, self).__clean__()
1345 def test_dual_ports_dhcp(self):
1347 Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP.
1348 NOTE: This test and any others that call ansible will most likely fail unless you do one of
1350 1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False
1351 2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False
1352 Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail.
1354 # Create ports/NICs for instance
1357 for network_creator in self.network_creators:
1358 ports_settings.append(PortSettings(
1359 name=self.guid + '-port-' + str(ctr),
1360 network_name=network_creator.network_settings.name))
1364 instance_settings = VmInstanceSettings(
1365 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings,
1366 floating_ip_settings=[FloatingIpSettings(
1367 name=self.floating_ip_name, port_name=self.port_1_name,
1368 router_name=self.pub_net_config.router_settings.name)])
1370 self.inst_creator = OpenStackVmInstance(
1371 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
1372 keypair_settings=self.keypair_creator.keypair_settings)
1374 vm_inst = self.inst_creator.create(block=True)
1376 self.assertEquals(vm_inst, self.inst_creator.get_vm_inst())
1378 # Effectively blocks until VM has been properly activated
1379 self.assertTrue(self.inst_creator.vm_active(block=True))
1381 # Effectively blocks until VM's ssh port has been opened
1382 self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1384 self.inst_creator.config_nics()
1386 # TODO - *** ADD VALIDATION HERE ***
1387 # TODO - Add validation that both floating IPs work
1388 # TODO - Add tests where only one NIC has a floating IP
1389 # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway
1392 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1394 Tests that include, add, and remove security groups from VM instances
1398 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1401 super(self.__class__, self).__start__()
1403 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1404 self.vm_inst_name = self.guid + '-inst'
1405 self.nova = nova_utils.nova_client(self.os_creds)
1406 self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
1408 self.vm_inst_name = self.guid + '-inst'
1409 self.port_1_name = self.guid + 'port-1'
1410 self.port_2_name = self.guid + 'port-2'
1411 self.floating_ip_name = self.guid + 'fip1'
1413 net_config = openstack_tests.get_priv_net_config(
1414 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1415 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1417 # Initialize for tearDown()
1418 self.image_creators = list()
1419 self.flavor_creator = None
1420 self.network_creator = None
1421 self.router_creator = None
1422 self.inst_creator = None
1423 self.sec_grp_creators = list()
1427 # Set any custom parameters sent from the app
1428 if self.image_metadata:
1429 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1430 self.os_image_settings.url = self.image_metadata['disk_url']
1431 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1432 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1434 # If this is a 3-part image create the kernel and ramdisk images first
1435 if self.image_metadata:
1436 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1437 kernel_image_settings = openstack_tests.cirros_url_image(
1438 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1439 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1440 kernel_image = self.image_creators[-1].create()
1441 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1443 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1444 ramdisk_image_settings = openstack_tests.cirros_url_image(
1445 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1446 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1447 ramdisk_image = self.image_creators[-1].create()
1448 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1450 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1451 self.image_creators[-1].create()
1454 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1455 self.network_creator.create()
1458 self.flavor_creator = OpenStackFlavor(
1459 self.admin_os_creds,
1460 FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=2,
1461 metadata=self.flavor_metadata))
1462 self.flavor_creator.create()
1464 self.port_settings = PortSettings(name=self.guid + '-port',
1465 network_name=net_config.network_settings.name)
1466 except Exception as e:
1472 Cleans the created object
1474 if self.inst_creator:
1476 self.inst_creator.clean()
1477 except Exception as e:
1478 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1480 for sec_grp_creator in self.sec_grp_creators:
1482 sec_grp_creator.clean()
1483 except Exception as e:
1484 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
1486 if self.flavor_creator:
1488 self.flavor_creator.clean()
1489 except Exception as e:
1490 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1492 if self.network_creator:
1494 self.network_creator.clean()
1495 except Exception as e:
1496 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1498 if self.image_creators:
1500 while self.image_creators:
1501 self.image_creators[-1].clean()
1502 self.image_creators.pop()
1503 except Exception as e:
1504 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1506 super(self.__class__, self).__clean__()
1508 def test_add_security_group(self):
1510 Tests the addition of a security group created after the instance.
1513 instance_settings = VmInstanceSettings(
1514 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1515 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1516 self.image_creators[-1].image_settings)
1517 vm_inst = self.inst_creator.create(block=True)
1518 self.assertIsNotNone(vm_inst)
1520 # Create security group object to add to instance
1521 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1522 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1523 sec_grp = sec_grp_creator.create()
1524 self.sec_grp_creators.append(sec_grp_creator)
1526 # Check that group has not been added
1527 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1529 # Add security group to instance after activated
1530 self.inst_creator.add_security_group(sec_grp)
1532 # Validate that security group has been added
1533 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1535 def test_add_invalid_security_group(self):
1537 Tests the addition of a security group that no longer exists.
1540 instance_settings = VmInstanceSettings(
1541 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1542 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1543 self.image_creators[-1].image_settings)
1544 vm_inst = self.inst_creator.create(block=True)
1545 self.assertIsNotNone(vm_inst)
1547 # Create security group object to add to instance
1548 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1549 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1550 sec_grp = sec_grp_creator.create()
1551 sec_grp_creator.clean()
1552 self.sec_grp_creators.append(sec_grp_creator)
1554 # Check that group has not been added
1555 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1557 # Add security group to instance after activated
1558 self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1560 # Validate that security group has been added
1561 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1563 def test_remove_security_group(self):
1565 Tests the removal of a security group created before and added to the instance.
1567 # Create security group object to add to instance
1568 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1569 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1570 sec_grp = sec_grp_creator.create()
1571 self.sec_grp_creators.append(sec_grp_creator)
1574 instance_settings = VmInstanceSettings(
1575 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1576 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1577 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1578 self.image_creators[-1].image_settings)
1579 vm_inst = self.inst_creator.create(block=True)
1580 self.assertIsNotNone(vm_inst)
1582 # Check that group has been added
1583 self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
1585 # Add security group to instance after activated
1586 self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1588 # Validate that security group has been added
1589 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1591 def test_remove_security_group_never_added(self):
1593 Tests the removal of a security group that was never added in the first place.
1595 # Create security group object to add to instance
1596 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1597 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1598 sec_grp = sec_grp_creator.create()
1599 self.sec_grp_creators.append(sec_grp_creator)
1602 instance_settings = VmInstanceSettings(
1603 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1604 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1605 self.image_creators[-1].image_settings)
1606 vm_inst = self.inst_creator.create(block=True)
1607 self.assertIsNotNone(vm_inst)
1609 # Check that group has been added
1610 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1612 # Add security group to instance after activated
1613 self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1615 # Validate that security group has been added
1616 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1618 def test_add_same_security_group(self):
1620 Tests the addition of a security group created before add added to the instance.
1622 # Create security group object to add to instance
1623 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1624 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1625 sec_grp = sec_grp_creator.create()
1626 self.sec_grp_creators.append(sec_grp_creator)
1629 instance_settings = VmInstanceSettings(
1630 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1631 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1632 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1633 self.image_creators[-1].image_settings)
1634 vm_inst = self.inst_creator.create(block=True)
1635 self.assertIsNotNone(vm_inst)
1637 # Check that group has been added
1638 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1640 # Add security group to instance after activated
1641 self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1643 # Validate that security group has been added
1644 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1647 def inst_has_sec_grp(vm_inst, sec_grp_name):
1649 Returns true if instance has a security group of a given name
1652 if not hasattr(vm_inst, 'security_groups'):
1656 for sec_grp_dict in vm_inst.security_groups:
1657 if sec_grp_name in sec_grp_dict['name']:
1663 def validate_ssh_client(instance_creator):
1665 Returns True if instance_creator returns an SSH client that is valid
1666 :param instance_creator: the object responsible for creating the VM instance
1669 ssh_active = instance_creator.vm_ssh_active(block=True)
1672 ssh_client = instance_creator.ssh_client()
1674 out = ssh_client.exec_command('pwd')[1]
1678 channel = out.channel
1679 in_buffer = channel.in_buffer
1680 pwd_out = in_buffer.read(1024)
1681 if not pwd_out or len(pwd_out) < 10:
1688 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1690 Test for the CreateInstance class for creating an image from a 3-part image
1695 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1698 super(self.__class__, self).__start__()
1700 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1701 self.image_name = guid
1702 self.vm_inst_name = guid + '-inst'
1703 self.nova = nova_utils.nova_client(self.os_creds)
1705 net_config = openstack_tests.get_priv_net_config(
1706 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1707 router_name=guid + '-pub-router', external_net=self.ext_net_name)
1709 # Initialize for tearDown()
1710 self.image_creators = list()
1711 self.network_creator = None
1712 self.flavor_creator = None
1713 self.inst_creator = None
1719 if self.image_metadata:
1720 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1721 properties = self.image_metadata['extra_properties']
1723 # Create the kernel image
1724 kernel_image_settings = openstack_tests.cirros_url_image(
1725 name=self.image_name+'_kernel',
1726 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
1728 if self.image_metadata:
1729 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1730 kernel_image_settings.url = self.image_metadata['kernel_url']
1732 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1733 kernel_image = self.image_creators[-1].create()
1735 # Create the ramdisk image
1736 ramdisk_image_settings = openstack_tests.cirros_url_image(
1737 name=self.image_name+'_ramdisk',
1738 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
1740 if self.image_metadata:
1741 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1742 ramdisk_image_settings.url = self.image_metadata['ramdisk_url']
1744 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1745 ramdisk_image = self.image_creators[-1].create()
1746 self.assertIsNotNone(ramdisk_image)
1748 # Create the main image
1749 os_image_settings = openstack_tests.cirros_url_image(
1750 name=self.image_name,
1751 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
1752 if self.image_metadata:
1753 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1754 os_image_settings.url = self.image_metadata['disk_url']
1756 properties['kernel_id'] = kernel_image.id
1757 properties['ramdisk_id'] = ramdisk_image.id
1758 os_image_settings.extra_properties = properties
1759 self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
1760 created_image = self.image_creators[-1].create()
1761 self.assertIsNotNone(created_image)
1764 self.flavor_creator = OpenStackFlavor(
1765 self.admin_os_creds,
1766 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
1767 self.flavor_creator.create()
1770 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1771 self.network_creator.create()
1773 self.port_settings = PortSettings(name=guid + '-port',
1774 network_name=net_config.network_settings.name)
1775 except Exception as e:
1781 Cleans the created object
1783 if self.inst_creator:
1785 self.inst_creator.clean()
1786 except Exception as e:
1787 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1789 if self.flavor_creator:
1791 self.flavor_creator.clean()
1792 except Exception as e:
1793 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1795 if self.network_creator:
1797 self.network_creator.clean()
1798 except Exception as e:
1799 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1801 if self.image_creators:
1803 while self.image_creators:
1804 self.image_creators[0].clean()
1805 self.image_creators.pop(0)
1806 except Exception as e:
1807 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1809 super(self.__class__, self).__clean__()
1811 def test_create_delete_instance_from_three_part_image(self):
1813 Tests the creation of an OpenStack instance from a 3-part image.
1815 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1816 port_settings=[self.port_settings])
1818 # The last created image is the main image from which we create the instance
1819 self.inst_creator = OpenStackVmInstance(
1820 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1822 vm_inst = self.inst_creator.create()
1823 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1825 self.assertTrue(self.inst_creator.vm_active(block=True))
1828 nova_utils.delete_vm_instance(self.nova, vm_inst)
1830 self.assertTrue(self.inst_creator.vm_deleted(block=True))
1831 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1833 # Exception should not be thrown
1834 self.inst_creator.clean()