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()
357 match_value = 'Lease of.*obtained'
359 logger.info("Looking for expression %s in the console log" % match_value)
361 while timeout > time.time() - start_time:
362 output = vm.get_console_output()
363 full_log = full_log + output
364 if re.search(match_value, output):
365 logger.info('DHCP lease obtained logged in console')
367 logger.info('With correct IP address')
370 logger.error('With incorrect IP address')
374 logger.error('Full console output -\n' + full_log)
376 logger.debug('Full console output -\n' + full_log)
378 self.assertTrue(found)
381 class CreateInstanceSimpleTests(OSIntegrationTestCase):
383 Simple instance creation tests without any other objects
387 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
390 super(self.__class__, self).__start__()
392 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
393 self.vm_inst_name = guid + '-inst'
394 self.nova = nova_utils.nova_client(self.os_creds)
395 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
397 net_config = openstack_tests.get_priv_net_config(
398 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
399 router_name=guid + '-pub-router', external_net=self.ext_net_name)
401 # Initialize for tearDown()
402 self.image_creators = list()
403 self.flavor_creator = None
405 self.network_creator = None
406 self.inst_creator = None
410 # Set any custom parameters sent from the app
411 if self.image_metadata:
412 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
413 self.os_image_settings.url = self.image_metadata['disk_url']
414 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
415 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
417 # If this is a 3-part image create the kernel and ramdisk images first
418 if self.image_metadata:
419 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
420 kernel_image_settings = openstack_tests.cirros_url_image(
421 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
422 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
423 kernel_image = self.image_creators[-1].create()
424 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
426 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
427 ramdisk_image_settings = openstack_tests.cirros_url_image(
428 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
429 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
430 ramdisk_image = self.image_creators[-1].create()
431 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
433 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
434 self.image_creators[-1].create()
437 self.flavor_creator = OpenStackFlavor(
439 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
440 self.flavor_creator.create()
443 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
444 self.network_creator.create()
446 self.port_settings = PortSettings(name=guid + '-port',
447 network_name=net_config.network_settings.name)
449 except Exception as e:
455 Cleans the created object
457 if self.inst_creator:
459 self.inst_creator.clean()
460 except Exception as e:
461 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
463 if self.flavor_creator:
465 self.flavor_creator.clean()
466 except Exception as e:
467 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
469 if self.network_creator:
471 self.network_creator.clean()
472 except Exception as e:
473 logger.error('Unexpected exception cleaning network with message - ' + e.message)
475 if self.image_creators:
477 while self.image_creators:
478 self.image_creators[-1].clean()
479 self.image_creators.pop()
480 except Exception as e:
481 logger.error('Unexpected exception cleaning image with message - ' + e.message)
483 super(self.__class__, self).__clean__()
485 def test_create_delete_instance(self):
487 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
489 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
490 port_settings=[self.port_settings])
492 self.inst_creator = OpenStackVmInstance(
493 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
495 vm_inst = self.inst_creator.create()
496 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
499 nova_utils.delete_vm_instance(self.nova, vm_inst)
501 self.assertTrue(self.inst_creator.vm_deleted(block=True))
502 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
504 # Exception should not be thrown
505 self.inst_creator.clean()
508 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
510 Test for the CreateInstance class with a single NIC/Port with Floating IPs
515 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
518 super(self.__class__, self).__start__()
520 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
521 self.keypair_priv_filepath = 'tmp/' + guid
522 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
523 self.keypair_name = guid + '-kp'
524 self.vm_inst_name = guid + '-inst'
525 self.port_1_name = guid + 'port-1'
526 self.port_2_name = guid + 'port-2'
527 self.floating_ip_name = guid + 'fip1'
529 # Initialize for tearDown()
530 self.image_creators = list()
531 self.network_creator = None
532 self.router_creator = None
533 self.flavor_creator = None
534 self.keypair_creator = None
535 self.inst_creators = list()
537 self.pub_net_config = openstack_tests.get_pub_net_config(
538 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
539 router_name=guid + '-pub-router', external_net=self.ext_net_name)
540 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
544 # Set any custom parameters sent from the app
545 if self.image_metadata:
546 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
547 self.os_image_settings.url = self.image_metadata['disk_url']
548 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
549 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
551 # If this is a 3-part image create the kernel and ramdisk images first
552 if self.image_metadata:
553 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
554 kernel_image_settings = openstack_tests.cirros_url_image(
555 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
556 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
557 kernel_image = self.image_creators[-1].create()
558 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
560 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
561 ramdisk_image_settings = openstack_tests.cirros_url_image(
562 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
563 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
564 ramdisk_image = self.image_creators[-1].create()
565 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
567 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
568 self.image_creators[-1].create()
571 self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
572 self.network_creator.create()
575 self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
576 self.router_creator.create()
579 self.flavor_creator = OpenStackFlavor(
581 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
582 self.flavor_creator.create()
584 self.keypair_creator = OpenStackKeypair(
585 self.os_creds, KeypairSettings(
586 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
587 private_filepath=self.keypair_priv_filepath))
588 self.keypair_creator.create()
589 except Exception as e:
595 Cleans the created object
597 for inst_creator in self.inst_creators:
600 except Exception as e:
601 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
603 if self.keypair_creator:
605 self.keypair_creator.clean()
606 except Exception as e:
607 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
609 if os.path.isfile(self.keypair_pub_filepath):
610 os.remove(self.keypair_pub_filepath)
612 if os.path.isfile(self.keypair_priv_filepath):
613 os.remove(self.keypair_priv_filepath)
615 if self.flavor_creator:
617 self.flavor_creator.clean()
618 except Exception as e:
619 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
621 if self.router_creator:
623 self.router_creator.clean()
624 except Exception as e:
625 logger.error('Unexpected exception cleaning router with message - ' + e.message)
627 if self.network_creator:
629 self.network_creator.clean()
630 except Exception as e:
631 logger.error('Unexpected exception cleaning network with message - ' + e.message)
633 if self.image_creators:
635 while self.image_creators:
636 self.image_creators[-1].clean()
637 self.image_creators.pop()
638 except Exception as e:
639 logger.error('Unexpected exception cleaning image with message - ' + e.message)
641 super(self.__class__, self).__clean__()
643 def test_single_port_static(self):
645 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
649 port_settings = PortSettings(
650 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name,
651 ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}])
653 instance_settings = VmInstanceSettings(
654 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
655 floating_ip_settings=[FloatingIpSettings(
656 name=self.floating_ip_name, port_name=self.port_1_name,
657 router_name=self.pub_net_config.router_settings.name)])
659 inst_creator = OpenStackVmInstance(
660 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
661 keypair_settings=self.keypair_creator.keypair_settings)
662 self.inst_creators.append(inst_creator)
663 vm_inst = inst_creator.create()
665 self.assertEquals(ip_1, inst_creator.get_port_ip(self.port_1_name))
666 self.assertTrue(inst_creator.vm_active(block=True))
667 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
669 def test_ssh_client_fip_before_active(self):
671 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
673 port_settings = PortSettings(
674 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
676 instance_settings = VmInstanceSettings(
677 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
678 floating_ip_settings=[FloatingIpSettings(
679 name=self.floating_ip_name, port_name=self.port_1_name,
680 router_name=self.pub_net_config.router_settings.name)])
682 inst_creator = OpenStackVmInstance(
683 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
684 keypair_settings=self.keypair_creator.keypair_settings)
685 self.inst_creators.append(inst_creator)
686 vm_inst = inst_creator.create()
687 self.assertIsNotNone(vm_inst)
689 self.assertTrue(inst_creator.vm_active(block=True))
690 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
692 self.assertTrue(validate_ssh_client(inst_creator))
694 def test_ssh_client_fip_after_active(self):
696 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
698 port_settings = PortSettings(
699 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
701 instance_settings = VmInstanceSettings(
702 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
703 floating_ip_settings=[FloatingIpSettings(
704 name=self.floating_ip_name, port_name=self.port_1_name,
705 router_name=self.pub_net_config.router_settings.name)])
707 inst_creator = OpenStackVmInstance(
708 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
709 keypair_settings=self.keypair_creator.keypair_settings)
710 self.inst_creators.append(inst_creator)
712 # block=True will force the create() method to block until the
713 vm_inst = inst_creator.create(block=True)
714 self.assertIsNotNone(vm_inst)
716 self.assertTrue(inst_creator.vm_active(block=True))
717 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
719 self.assertTrue(validate_ssh_client(inst_creator))
721 # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
722 # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
723 # def test_allowed_address_port_access(self):
725 # Tests to ensure that setting allowed_address_pairs on a port functions as designed
727 # port_settings_1 = PortSettings(
728 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
730 # instance_settings_1 = VmInstanceSettings(
731 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
732 # floating_ip_settings=[FloatingIpSettings(
733 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
734 # router_name=self.pub_net_config.router_settings.name)])
736 # inst_creator_1 = OpenStackVmInstance(
737 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
738 # keypair_settings=self.keypair_creator.keypair_settings)
739 # self.inst_creators.append(inst_creator_1)
741 # # block=True will force the create() method to block until the
742 # vm_inst_1 = inst_creator_1.create(block=True)
743 # self.assertIsNotNone(vm_inst_1)
745 # port_settings_1 = PortSettings(
746 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
748 # instance_settings_1 = VmInstanceSettings(
749 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
750 # floating_ip_settings=[FloatingIpSettings(
751 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
752 # router_name=self.pub_net_config.router_settings.name)])
754 # inst_creator_1 = OpenStackVmInstance(
755 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
756 # keypair_settings=self.keypair_creator.keypair_settings)
757 # self.inst_creators.append(inst_creator_1)
758 # inst_creator_1.create(block=True)
760 # ip = inst_creator_1.get_port_ip(port_settings_1.name,
761 # subnet_name=self.pub_net_config.network_settings.subnet_settings[0].name)
762 # self.assertIsNotNone(ip)
763 # mac_addr = inst_creator_1.get_port_mac(port_settings_1.name)
764 # self.assertIsNotNone(mac_addr)
766 # allowed_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
768 # # Create VM that can be accessed by vm_inst_1
769 # port_settings_2 = PortSettings(
770 # name=self.port_1_name + '-2', network_name=self.pub_net_config.network_settings.name,
771 # allowed_address_pairs=allowed_address_pairs)
773 # instance_settings_2 = VmInstanceSettings(
774 # name=self.vm_inst_name + '-2', flavor=self.flavor_creator.flavor_settings.name,
775 # port_settings=[port_settings_2])
777 # inst_creator_2 = OpenStackVmInstance(
778 # self.os_creds, instance_settings_2, self.image_creators[-1].image_settings)
779 # self.inst_creators.append(inst_creator_2)
780 # inst_creator_2.create(block=True)
782 # # Create VM that cannot be accessed by vm_inst_1
784 # mac_addr = '0a:1b:2c:3d:4e:5f'
785 # invalid_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
787 # port_settings_3 = PortSettings(
788 # name=self.port_1_name + '-3', network_name=self.pub_net_config.network_settings.name,
789 # allowed_address_pairs=invalid_address_pairs)
791 # instance_settings_3 = VmInstanceSettings(
792 # name=self.vm_inst_name + '-3', flavor=self.flavor_creator.flavor_settings.name,
793 # port_settings=[port_settings_3])
795 # inst_creator_3 = OpenStackVmInstance(
796 # self.os_creds, instance_settings_3, self.image_creators[-1].image_settings)
797 # self.inst_creators.append(inst_creator_3)
798 # inst_creator_3.create(block=True)
801 # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would
802 # expect inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
803 # TODO - Add validation
806 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
808 Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set
813 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
816 super(self.__class__, self).__start__()
818 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
819 self.vm_inst_name = guid + '-inst'
820 self.port_1_name = guid + 'port-1'
821 self.port_2_name = guid + 'port-2'
822 self.floating_ip_name = guid + 'fip1'
824 # Initialize for tearDown()
825 self.image_creators = list()
826 self.network_creator = None
827 self.flavor_creator = None
828 self.inst_creator = None
830 self.net_config = openstack_tests.get_priv_net_config(
831 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
832 router_name=guid + '-pub-router', external_net=self.ext_net_name)
833 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
837 # Set any custom parameters sent from the app
838 if self.image_metadata:
839 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
840 self.os_image_settings.url = self.image_metadata['disk_url']
841 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
842 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
844 # If this is a 3-part image create the kernel and ramdisk images first
845 if self.image_metadata:
846 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
847 kernel_image_settings = openstack_tests.cirros_url_image(
848 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
849 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
850 kernel_image = self.image_creators[-1].create()
851 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
853 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
854 ramdisk_image_settings = openstack_tests.cirros_url_image(
855 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
856 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
857 ramdisk_image = self.image_creators[-1].create()
858 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
860 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
861 self.image_creators[-1].create()
864 self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
865 self.network_creator.create()
868 self.flavor_creator = OpenStackFlavor(
870 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
871 self.flavor_creator.create()
872 except Exception as e:
878 Cleans the created object
880 if self.inst_creator:
882 self.inst_creator.clean()
883 except Exception as e:
884 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
886 if self.flavor_creator:
888 self.flavor_creator.clean()
889 except Exception as e:
890 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
892 if self.network_creator:
894 self.network_creator.clean()
895 except Exception as e:
896 logger.error('Unexpected exception cleaning network with message - ' + e.message)
898 if self.image_creators:
900 while self.image_creators:
901 self.image_creators[-1].clean()
902 self.image_creators.pop()
903 except Exception as e:
904 logger.error('Unexpected exception cleaning image with message - ' + e.message)
906 super(self.__class__, self).__clean__()
908 def test_set_custom_valid_ip_one_subnet(self):
910 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
913 port_settings = PortSettings(
914 name=self.port_1_name, network_name=self.net_config.network_settings.name,
915 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
917 instance_settings = VmInstanceSettings(
918 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
920 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
921 self.image_creators[-1].image_settings)
922 self.inst_creator.create()
924 self.assertEquals(ip, self.inst_creator.get_port_ip(
925 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
927 def test_set_custom_invalid_ip_one_subnet(self):
929 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
932 port_settings = PortSettings(
933 name=self.port_1_name, network_name=self.net_config.network_settings.name,
934 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
936 instance_settings = VmInstanceSettings(
937 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
939 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
940 self.image_creators[-1].image_settings)
942 with self.assertRaises(Exception):
943 self.inst_creator.create()
945 def test_set_custom_valid_mac(self):
947 Tests the creation of an OpenStack instance with a single port where the MAC address is assigned.
949 mac_addr = '0a:1b:2c:3d:4e:5f'
950 port_settings = PortSettings(
951 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr)
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(self.os_creds, instance_settings,
957 self.image_creators[-1].image_settings)
958 self.inst_creator.create()
960 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
962 def test_set_custom_invalid_mac(self):
964 Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being
965 assigned. This should raise an Exception
967 port_settings = PortSettings(
968 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo')
970 instance_settings = VmInstanceSettings(
971 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
973 self.inst_creator = OpenStackVmInstance(
974 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
976 with self.assertRaises(Exception):
977 self.inst_creator.create()
979 def test_set_custom_mac_and_ip(self):
981 Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned.
984 mac_addr = '0a:1b:2c:3d:4e:5f'
985 port_settings = PortSettings(
986 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr,
987 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
989 instance_settings = VmInstanceSettings(
990 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
992 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
993 self.image_creators[-1].image_settings)
994 self.inst_creator.create()
996 self.assertEquals(ip, self.inst_creator.get_port_ip(
997 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
998 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
1000 def test_set_allowed_address_pairs(self):
1002 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set.
1005 mac_addr = '0a:1b:2c:3d:4e:5f'
1006 pair = {'ip_address': ip, 'mac_address': mac_addr}
1007 port_settings = PortSettings(
1008 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1010 instance_settings = VmInstanceSettings(
1011 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1013 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1014 self.image_creators[-1].image_settings)
1015 self.inst_creator.create()
1017 port = self.inst_creator.get_port_by_name(port_settings.name)
1018 self.assertIsNotNone(port)
1019 self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
1020 self.assertEquals(1, len(port['port']['allowed_address_pairs']))
1021 validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0])
1023 def test_set_allowed_address_pairs_bad_mac(self):
1025 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1026 invalid MAC address.
1030 pair = {'ip_address': ip, 'mac_address': mac_addr}
1032 pairs.add((ip, mac_addr))
1033 port_settings = PortSettings(
1034 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1036 instance_settings = VmInstanceSettings(
1037 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1039 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1040 self.image_creators[-1].image_settings)
1041 with self.assertRaises(Exception):
1042 self.inst_creator.create()
1044 def test_set_allowed_address_pairs_bad_ip(self):
1046 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1047 invalid MAC address.
1050 mac_addr = '0a:1b:2c:3d:4e:5f'
1051 pair = {'ip_address': ip, 'mac_address': mac_addr}
1053 pairs.add((ip, mac_addr))
1054 port_settings = PortSettings(
1055 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1057 instance_settings = VmInstanceSettings(
1058 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1060 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1061 self.image_creators[-1].image_settings)
1062 with self.assertRaises(Exception):
1063 self.inst_creator.create()
1066 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1068 Test for the CreateInstance where one VM is deployed to each compute node
1073 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1076 super(self.__class__, self).__start__()
1078 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1079 self.vm_inst_name = guid + '-inst'
1080 self.port_base_name = guid + 'port'
1082 # Initialize for tearDown()
1083 self.image_creators = list()
1084 self.flavor_creator = None
1085 self.network_creator = None
1086 self.inst_creators = list()
1088 self.priv_net_config = openstack_tests.get_priv_net_config(
1089 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
1091 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
1095 self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
1096 self.network_creator.create()
1099 self.flavor_creator = OpenStackFlavor(
1100 self.admin_os_creds,
1101 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
1102 self.flavor_creator.create()
1105 # Set any custom parameters sent from the app
1106 if self.image_metadata:
1107 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1108 self.os_image_settings.url = self.image_metadata['disk_url']
1109 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1110 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1112 # If this is a 3-part image create the kernel and ramdisk images first
1113 if self.image_metadata:
1114 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1115 kernel_image_settings = openstack_tests.cirros_url_image(
1116 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1117 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1118 kernel_image = self.image_creators[-1].create()
1119 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1121 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1122 ramdisk_image_settings = openstack_tests.cirros_url_image(
1123 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1124 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1125 ramdisk_image = self.image_creators[-1].create()
1126 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1128 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1129 self.image_creators[-1].create()
1131 except Exception as e:
1137 Cleans the created object
1139 for inst_creator in self.inst_creators:
1141 inst_creator.clean()
1142 except Exception as e:
1143 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1145 if self.flavor_creator:
1147 self.flavor_creator.clean()
1148 except Exception as e:
1149 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1151 if self.network_creator:
1153 self.network_creator.clean()
1154 except Exception as e:
1155 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1157 if self.image_creators:
1159 while self.image_creators:
1160 self.image_creators[-1].clean()
1161 self.image_creators.pop()
1162 except Exception as e:
1163 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1165 super(self.__class__, self).__clean__()
1167 def test_deploy_vm_to_each_compute_node(self):
1169 Tests the creation of OpenStack VM instances to each compute node.
1171 from snaps.openstack.utils import nova_utils
1172 nova = nova_utils.nova_client(self.admin_os_creds)
1173 zones = nova_utils.get_nova_availability_zones(nova)
1175 # Create Instance on each server/zone
1178 inst_name = self.vm_inst_name + '-' + zone
1180 port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr),
1181 network_name=self.priv_net_config.network_settings.name)
1183 instance_settings = VmInstanceSettings(
1184 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
1185 port_settings=[port_settings])
1186 inst_creator = OpenStackVmInstance(
1187 self.admin_os_creds, instance_settings, self.image_creators[-1].image_settings)
1188 self.inst_creators.append(inst_creator)
1189 inst_creator.create()
1191 # Validate instances to ensure they've been deployed to the correct server
1194 creator = self.inst_creators[index]
1195 self.assertTrue(creator.vm_active(block=True))
1196 vm = creator.get_vm_inst()
1197 deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
1198 deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
1199 self.assertEquals(zone, deployed_zone + ':' + deployed_host)
1203 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1205 Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o
1206 These tests require a Centos image
1211 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1214 super(self.__class__, self).__start__()
1216 # Initialize for tearDown()
1217 self.image_creators = list()
1218 self.network_creators = list()
1219 self.router_creators = list()
1220 self.flavor_creator = None
1221 self.keypair_creator = None
1222 self.inst_creator = None
1224 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1225 self.keypair_priv_filepath = 'tmp/' + self.guid
1226 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1227 self.keypair_name = self.guid + '-kp'
1228 self.vm_inst_name = self.guid + '-inst'
1229 self.port_1_name = self.guid + '-port-1'
1230 self.port_2_name = self.guid + '-port-2'
1231 self.floating_ip_name = self.guid + 'fip1'
1232 self.priv_net_config = openstack_tests.get_priv_net_config(
1233 net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet',
1234 router_name=self.guid + '-priv-router', external_net=self.ext_net_name)
1235 self.pub_net_config = openstack_tests.get_pub_net_config(
1236 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1237 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1238 image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1239 self.os_image_settings = openstack_tests.centos_url_image(name=image_name)
1243 # Set any custom parameters sent from the app
1244 if self.image_metadata:
1245 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1246 self.os_image_settings.url = self.image_metadata['disk_url']
1247 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1248 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1250 # If this is a 3-part image create the kernel and ramdisk images first
1251 if self.image_metadata:
1252 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1253 kernel_image_settings = openstack_tests.cirros_url_image(
1254 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1255 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1256 kernel_image = self.image_creators[-1].create()
1257 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1259 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1260 ramdisk_image_settings = openstack_tests.cirros_url_image(
1261 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1262 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1263 ramdisk_image = self.image_creators[-1].create()
1264 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1266 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1267 self.image_creators[-1].create()
1269 # First network is public
1270 self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
1271 # Second network is private
1272 self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings))
1273 for network_creator in self.network_creators:
1274 network_creator.create()
1276 self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings))
1277 self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings))
1280 for router_creator in self.router_creators:
1281 router_creator.create()
1284 self.flavor_creator = OpenStackFlavor(
1285 self.admin_os_creds,
1286 FlavorSettings(name=self.guid + '-flavor-name', ram=512, disk=10, vcpus=2,
1287 metadata=self.flavor_metadata))
1288 self.flavor_creator.create()
1291 self.keypair_creator = OpenStackKeypair(
1292 self.os_creds, KeypairSettings(
1293 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
1294 private_filepath=self.keypair_priv_filepath))
1295 self.keypair_creator.create()
1296 except Exception as e:
1298 raise Exception(e.message)
1302 Cleans the created objects
1304 if self.inst_creator:
1306 self.inst_creator.clean()
1307 except Exception as e:
1308 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1310 if self.keypair_creator:
1312 self.keypair_creator.clean()
1313 except Exception as e:
1314 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
1316 if os.path.isfile(self.keypair_pub_filepath):
1317 os.remove(self.keypair_pub_filepath)
1319 if os.path.isfile(self.keypair_priv_filepath):
1320 os.remove(self.keypair_priv_filepath)
1322 if self.flavor_creator:
1324 self.flavor_creator.clean()
1325 except Exception as e:
1326 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1328 for router_creator in self.router_creators:
1330 router_creator.clean()
1331 except Exception as e:
1332 logger.error('Unexpected exception cleaning router with message - ' + e.message)
1334 for network_creator in self.network_creators:
1336 network_creator.clean()
1337 except Exception as e:
1338 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1340 if self.image_creators:
1342 while self.image_creators:
1343 self.image_creators[-1].clean()
1344 self.image_creators.pop()
1345 except Exception as e:
1346 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1348 super(self.__class__, self).__clean__()
1350 def test_dual_ports_dhcp(self):
1352 Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP.
1353 NOTE: This test and any others that call ansible will most likely fail unless you do one of
1355 1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False
1356 2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False
1357 Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail.
1359 # Create ports/NICs for instance
1362 for network_creator in self.network_creators:
1363 ports_settings.append(PortSettings(
1364 name=self.guid + '-port-' + str(ctr),
1365 network_name=network_creator.network_settings.name))
1369 instance_settings = VmInstanceSettings(
1370 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings,
1371 floating_ip_settings=[FloatingIpSettings(
1372 name=self.floating_ip_name, port_name=self.port_1_name,
1373 router_name=self.pub_net_config.router_settings.name)])
1375 self.inst_creator = OpenStackVmInstance(
1376 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
1377 keypair_settings=self.keypair_creator.keypair_settings)
1379 vm_inst = self.inst_creator.create(block=True)
1381 self.assertEquals(vm_inst, self.inst_creator.get_vm_inst())
1383 # Effectively blocks until VM has been properly activated
1384 self.assertTrue(self.inst_creator.vm_active(block=True))
1386 # Effectively blocks until VM's ssh port has been opened
1387 self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1389 self.inst_creator.config_nics()
1391 # TODO - *** ADD VALIDATION HERE ***
1392 # TODO - Add validation that both floating IPs work
1393 # TODO - Add tests where only one NIC has a floating IP
1394 # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway
1397 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1399 Tests that include, add, and remove security groups from VM instances
1403 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1406 super(self.__class__, self).__start__()
1408 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1409 self.vm_inst_name = self.guid + '-inst'
1410 self.nova = nova_utils.nova_client(self.os_creds)
1411 self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
1413 self.vm_inst_name = self.guid + '-inst'
1414 self.port_1_name = self.guid + 'port-1'
1415 self.port_2_name = self.guid + 'port-2'
1416 self.floating_ip_name = self.guid + 'fip1'
1418 net_config = openstack_tests.get_priv_net_config(
1419 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1420 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1422 # Initialize for tearDown()
1423 self.image_creators = list()
1424 self.flavor_creator = None
1425 self.network_creator = None
1426 self.router_creator = None
1427 self.inst_creator = None
1428 self.sec_grp_creators = list()
1432 # Set any custom parameters sent from the app
1433 if self.image_metadata:
1434 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1435 self.os_image_settings.url = self.image_metadata['disk_url']
1436 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1437 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1439 # If this is a 3-part image create the kernel and ramdisk images first
1440 if self.image_metadata:
1441 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1442 kernel_image_settings = openstack_tests.cirros_url_image(
1443 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1444 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1445 kernel_image = self.image_creators[-1].create()
1446 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1448 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1449 ramdisk_image_settings = openstack_tests.cirros_url_image(
1450 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1451 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1452 ramdisk_image = self.image_creators[-1].create()
1453 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1455 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1456 self.image_creators[-1].create()
1459 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1460 self.network_creator.create()
1463 self.flavor_creator = OpenStackFlavor(
1464 self.admin_os_creds,
1465 FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=2,
1466 metadata=self.flavor_metadata))
1467 self.flavor_creator.create()
1469 self.port_settings = PortSettings(name=self.guid + '-port',
1470 network_name=net_config.network_settings.name)
1471 except Exception as e:
1477 Cleans the created object
1479 if self.inst_creator:
1481 self.inst_creator.clean()
1482 except Exception as e:
1483 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1485 for sec_grp_creator in self.sec_grp_creators:
1487 sec_grp_creator.clean()
1488 except Exception as e:
1489 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
1491 if self.flavor_creator:
1493 self.flavor_creator.clean()
1494 except Exception as e:
1495 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1497 if self.network_creator:
1499 self.network_creator.clean()
1500 except Exception as e:
1501 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1503 if self.image_creators:
1505 while self.image_creators:
1506 self.image_creators[-1].clean()
1507 self.image_creators.pop()
1508 except Exception as e:
1509 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1511 super(self.__class__, self).__clean__()
1513 def test_add_security_group(self):
1515 Tests the addition of a security group created after the instance.
1518 instance_settings = VmInstanceSettings(
1519 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1520 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1521 self.image_creators[-1].image_settings)
1522 vm_inst = self.inst_creator.create(block=True)
1523 self.assertIsNotNone(vm_inst)
1525 # Create security group object to add to instance
1526 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1527 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1528 sec_grp = sec_grp_creator.create()
1529 self.sec_grp_creators.append(sec_grp_creator)
1531 # Check that group has not been added
1532 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1534 # Add security group to instance after activated
1535 self.inst_creator.add_security_group(sec_grp)
1537 # Validate that security group has been added
1538 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1540 def test_add_invalid_security_group(self):
1542 Tests the addition of a security group that no longer exists.
1545 instance_settings = VmInstanceSettings(
1546 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1547 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1548 self.image_creators[-1].image_settings)
1549 vm_inst = self.inst_creator.create(block=True)
1550 self.assertIsNotNone(vm_inst)
1552 # Create security group object to add to instance
1553 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1554 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1555 sec_grp = sec_grp_creator.create()
1556 sec_grp_creator.clean()
1557 self.sec_grp_creators.append(sec_grp_creator)
1559 # Check that group has not been added
1560 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1562 # Add security group to instance after activated
1563 self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1565 # Validate that security group has been added
1566 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1568 def test_remove_security_group(self):
1570 Tests the removal of a security group created before and added to the instance.
1572 # Create security group object to add to instance
1573 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1574 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1575 sec_grp = sec_grp_creator.create()
1576 self.sec_grp_creators.append(sec_grp_creator)
1579 instance_settings = VmInstanceSettings(
1580 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1581 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1582 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1583 self.image_creators[-1].image_settings)
1584 vm_inst = self.inst_creator.create(block=True)
1585 self.assertIsNotNone(vm_inst)
1587 # Check that group has been added
1588 self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
1590 # Add security group to instance after activated
1591 self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1593 # Validate that security group has been added
1594 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1596 def test_remove_security_group_never_added(self):
1598 Tests the removal of a security group that was never added in the first place.
1600 # Create security group object to add to instance
1601 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1602 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1603 sec_grp = sec_grp_creator.create()
1604 self.sec_grp_creators.append(sec_grp_creator)
1607 instance_settings = VmInstanceSettings(
1608 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1609 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1610 self.image_creators[-1].image_settings)
1611 vm_inst = self.inst_creator.create(block=True)
1612 self.assertIsNotNone(vm_inst)
1614 # Check that group has been added
1615 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1617 # Add security group to instance after activated
1618 self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1620 # Validate that security group has been added
1621 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1623 def test_add_same_security_group(self):
1625 Tests the addition of a security group created before add added to the instance.
1627 # Create security group object to add to instance
1628 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1629 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1630 sec_grp = sec_grp_creator.create()
1631 self.sec_grp_creators.append(sec_grp_creator)
1634 instance_settings = VmInstanceSettings(
1635 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1636 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1637 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1638 self.image_creators[-1].image_settings)
1639 vm_inst = self.inst_creator.create(block=True)
1640 self.assertIsNotNone(vm_inst)
1642 # Check that group has been added
1643 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1645 # Add security group to instance after activated
1646 self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1648 # Validate that security group has been added
1649 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1652 def inst_has_sec_grp(vm_inst, sec_grp_name):
1654 Returns true if instance has a security group of a given name
1657 if not hasattr(vm_inst, 'security_groups'):
1661 for sec_grp_dict in vm_inst.security_groups:
1662 if sec_grp_name in sec_grp_dict['name']:
1668 def validate_ssh_client(instance_creator):
1670 Returns True if instance_creator returns an SSH client that is valid
1671 :param instance_creator: the object responsible for creating the VM instance
1674 ssh_active = instance_creator.vm_ssh_active(block=True)
1677 ssh_client = instance_creator.ssh_client()
1679 out = ssh_client.exec_command('pwd')[1]
1683 channel = out.channel
1684 in_buffer = channel.in_buffer
1685 pwd_out = in_buffer.read(1024)
1686 if not pwd_out or len(pwd_out) < 10:
1693 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1695 Test for the CreateInstance class for creating an image from a 3-part image
1700 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1703 super(self.__class__, self).__start__()
1705 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1706 self.image_name = guid
1707 self.vm_inst_name = guid + '-inst'
1708 self.nova = nova_utils.nova_client(self.os_creds)
1710 net_config = openstack_tests.get_priv_net_config(
1711 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1712 router_name=guid + '-pub-router', external_net=self.ext_net_name)
1714 # Initialize for tearDown()
1715 self.image_creators = list()
1716 self.network_creator = None
1717 self.flavor_creator = None
1718 self.inst_creator = None
1724 if self.image_metadata:
1725 if 'extra_properties' in self.image_metadata and self.image_metadata['extra_properties']:
1726 properties = self.image_metadata['extra_properties']
1728 # Create the kernel image
1729 kernel_image_settings = openstack_tests.cirros_url_image(
1730 name=self.image_name+'_kernel',
1731 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
1733 if self.image_metadata:
1734 if 'kernel_url' in self.image_metadata and self.image_metadata['kernel_url']:
1735 kernel_image_settings.url = self.image_metadata['kernel_url']
1737 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1738 kernel_image = self.image_creators[-1].create()
1740 # Create the ramdisk image
1741 ramdisk_image_settings = openstack_tests.cirros_url_image(
1742 name=self.image_name+'_ramdisk',
1743 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
1745 if self.image_metadata:
1746 if 'ramdisk_url' in self.image_metadata and self.image_metadata['ramdisk_url']:
1747 ramdisk_image_settings.url = self.image_metadata['ramdisk_url']
1749 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1750 ramdisk_image = self.image_creators[-1].create()
1751 self.assertIsNotNone(ramdisk_image)
1753 # Create the main image
1754 os_image_settings = openstack_tests.cirros_url_image(
1755 name=self.image_name,
1756 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
1757 if self.image_metadata:
1758 if 'disk_url' in self.image_metadata and self.image_metadata['disk_url']:
1759 os_image_settings.url = self.image_metadata['disk_url']
1761 properties['kernel_id'] = kernel_image.id
1762 properties['ramdisk_id'] = ramdisk_image.id
1763 os_image_settings.extra_properties = properties
1764 self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
1765 created_image = self.image_creators[-1].create()
1766 self.assertIsNotNone(created_image)
1769 self.flavor_creator = OpenStackFlavor(
1770 self.admin_os_creds,
1771 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
1772 self.flavor_creator.create()
1775 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1776 self.network_creator.create()
1778 self.port_settings = PortSettings(name=guid + '-port',
1779 network_name=net_config.network_settings.name)
1780 except Exception as e:
1786 Cleans the created object
1788 if self.inst_creator:
1790 self.inst_creator.clean()
1791 except Exception as e:
1792 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1794 if self.flavor_creator:
1796 self.flavor_creator.clean()
1797 except Exception as e:
1798 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1800 if self.network_creator:
1802 self.network_creator.clean()
1803 except Exception as e:
1804 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1806 if self.image_creators:
1808 while self.image_creators:
1809 self.image_creators[0].clean()
1810 self.image_creators.pop(0)
1811 except Exception as e:
1812 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1814 super(self.__class__, self).__clean__()
1816 def test_create_delete_instance_from_three_part_image(self):
1818 Tests the creation of an OpenStack instance from a 3-part image.
1820 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1821 port_settings=[self.port_settings])
1823 # The last created image is the main image from which we create the instance
1824 self.inst_creator = OpenStackVmInstance(
1825 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1827 vm_inst = self.inst_creator.create()
1828 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1830 self.assertTrue(self.inst_creator.vm_active(block=True))
1833 nova_utils.delete_vm_instance(self.nova, vm_inst)
1835 self.assertTrue(self.inst_creator.vm_deleted(block=True))
1836 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1838 # Exception should not be thrown
1839 self.inst_creator.clean()