1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
22 from snaps.openstack.create_instance import VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings
23 from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
24 from snaps.openstack.create_keypairs import OpenStackKeypair, KeypairSettings
25 from snaps.openstack.create_network import OpenStackNetwork, PortSettings
26 from snaps.openstack.create_router import OpenStackRouter
27 from snaps.openstack.create_image import OpenStackImage
28 from snaps.openstack.create_security_group import SecurityGroupSettings, OpenStackSecurityGroup
29 from snaps.openstack.tests import openstack_tests, validation_utils
30 from snaps.openstack.utils import nova_utils
31 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
33 __author__ = 'spisarski'
37 logger = logging.getLogger('create_instance_tests')
40 class VmInstanceSettingsUnitTests(unittest.TestCase):
42 Tests the construction of the VmInstanceSettings class
45 def test_no_params(self):
46 with self.assertRaises(Exception):
49 def test_empty_config(self):
50 with self.assertRaises(Exception):
51 VmInstanceSettings(config=dict())
53 def test_name_only(self):
54 with self.assertRaises(Exception):
55 VmInstanceSettings(name='foo')
57 def test_config_with_name_only(self):
58 with self.assertRaises(Exception):
59 VmInstanceSettings(config={'name': 'foo'})
61 def test_name_flavor_only(self):
62 with self.assertRaises(Exception):
63 VmInstanceSettings(name='foo', flavor='bar')
65 def test_config_with_name_flavor_only(self):
66 with self.assertRaises(Exception):
67 VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
69 def test_name_flavor_port_only(self):
70 port_settings = PortSettings(name='foo-port', network_name='bar-net')
71 settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings])
72 self.assertEquals('foo', settings.name)
73 self.assertEquals('bar', settings.flavor)
74 self.assertEquals(1, len(settings.port_settings))
75 self.assertEquals('foo-port', settings.port_settings[0].name)
76 self.assertEquals('bar-net', settings.port_settings[0].network_name)
77 self.assertEquals(0, len(settings.security_group_names))
78 self.assertEquals(0, len(settings.floating_ip_settings))
79 self.assertIsNone(settings.sudo_user)
80 self.assertEquals(900, settings.vm_boot_timeout)
81 self.assertEquals(300, settings.vm_delete_timeout)
82 self.assertEquals(180, settings.ssh_connect_timeout)
83 self.assertIsNone(settings.availability_zone)
85 def test_config_with_name_flavor_port_only(self):
86 port_settings = PortSettings(name='foo-port', network_name='bar-net')
87 settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
88 self.assertEquals('foo', settings.name)
89 self.assertEquals('bar', settings.flavor)
90 self.assertEquals(1, len(settings.port_settings))
91 self.assertEquals('foo-port', settings.port_settings[0].name)
92 self.assertEquals('bar-net', settings.port_settings[0].network_name)
93 self.assertEquals(0, len(settings.security_group_names))
94 self.assertEquals(0, len(settings.floating_ip_settings))
95 self.assertIsNone(settings.sudo_user)
96 self.assertEquals(900, settings.vm_boot_timeout)
97 self.assertEquals(300, settings.vm_delete_timeout)
98 self.assertEquals(180, settings.ssh_connect_timeout)
99 self.assertIsNone(settings.availability_zone)
102 port_settings = PortSettings(name='foo-port', network_name='bar-net')
103 fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router')
105 settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings],
106 security_group_names=['sec_grp_1'], floating_ip_settings=[fip_settings],
107 sudo_user='joe', vm_boot_timeout=999, vm_delete_timeout=333,
108 ssh_connect_timeout=111, availability_zone='server name')
109 self.assertEquals('foo', settings.name)
110 self.assertEquals('bar', settings.flavor)
111 self.assertEquals(1, len(settings.port_settings))
112 self.assertEquals('foo-port', settings.port_settings[0].name)
113 self.assertEquals('bar-net', settings.port_settings[0].network_name)
114 self.assertEquals(1, len(settings.security_group_names))
115 self.assertEquals('sec_grp_1', settings.security_group_names[0])
116 self.assertEquals(1, len(settings.floating_ip_settings))
117 self.assertEquals('foo-fip', settings.floating_ip_settings[0].name)
118 self.assertEquals('bar-port', settings.floating_ip_settings[0].port_name)
119 self.assertEquals('foo-bar-router', settings.floating_ip_settings[0].router_name)
120 self.assertEquals('joe', settings.sudo_user)
121 self.assertEquals(999, settings.vm_boot_timeout)
122 self.assertEquals(333, settings.vm_delete_timeout)
123 self.assertEquals(111, settings.ssh_connect_timeout)
124 self.assertEquals('server name', settings.availability_zone)
126 def test_config_all(self):
127 port_settings = PortSettings(name='foo-port', network_name='bar-net')
128 fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router')
130 settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings],
131 'security_group_names': ['sec_grp_1'],
132 'floating_ips': [fip_settings], 'sudo_user': 'joe',
133 'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
134 'ssh_connect_timeout': 111, 'availability_zone': 'server name'})
135 self.assertEquals('foo', settings.name)
136 self.assertEquals('bar', settings.flavor)
137 self.assertEquals(1, len(settings.port_settings))
138 self.assertEquals('foo-port', settings.port_settings[0].name)
139 self.assertEquals('bar-net', settings.port_settings[0].network_name)
140 self.assertEquals(1, len(settings.security_group_names))
141 self.assertEquals(1, len(settings.floating_ip_settings))
142 self.assertEquals('foo-fip', settings.floating_ip_settings[0].name)
143 self.assertEquals('bar-port', settings.floating_ip_settings[0].port_name)
144 self.assertEquals('foo-bar-router', settings.floating_ip_settings[0].router_name)
145 self.assertEquals('joe', settings.sudo_user)
146 self.assertEquals(999, settings.vm_boot_timeout)
147 self.assertEquals(333, settings.vm_delete_timeout)
148 self.assertEquals(111, settings.ssh_connect_timeout)
149 self.assertEquals('server name', settings.availability_zone)
152 class FloatingIpSettingsUnitTests(unittest.TestCase):
154 Tests the construction of the FloatingIpSettings class
157 def test_no_params(self):
158 with self.assertRaises(Exception):
161 def test_empty_config(self):
162 with self.assertRaises(Exception):
163 FloatingIpSettings(config=dict())
165 def test_name_only(self):
166 with self.assertRaises(Exception):
167 FloatingIpSettings(name='foo')
169 def test_config_with_name_only(self):
170 with self.assertRaises(Exception):
171 FloatingIpSettings(config={'name': 'foo'})
173 def test_name_port_only(self):
174 with self.assertRaises(Exception):
175 FloatingIpSettings(name='foo', port_name='bar')
177 def test_config_with_name_port_only(self):
178 with self.assertRaises(Exception):
179 FloatingIpSettings(config={'name': 'foo', 'port_name': 'bar'})
181 def test_name_router_only(self):
182 with self.assertRaises(Exception):
183 FloatingIpSettings(name='foo', router_name='bar')
185 def test_config_with_name_router_only(self):
186 with self.assertRaises(Exception):
187 FloatingIpSettings(config={'name': 'foo', 'router_name': 'bar'})
189 def test_name_port_router_only(self):
190 settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router')
191 self.assertEquals('foo', settings.name)
192 self.assertEquals('foo-port', settings.port_name)
193 self.assertEquals('bar-router', settings.router_name)
194 self.assertIsNone(settings.subnet_name)
195 self.assertTrue(settings.provisioning)
197 def test_config_with_name_port_router_only(self):
198 settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router'})
199 self.assertEquals('foo', settings.name)
200 self.assertEquals('foo-port', settings.port_name)
201 self.assertEquals('bar-router', settings.router_name)
202 self.assertIsNone(settings.subnet_name)
203 self.assertTrue(settings.provisioning)
206 settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router',
207 subnet_name='bar-subnet', provisioning=False)
208 self.assertEquals('foo', settings.name)
209 self.assertEquals('foo-port', settings.port_name)
210 self.assertEquals('bar-router', settings.router_name)
211 self.assertEquals('bar-subnet', settings.subnet_name)
212 self.assertFalse(settings.provisioning)
214 def test_config_all(self):
215 settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router',
216 'subnet_name': 'bar-subnet', 'provisioning': False})
217 self.assertEquals('foo', settings.name)
218 self.assertEquals('foo-port', settings.port_name)
219 self.assertEquals('bar-router', settings.router_name)
220 self.assertEquals('bar-subnet', settings.subnet_name)
221 self.assertFalse(settings.provisioning)
224 class SimpleHealthCheck(OSIntegrationTestCase):
226 Test for the CreateInstance class with a single NIC/Port with Floating IPs
231 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
234 super(self.__class__, self).__start__()
236 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
237 self.keypair_priv_filepath = 'tmp/' + guid
238 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
239 self.keypair_name = guid + '-kp'
240 self.vm_inst_name = guid + '-inst'
241 self.port_1_name = guid + 'port-1'
242 self.port_2_name = guid + 'port-2'
243 self.floating_ip_name = guid + 'fip1'
245 # Initialize for tearDown()
246 self.image_creators = list()
247 self.network_creator = None
248 self.flavor_creator = None
249 self.inst_creator = None
251 self.priv_net_config = openstack_tests.get_priv_net_config(
252 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
253 self.port_settings = PortSettings(
254 name=self.port_1_name, network_name=self.priv_net_config.network_settings.name)
257 # Set the default image settings, then set any custom parameters sent from the app
258 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
260 if self.image_metadata:
261 if self.image_metadata['disk_url']:
262 self.os_image_settings.url = self.image_metadata['disk_url']
263 if self.image_metadata['extra_properties']:
264 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
267 # If this is a 3-part image create the kernel and ramdisk images first
268 if self.image_metadata:
269 if self.image_metadata['kernel_url']:
270 kernel_image_settings = openstack_tests.cirros_url_image(
271 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
272 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
273 kernel_image = self.image_creators[-1].create()
274 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
276 if self.image_metadata['ramdisk_url']:
277 ramdisk_image_settings = openstack_tests.cirros_url_image(
278 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
279 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
280 ramdisk_image = self.image_creators[-1].create()
281 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
283 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
284 self.image_creators[-1].create()
287 self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
288 self.network_creator.create()
291 self.flavor_creator = OpenStackFlavor(
293 FlavorSettings(name=guid + '-flavor-name', ram=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.flavor_creator:
317 self.flavor_creator.clean()
318 except Exception as e:
319 logger.error('Unexpected exception cleaning network with message - ' + e.message)
321 if self.image_creators:
323 while self.image_creators:
324 self.image_creators[-1].clean()
325 self.image_creators.pop()
326 except Exception as e:
327 logger.error('Unexpected exception cleaning image with message - ' + e.message)
329 super(self.__class__, self).__clean__()
331 def test_check_vm_ip_dhcp(self):
333 Tests the creation of an OpenStack instance with a single port and ensures that it's assigned IP address is
336 instance_settings = VmInstanceSettings(
337 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
339 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
340 self.image_creators[-1].image_settings)
341 vm = self.inst_creator.create()
343 ip = self.inst_creator.get_port_ip(self.port_settings.name)
344 self.assertIsNotNone(ip)
346 self.assertTrue(self.inst_creator.vm_active(block=True))
350 start_time = time.time()
351 match_value = 'Lease of.*obtained'
353 logger.info("Looking for expression %s in the console log" % match_value)
355 while timeout > time.time() - start_time:
356 output = vm.get_console_output()
357 full_log = full_log + output
358 if re.search(match_value, output):
359 logger.info('DHCP lease obtained logged in console')
361 logger.info('With correct IP address')
364 logger.error('With incorrect IP address')
368 logger.error('Full console output -\n' + full_log)
370 logger.debug('Full console output -\n' + full_log)
372 self.assertTrue(found)
375 class CreateInstanceSimpleTests(OSIntegrationTestCase):
377 Simple instance creation tests without any other objects
381 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
384 super(self.__class__, self).__start__()
386 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
387 self.vm_inst_name = guid + '-inst'
388 self.nova = nova_utils.nova_client(self.os_creds)
389 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
391 net_config = openstack_tests.get_priv_net_config(
392 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
393 router_name=guid + '-pub-router', external_net=self.ext_net_name)
395 # Initialize for tearDown()
396 self.image_creators = list()
397 self.flavor_creator = None
399 self.net_creator = None
400 self.inst_creator = None
404 # Set any custom parameters sent from the app
405 if self.image_metadata:
406 if self.image_metadata['disk_url']:
407 self.os_image_settings.url = self.image_metadata['disk_url']
408 if self.image_metadata['extra_properties']:
409 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
411 # If this is a 3-part image create the kernel and ramdisk images first
412 if self.image_metadata:
413 if self.image_metadata['kernel_url']:
414 kernel_image_settings = openstack_tests.cirros_url_image(
415 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
416 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
417 kernel_image = self.image_creators[-1].create()
418 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
420 if self.image_metadata['ramdisk_url']:
421 ramdisk_image_settings = openstack_tests.cirros_url_image(
422 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
423 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
424 ramdisk_image = self.image_creators[-1].create()
425 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
427 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
428 self.image_creators[-1].create()
431 self.flavor_creator = OpenStackFlavor(
433 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
434 self.flavor_creator.create()
437 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
438 self.network_creator.create()
440 self.port_settings = PortSettings(name=guid + '-port',
441 network_name=net_config.network_settings.name)
443 except Exception as e:
449 Cleans the created object
451 if self.inst_creator:
453 self.inst_creator.clean()
454 except Exception as e:
455 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
457 if self.flavor_creator:
459 self.flavor_creator.clean()
460 except Exception as e:
461 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
465 self.net_creator.clean()
466 except Exception as e:
467 logger.error('Unexpected exception cleaning network with message - ' + e.message)
469 if self.image_creators:
471 while self.image_creators:
472 self.image_creators[-1].clean()
473 self.image_creators.pop()
474 except Exception as e:
475 logger.error('Unexpected exception cleaning image with message - ' + e.message)
477 super(self.__class__, self).__clean__()
479 def test_create_delete_instance(self):
481 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
483 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
484 port_settings=[self.port_settings])
486 self.inst_creator = OpenStackVmInstance(
487 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
489 vm_inst = self.inst_creator.create()
490 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
493 nova_utils.delete_vm_instance(self.nova, vm_inst)
495 self.assertTrue(self.inst_creator.vm_deleted(block=True))
496 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
498 # Exception should not be thrown
499 self.inst_creator.clean()
502 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
504 Test for the CreateInstance class with a single NIC/Port with Floating IPs
509 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
512 super(self.__class__, self).__start__()
514 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
515 self.keypair_priv_filepath = 'tmp/' + guid
516 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
517 self.keypair_name = guid + '-kp'
518 self.vm_inst_name = guid + '-inst'
519 self.port_1_name = guid + 'port-1'
520 self.port_2_name = guid + 'port-2'
521 self.floating_ip_name = guid + 'fip1'
523 # Initialize for tearDown()
524 self.image_creators = list()
525 self.network_creator = None
526 self.router_creator = None
527 self.flavor_creator = None
528 self.keypair_creator = None
529 self.inst_creators = list()
531 self.pub_net_config = openstack_tests.get_pub_net_config(
532 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
533 router_name=guid + '-pub-router', external_net=self.ext_net_name)
534 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
538 # Set any custom parameters sent from the app
539 if self.image_metadata:
540 if self.image_metadata['disk_url']:
541 self.os_image_settings.url = self.image_metadata['disk_url']
542 if self.image_metadata['extra_properties']:
543 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
545 # If this is a 3-part image create the kernel and ramdisk images first
546 if self.image_metadata:
547 if self.image_metadata['kernel_url']:
548 kernel_image_settings = openstack_tests.cirros_url_image(
549 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
550 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
551 kernel_image = self.image_creators[-1].create()
552 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
554 if self.image_metadata['ramdisk_url']:
555 ramdisk_image_settings = openstack_tests.cirros_url_image(
556 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
557 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
558 ramdisk_image = self.image_creators[-1].create()
559 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
561 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
562 self.image_creators[-1].create()
565 self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
566 self.network_creator.create()
569 self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
570 self.router_creator.create()
573 self.flavor_creator = OpenStackFlavor(
575 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
576 self.flavor_creator.create()
578 self.keypair_creator = OpenStackKeypair(
579 self.os_creds, KeypairSettings(
580 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
581 private_filepath=self.keypair_priv_filepath))
582 self.keypair_creator.create()
583 except Exception as e:
589 Cleans the created object
591 for inst_creator in self.inst_creators:
594 except Exception as e:
595 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
597 if self.keypair_creator:
599 self.keypair_creator.clean()
600 except Exception as e:
601 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
603 if os.path.isfile(self.keypair_pub_filepath):
604 os.remove(self.keypair_pub_filepath)
606 if os.path.isfile(self.keypair_priv_filepath):
607 os.remove(self.keypair_priv_filepath)
609 if self.flavor_creator:
611 self.flavor_creator.clean()
612 except Exception as e:
613 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
615 if self.router_creator:
617 self.router_creator.clean()
618 except Exception as e:
619 logger.error('Unexpected exception cleaning router with message - ' + e.message)
621 if self.network_creator:
623 self.network_creator.clean()
624 except Exception as e:
625 logger.error('Unexpected exception cleaning network with message - ' + e.message)
627 if self.image_creators:
629 while self.image_creators:
630 self.image_creators[-1].clean()
631 self.image_creators.pop()
632 except Exception as e:
633 logger.error('Unexpected exception cleaning image with message - ' + e.message)
635 super(self.__class__, self).__clean__()
637 def test_single_port_static(self):
639 Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
643 port_settings = PortSettings(
644 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name,
645 ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}])
647 instance_settings = VmInstanceSettings(
648 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
649 floating_ip_settings=[FloatingIpSettings(
650 name=self.floating_ip_name, port_name=self.port_1_name,
651 router_name=self.pub_net_config.router_settings.name)])
653 inst_creator = OpenStackVmInstance(
654 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
655 keypair_settings=self.keypair_creator.keypair_settings)
656 self.inst_creators.append(inst_creator)
657 vm_inst = inst_creator.create()
659 self.assertEquals(ip_1, inst_creator.get_port_ip(self.port_1_name))
660 self.assertTrue(inst_creator.vm_active(block=True))
661 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
663 def test_ssh_client_fip_before_active(self):
665 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
667 port_settings = PortSettings(
668 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
670 instance_settings = VmInstanceSettings(
671 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
672 floating_ip_settings=[FloatingIpSettings(
673 name=self.floating_ip_name, port_name=self.port_1_name,
674 router_name=self.pub_net_config.router_settings.name)])
676 inst_creator = OpenStackVmInstance(
677 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
678 keypair_settings=self.keypair_creator.keypair_settings)
679 self.inst_creators.append(inst_creator)
680 vm_inst = inst_creator.create()
681 self.assertIsNotNone(vm_inst)
683 self.assertTrue(inst_creator.vm_active(block=True))
684 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
686 self.assertTrue(validate_ssh_client(inst_creator))
688 def test_ssh_client_fip_after_active(self):
690 Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
692 port_settings = PortSettings(
693 name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
695 instance_settings = VmInstanceSettings(
696 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
697 floating_ip_settings=[FloatingIpSettings(
698 name=self.floating_ip_name, port_name=self.port_1_name,
699 router_name=self.pub_net_config.router_settings.name)])
701 inst_creator = OpenStackVmInstance(
702 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
703 keypair_settings=self.keypair_creator.keypair_settings)
704 self.inst_creators.append(inst_creator)
706 # block=True will force the create() method to block until the
707 vm_inst = inst_creator.create(block=True)
708 self.assertIsNotNone(vm_inst)
710 self.assertTrue(inst_creator.vm_active(block=True))
711 self.assertEquals(vm_inst, inst_creator.get_vm_inst())
713 self.assertTrue(validate_ssh_client(inst_creator))
715 # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
716 # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
717 # def test_allowed_address_port_access(self):
719 # Tests to ensure that setting allowed_address_pairs on a port functions as designed
721 # port_settings_1 = PortSettings(
722 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
724 # instance_settings_1 = VmInstanceSettings(
725 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
726 # floating_ip_settings=[FloatingIpSettings(
727 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
728 # router_name=self.pub_net_config.router_settings.name)])
730 # inst_creator_1 = OpenStackVmInstance(
731 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
732 # keypair_settings=self.keypair_creator.keypair_settings)
733 # self.inst_creators.append(inst_creator_1)
735 # # block=True will force the create() method to block until the
736 # vm_inst_1 = inst_creator_1.create(block=True)
737 # self.assertIsNotNone(vm_inst_1)
739 # port_settings_1 = PortSettings(
740 # name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
742 # instance_settings_1 = VmInstanceSettings(
743 # name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
744 # floating_ip_settings=[FloatingIpSettings(
745 # name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
746 # router_name=self.pub_net_config.router_settings.name)])
748 # inst_creator_1 = OpenStackVmInstance(
749 # self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
750 # keypair_settings=self.keypair_creator.keypair_settings)
751 # self.inst_creators.append(inst_creator_1)
752 # inst_creator_1.create(block=True)
754 # ip = inst_creator_1.get_port_ip(port_settings_1.name,
755 # subnet_name=self.pub_net_config.network_settings.subnet_settings[0].name)
756 # self.assertIsNotNone(ip)
757 # mac_addr = inst_creator_1.get_port_mac(port_settings_1.name)
758 # self.assertIsNotNone(mac_addr)
760 # allowed_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
762 # # Create VM that can be accessed by vm_inst_1
763 # port_settings_2 = PortSettings(
764 # name=self.port_1_name + '-2', network_name=self.pub_net_config.network_settings.name,
765 # allowed_address_pairs=allowed_address_pairs)
767 # instance_settings_2 = VmInstanceSettings(
768 # name=self.vm_inst_name + '-2', flavor=self.flavor_creator.flavor_settings.name,
769 # port_settings=[port_settings_2])
771 # inst_creator_2 = OpenStackVmInstance(
772 # self.os_creds, instance_settings_2, self.image_creators[-1].image_settings)
773 # self.inst_creators.append(inst_creator_2)
774 # inst_creator_2.create(block=True)
776 # # Create VM that cannot be accessed by vm_inst_1
778 # mac_addr = '0a:1b:2c:3d:4e:5f'
779 # invalid_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
781 # port_settings_3 = PortSettings(
782 # name=self.port_1_name + '-3', network_name=self.pub_net_config.network_settings.name,
783 # allowed_address_pairs=invalid_address_pairs)
785 # instance_settings_3 = VmInstanceSettings(
786 # name=self.vm_inst_name + '-3', flavor=self.flavor_creator.flavor_settings.name,
787 # port_settings=[port_settings_3])
789 # inst_creator_3 = OpenStackVmInstance(
790 # self.os_creds, instance_settings_3, self.image_creators[-1].image_settings)
791 # self.inst_creators.append(inst_creator_3)
792 # inst_creator_3.create(block=True)
795 # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would
796 # expect inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
797 # TODO - Add validation
800 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
802 Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set
807 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
810 super(self.__class__, self).__start__()
812 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
813 self.vm_inst_name = guid + '-inst'
814 self.port_1_name = guid + 'port-1'
815 self.port_2_name = guid + 'port-2'
816 self.floating_ip_name = guid + 'fip1'
818 # Initialize for tearDown()
819 self.image_creators = list()
820 self.network_creator = None
821 self.flavor_creator = None
822 self.inst_creator = None
824 self.net_config = openstack_tests.get_priv_net_config(
825 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
826 router_name=guid + '-pub-router', external_net=self.ext_net_name)
827 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
831 # Set any custom parameters sent from the app
832 if self.image_metadata:
833 if self.image_metadata['disk_url']:
834 self.os_image_settings.url = self.image_metadata['disk_url']
835 if self.image_metadata['extra_properties']:
836 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
838 # If this is a 3-part image create the kernel and ramdisk images first
839 if self.image_metadata:
840 if self.image_metadata['kernel_url']:
841 kernel_image_settings = openstack_tests.cirros_url_image(
842 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
843 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
844 kernel_image = self.image_creators[-1].create()
845 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
847 if self.image_metadata['ramdisk_url']:
848 ramdisk_image_settings = openstack_tests.cirros_url_image(
849 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
850 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
851 ramdisk_image = self.image_creators[-1].create()
852 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
854 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
855 self.image_creators[-1].create()
858 self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
859 self.network_creator.create()
862 self.flavor_creator = OpenStackFlavor(
864 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
865 self.flavor_creator.create()
866 except Exception as e:
872 Cleans the created object
874 if self.inst_creator:
876 self.inst_creator.clean()
877 except Exception as e:
878 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
880 if self.flavor_creator:
882 self.flavor_creator.clean()
883 except Exception as e:
884 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
886 if self.network_creator:
888 self.network_creator.clean()
889 except Exception as e:
890 logger.error('Unexpected exception cleaning network with message - ' + e.message)
892 if self.image_creators:
894 while self.image_creators:
895 self.image_creators[-1].clean()
896 self.image_creators.pop()
897 except Exception as e:
898 logger.error('Unexpected exception cleaning image with message - ' + e.message)
900 super(self.__class__, self).__clean__()
902 def test_set_custom_valid_ip_one_subnet(self):
904 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
907 port_settings = PortSettings(
908 name=self.port_1_name, network_name=self.net_config.network_settings.name,
909 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
911 instance_settings = VmInstanceSettings(
912 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
914 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
915 self.image_creators[-1].image_settings)
916 self.inst_creator.create()
918 self.assertEquals(ip, self.inst_creator.get_port_ip(
919 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
921 def test_set_custom_invalid_ip_one_subnet(self):
923 Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
926 port_settings = PortSettings(
927 name=self.port_1_name, network_name=self.net_config.network_settings.name,
928 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
930 instance_settings = VmInstanceSettings(
931 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
933 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
934 self.image_creators[-1].image_settings)
936 with self.assertRaises(Exception):
937 self.inst_creator.create()
939 def test_set_custom_valid_mac(self):
941 Tests the creation of an OpenStack instance with a single port where the MAC address is assigned.
943 mac_addr = '0a:1b:2c:3d:4e:5f'
944 port_settings = PortSettings(
945 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr)
947 instance_settings = VmInstanceSettings(
948 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
950 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
951 self.image_creators[-1].image_settings)
952 self.inst_creator.create()
954 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
956 def test_set_custom_invalid_mac(self):
958 Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being
959 assigned. This should raise an Exception
961 port_settings = PortSettings(
962 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo')
964 instance_settings = VmInstanceSettings(
965 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
967 self.inst_creator = OpenStackVmInstance(
968 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
970 with self.assertRaises(Exception):
971 self.inst_creator.create()
973 def test_set_custom_mac_and_ip(self):
975 Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned.
978 mac_addr = '0a:1b:2c:3d:4e:5f'
979 port_settings = PortSettings(
980 name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr,
981 ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
983 instance_settings = VmInstanceSettings(
984 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
986 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
987 self.image_creators[-1].image_settings)
988 self.inst_creator.create()
990 self.assertEquals(ip, self.inst_creator.get_port_ip(
991 self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
992 self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
994 def test_set_allowed_address_pairs(self):
996 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set.
999 mac_addr = '0a:1b:2c:3d:4e:5f'
1000 pair = {'ip_address': ip, 'mac_address': mac_addr}
1001 port_settings = PortSettings(
1002 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1004 instance_settings = VmInstanceSettings(
1005 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1007 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1008 self.image_creators[-1].image_settings)
1009 self.inst_creator.create()
1011 port = self.inst_creator.get_port_by_name(port_settings.name)
1012 self.assertIsNotNone(port)
1013 self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
1014 self.assertEquals(1, len(port['port']['allowed_address_pairs']))
1015 validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0])
1017 def test_set_allowed_address_pairs_bad_mac(self):
1019 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1020 invalid MAC address.
1024 pair = {'ip_address': ip, 'mac_address': mac_addr}
1026 pairs.add((ip, mac_addr))
1027 port_settings = PortSettings(
1028 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1030 instance_settings = VmInstanceSettings(
1031 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1033 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1034 self.image_creators[-1].image_settings)
1035 with self.assertRaises(Exception):
1036 self.inst_creator.create()
1038 def test_set_allowed_address_pairs_bad_ip(self):
1040 Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1041 invalid MAC address.
1044 mac_addr = '0a:1b:2c:3d:4e:5f'
1045 pair = {'ip_address': ip, 'mac_address': mac_addr}
1047 pairs.add((ip, mac_addr))
1048 port_settings = PortSettings(
1049 name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1051 instance_settings = VmInstanceSettings(
1052 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1054 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1055 self.image_creators[-1].image_settings)
1056 with self.assertRaises(Exception):
1057 self.inst_creator.create()
1060 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1062 Test for the CreateInstance where one VM is deployed to each compute node
1067 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1070 super(self.__class__, self).__start__()
1072 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1073 self.vm_inst_name = guid + '-inst'
1074 self.port_base_name = guid + 'port'
1076 # Initialize for tearDown()
1077 self.image_creators = list()
1078 self.flavor_creator = None
1079 self.network_creator = None
1080 self.inst_creators = list()
1082 self.priv_net_config = openstack_tests.get_priv_net_config(
1083 net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
1085 self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
1089 self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
1090 self.network_creator.create()
1093 self.flavor_creator = OpenStackFlavor(
1094 self.admin_os_creds,
1095 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
1096 self.flavor_creator.create()
1099 # Set any custom parameters sent from the app
1100 if self.image_metadata:
1101 if self.image_metadata['disk_url']:
1102 self.os_image_settings.url = self.image_metadata['disk_url']
1103 if self.image_metadata['extra_properties']:
1104 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1106 # If this is a 3-part image create the kernel and ramdisk images first
1107 if self.image_metadata:
1108 if self.image_metadata['kernel_url']:
1109 kernel_image_settings = openstack_tests.cirros_url_image(
1110 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1111 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1112 kernel_image = self.image_creators[-1].create()
1113 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1115 if self.image_metadata['ramdisk_url']:
1116 ramdisk_image_settings = openstack_tests.cirros_url_image(
1117 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1118 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1119 ramdisk_image = self.image_creators[-1].create()
1120 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1122 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1123 self.image_creators[-1].create()
1125 except Exception as e:
1131 Cleans the created object
1133 for inst_creator in self.inst_creators:
1135 inst_creator.clean()
1136 except Exception as e:
1137 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1139 if self.flavor_creator:
1141 self.flavor_creator.clean()
1142 except Exception as e:
1143 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1145 if self.network_creator:
1147 self.network_creator.clean()
1148 except Exception as e:
1149 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1151 if self.image_creators:
1153 while self.image_creators:
1154 self.image_creators[-1].clean()
1155 self.image_creators.pop()
1156 except Exception as e:
1157 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1159 super(self.__class__, self).__clean__()
1161 def test_deploy_vm_to_each_compute_node(self):
1163 Tests the creation of OpenStack VM instances to each compute node.
1165 from snaps.openstack.utils import nova_utils
1166 nova = nova_utils.nova_client(self.admin_os_creds)
1167 zones = nova_utils.get_nova_availability_zones(nova)
1169 # Create Instance on each server/zone
1172 inst_name = self.vm_inst_name + '-' + zone
1174 port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr),
1175 network_name=self.priv_net_config.network_settings.name)
1177 instance_settings = VmInstanceSettings(
1178 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
1179 port_settings=[port_settings])
1180 inst_creator = OpenStackVmInstance(
1181 self.admin_os_creds, instance_settings, self.image_creators[-1].image_settings)
1182 self.inst_creators.append(inst_creator)
1183 inst_creator.create()
1185 # Validate instances to ensure they've been deployed to the correct server
1188 creator = self.inst_creators[index]
1189 self.assertTrue(creator.vm_active(block=True))
1190 vm = creator.get_vm_inst()
1191 deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
1192 deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
1193 self.assertEquals(zone, deployed_zone + ':' + deployed_host)
1197 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1199 Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o
1200 These tests require a Centos image
1205 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1208 super(self.__class__, self).__start__()
1210 # Initialize for tearDown()
1211 self.image_creators = list()
1212 self.network_creators = list()
1213 self.router_creators = list()
1214 self.flavor_creator = None
1215 self.keypair_creator = None
1216 self.inst_creator = None
1218 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1219 self.keypair_priv_filepath = 'tmp/' + self.guid
1220 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1221 self.keypair_name = self.guid + '-kp'
1222 self.vm_inst_name = self.guid + '-inst'
1223 self.port_1_name = self.guid + '-port-1'
1224 self.port_2_name = self.guid + '-port-2'
1225 self.floating_ip_name = self.guid + 'fip1'
1226 self.priv_net_config = openstack_tests.get_priv_net_config(
1227 net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet',
1228 router_name=self.guid + '-priv-router', external_net=self.ext_net_name)
1229 self.pub_net_config = openstack_tests.get_pub_net_config(
1230 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1231 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1232 image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1233 self.os_image_settings = openstack_tests.centos_url_image(name=image_name)
1237 # Set any custom parameters sent from the app
1238 if self.image_metadata:
1239 if self.image_metadata['disk_url']:
1240 self.os_image_settings.url = self.image_metadata['disk_url']
1241 if self.image_metadata['extra_properties']:
1242 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1244 # If this is a 3-part image create the kernel and ramdisk images first
1245 if self.image_metadata:
1246 if self.image_metadata['kernel_url']:
1247 kernel_image_settings = openstack_tests.cirros_url_image(
1248 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1249 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1250 kernel_image = self.image_creators[-1].create()
1251 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1253 if self.image_metadata['ramdisk_url']:
1254 ramdisk_image_settings = openstack_tests.cirros_url_image(
1255 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1256 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1257 ramdisk_image = self.image_creators[-1].create()
1258 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1260 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1261 self.image_creators[-1].create()
1263 # First network is public
1264 self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
1265 # Second network is private
1266 self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings))
1267 for network_creator in self.network_creators:
1268 network_creator.create()
1270 self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings))
1271 self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings))
1274 for router_creator in self.router_creators:
1275 router_creator.create()
1278 self.flavor_creator = OpenStackFlavor(
1279 self.admin_os_creds,
1280 FlavorSettings(name=self.guid + '-flavor-name', ram=512, disk=10, vcpus=2,
1281 metadata=self.flavor_metadata))
1282 self.flavor_creator.create()
1285 self.keypair_creator = OpenStackKeypair(
1286 self.os_creds, KeypairSettings(
1287 name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
1288 private_filepath=self.keypair_priv_filepath))
1289 self.keypair_creator.create()
1290 except Exception as e:
1292 raise Exception(e.message)
1296 Cleans the created objects
1298 if self.inst_creator:
1300 self.inst_creator.clean()
1301 except Exception as e:
1302 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1304 if self.keypair_creator:
1306 self.keypair_creator.clean()
1307 except Exception as e:
1308 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
1310 if os.path.isfile(self.keypair_pub_filepath):
1311 os.remove(self.keypair_pub_filepath)
1313 if os.path.isfile(self.keypair_priv_filepath):
1314 os.remove(self.keypair_priv_filepath)
1316 if self.flavor_creator:
1318 self.flavor_creator.clean()
1319 except Exception as e:
1320 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1322 for router_creator in self.router_creators:
1324 router_creator.clean()
1325 except Exception as e:
1326 logger.error('Unexpected exception cleaning router with message - ' + e.message)
1328 for network_creator in self.network_creators:
1330 network_creator.clean()
1331 except Exception as e:
1332 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1334 if self.image_creators:
1336 while self.image_creators:
1337 self.image_creators[-1].clean()
1338 self.image_creators.pop()
1339 except Exception as e:
1340 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1342 super(self.__class__, self).__clean__()
1344 def test_dual_ports_dhcp(self):
1346 Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP.
1347 NOTE: This test and any others that call ansible will most likely fail unless you do one of
1349 1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False
1350 2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False
1351 Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail.
1353 # Create ports/NICs for instance
1356 for network_creator in self.network_creators:
1357 ports_settings.append(PortSettings(
1358 name=self.guid + '-port-' + str(ctr),
1359 network_name=network_creator.network_settings.name))
1363 instance_settings = VmInstanceSettings(
1364 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings,
1365 floating_ip_settings=[FloatingIpSettings(
1366 name=self.floating_ip_name, port_name=self.port_1_name,
1367 router_name=self.pub_net_config.router_settings.name)])
1369 self.inst_creator = OpenStackVmInstance(
1370 self.os_creds, instance_settings, self.image_creators[-1].image_settings,
1371 keypair_settings=self.keypair_creator.keypair_settings)
1373 vm_inst = self.inst_creator.create(block=True)
1375 self.assertEquals(vm_inst, self.inst_creator.get_vm_inst())
1377 # Effectively blocks until VM has been properly activated
1378 self.assertTrue(self.inst_creator.vm_active(block=True))
1380 # Effectively blocks until VM's ssh port has been opened
1381 self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1383 self.inst_creator.config_nics()
1385 # TODO - *** ADD VALIDATION HERE ***
1386 # TODO - Add validation that both floating IPs work
1387 # TODO - Add tests where only one NIC has a floating IP
1388 # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway
1391 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1393 Tests that include, add, and remove security groups from VM instances
1397 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1400 super(self.__class__, self).__start__()
1402 self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1403 self.vm_inst_name = self.guid + '-inst'
1404 self.nova = nova_utils.nova_client(self.os_creds)
1405 self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
1407 self.vm_inst_name = self.guid + '-inst'
1408 self.port_1_name = self.guid + 'port-1'
1409 self.port_2_name = self.guid + 'port-2'
1410 self.floating_ip_name = self.guid + 'fip1'
1412 net_config = openstack_tests.get_priv_net_config(
1413 net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1414 router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1416 # Initialize for tearDown()
1417 self.image_creators = list()
1418 self.flavor_creator = None
1419 self.network_creator = None
1420 self.router_creator = None
1421 self.inst_creator = None
1422 self.sec_grp_creators = list()
1426 # Set any custom parameters sent from the app
1427 if self.image_metadata:
1428 if self.image_metadata['disk_url']:
1429 self.os_image_settings.url = self.image_metadata['disk_url']
1430 if self.image_metadata['extra_properties']:
1431 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1433 # If this is a 3-part image create the kernel and ramdisk images first
1434 if self.image_metadata:
1435 if self.image_metadata['kernel_url']:
1436 kernel_image_settings = openstack_tests.cirros_url_image(
1437 name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1438 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1439 kernel_image = self.image_creators[-1].create()
1440 self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1442 if self.image_metadata['ramdisk_url']:
1443 ramdisk_image_settings = openstack_tests.cirros_url_image(
1444 name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1445 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1446 ramdisk_image = self.image_creators[-1].create()
1447 self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1449 self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1450 self.image_creators[-1].create()
1453 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1454 self.network_creator.create()
1457 self.flavor_creator = OpenStackFlavor(
1458 self.admin_os_creds,
1459 FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=2,
1460 metadata=self.flavor_metadata))
1461 self.flavor_creator.create()
1463 self.port_settings = PortSettings(name=self.guid + '-port',
1464 network_name=net_config.network_settings.name)
1465 except Exception as e:
1471 Cleans the created object
1473 if self.inst_creator:
1475 self.inst_creator.clean()
1476 except Exception as e:
1477 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1479 for sec_grp_creator in self.sec_grp_creators:
1481 sec_grp_creator.clean()
1482 except Exception as e:
1483 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
1485 if self.flavor_creator:
1487 self.flavor_creator.clean()
1488 except Exception as e:
1489 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1491 if self.network_creator:
1493 self.network_creator.clean()
1494 except Exception as e:
1495 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1497 if self.image_creators:
1499 while self.image_creators:
1500 self.image_creators[-1].clean()
1501 self.image_creators.pop()
1502 except Exception as e:
1503 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1505 super(self.__class__, self).__clean__()
1507 def test_add_security_group(self):
1509 Tests the addition of a security group created after the instance.
1512 instance_settings = VmInstanceSettings(
1513 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1514 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1515 self.image_creators[-1].image_settings)
1516 vm_inst = self.inst_creator.create(block=True)
1517 self.assertIsNotNone(vm_inst)
1519 # Create security group object to add to instance
1520 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1521 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1522 sec_grp = sec_grp_creator.create()
1523 self.sec_grp_creators.append(sec_grp_creator)
1525 # Check that group has not been added
1526 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1528 # Add security group to instance after activated
1529 self.inst_creator.add_security_group(sec_grp)
1531 # Validate that security group has been added
1532 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1534 def test_add_invalid_security_group(self):
1536 Tests the addition of a security group that no longer exists.
1539 instance_settings = VmInstanceSettings(
1540 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1541 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1542 self.image_creators[-1].image_settings)
1543 vm_inst = self.inst_creator.create(block=True)
1544 self.assertIsNotNone(vm_inst)
1546 # Create security group object to add to instance
1547 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1548 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1549 sec_grp = sec_grp_creator.create()
1550 sec_grp_creator.clean()
1551 self.sec_grp_creators.append(sec_grp_creator)
1553 # Check that group has not been added
1554 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1556 # Add security group to instance after activated
1557 self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1559 # Validate that security group has been added
1560 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1562 def test_remove_security_group(self):
1564 Tests the removal of a security group created before and added to the instance.
1566 # Create security group object to add to instance
1567 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1568 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1569 sec_grp = sec_grp_creator.create()
1570 self.sec_grp_creators.append(sec_grp_creator)
1573 instance_settings = VmInstanceSettings(
1574 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1575 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1576 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1577 self.image_creators[-1].image_settings)
1578 vm_inst = self.inst_creator.create(block=True)
1579 self.assertIsNotNone(vm_inst)
1581 # Check that group has been added
1582 self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
1584 # Add security group to instance after activated
1585 self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1587 # Validate that security group has been added
1588 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1590 def test_remove_security_group_never_added(self):
1592 Tests the removal of a security group that was never added in the first place.
1594 # Create security group object to add to instance
1595 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1596 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1597 sec_grp = sec_grp_creator.create()
1598 self.sec_grp_creators.append(sec_grp_creator)
1601 instance_settings = VmInstanceSettings(
1602 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1603 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1604 self.image_creators[-1].image_settings)
1605 vm_inst = self.inst_creator.create(block=True)
1606 self.assertIsNotNone(vm_inst)
1608 # Check that group has been added
1609 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1611 # Add security group to instance after activated
1612 self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1614 # Validate that security group has been added
1615 self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1617 def test_add_same_security_group(self):
1619 Tests the addition of a security group created before add added to the instance.
1621 # Create security group object to add to instance
1622 sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1623 sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1624 sec_grp = sec_grp_creator.create()
1625 self.sec_grp_creators.append(sec_grp_creator)
1628 instance_settings = VmInstanceSettings(
1629 name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1630 security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1631 self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings,
1632 self.image_creators[-1].image_settings)
1633 vm_inst = self.inst_creator.create(block=True)
1634 self.assertIsNotNone(vm_inst)
1636 # Check that group has been added
1637 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1639 # Add security group to instance after activated
1640 self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1642 # Validate that security group has been added
1643 self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1646 def inst_has_sec_grp(vm_inst, sec_grp_name):
1648 Returns true if instance has a security group of a given name
1651 if not hasattr(vm_inst, 'security_groups'):
1655 for sec_grp_dict in vm_inst.security_groups:
1656 if sec_grp_name in sec_grp_dict['name']:
1662 def validate_ssh_client(instance_creator):
1664 Returns True if instance_creator returns an SSH client that is valid
1665 :param instance_creator: the object responsible for creating the VM instance
1668 ssh_active = instance_creator.vm_ssh_active(block=True)
1671 ssh_client = instance_creator.ssh_client()
1673 out = ssh_client.exec_command('pwd')[1]
1677 channel = out.channel
1678 in_buffer = channel.in_buffer
1679 pwd_out = in_buffer.read(1024)
1680 if not pwd_out or len(pwd_out) < 10:
1687 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1689 Test for the CreateInstance class for creating an image from a 3-part image
1694 Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1697 super(self.__class__, self).__start__()
1699 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1700 self.image_name = guid
1701 self.vm_inst_name = guid + '-inst'
1702 self.nova = nova_utils.nova_client(self.os_creds)
1704 net_config = openstack_tests.get_priv_net_config(
1705 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1706 router_name=guid + '-pub-router', external_net=self.ext_net_name)
1708 # Initialize for tearDown()
1709 self.image_creators = list()
1710 self.network_creator = None
1711 self.flavor_creator = None
1712 self.inst_creator = None
1718 if self.image_metadata and self.image_metadata['extra_properties']:
1719 properties = self.image_metadata['extra_properties']
1721 # Create the kernel image
1722 kernel_image_settings = openstack_tests.cirros_url_image(
1723 name=self.image_name+'_kernel',
1724 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
1726 if self.image_metadata and self.image_metadata['kernel_url']:
1727 kernel_image_settings.url = self.image_metadata['kernel_url']
1729 self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1730 kernel_image = self.image_creators[-1].create()
1732 # Create the ramdisk image
1733 ramdisk_image_settings = openstack_tests.cirros_url_image(
1734 name=self.image_name+'_ramdisk',
1735 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
1736 if self.image_metadata and self.image_metadata['ramdisk_url']:
1737 ramdisk_image_settings.url = self.image_metadata['ramdisk_url']
1739 self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1740 ramdisk_image = self.image_creators[-1].create()
1741 self.assertIsNotNone(ramdisk_image)
1743 # Create the main image
1744 os_image_settings = openstack_tests.cirros_url_image(
1745 name=self.image_name,
1746 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
1747 if self.image_metadata and self.image_metadata['disk_url']:
1748 os_image_settings.url = self.image_metadata['disk_url']
1750 properties['kernel_id'] = kernel_image.id
1751 properties['ramdisk_id'] = ramdisk_image.id
1752 os_image_settings.extra_properties = properties
1753 self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
1754 created_image = self.image_creators[-1].create()
1755 self.assertIsNotNone(created_image)
1758 self.flavor_creator = OpenStackFlavor(
1759 self.admin_os_creds,
1760 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
1761 self.flavor_creator.create()
1764 self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1765 self.network_creator.create()
1767 self.port_settings = PortSettings(name=guid + '-port',
1768 network_name=net_config.network_settings.name)
1769 except Exception as e:
1775 Cleans the created object
1777 if self.inst_creator:
1779 self.inst_creator.clean()
1780 except Exception as e:
1781 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1783 if self.flavor_creator:
1785 self.flavor_creator.clean()
1786 except Exception as e:
1787 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1789 if self.network_creator:
1791 self.network_creator.clean()
1792 except Exception as e:
1793 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1795 if self.image_creators:
1797 while self.image_creators:
1798 self.image_creators[0].clean()
1799 self.image_creators.pop(0)
1800 except Exception as e:
1801 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1803 super(self.__class__, self).__clean__()
1805 def test_create_delete_instance_from_three_part_image(self):
1807 Tests the creation of an OpenStack instance from a 3-part image.
1809 instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1810 port_settings=[self.port_settings])
1812 # The last created image is the main image from which we create the instance
1813 self.inst_creator = OpenStackVmInstance(
1814 self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1816 vm_inst = self.inst_creator.create()
1817 self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1819 self.assertTrue(self.inst_creator.vm_active(block=True))
1822 nova_utils.delete_vm_instance(self.nova, vm_inst)
1824 self.assertTrue(self.inst_creator.vm_deleted(block=True))
1825 self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1827 # Exception should not be thrown
1828 self.inst_creator.clean()