Merge "Removed project query restriction when looking up network for port creation."
[snaps.git] / snaps / openstack / tests / create_instance_tests.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15 import logging
16 import re
17 import shutil
18 import time
19 import unittest
20 import uuid
21
22 import os
23 from neutronclient.common.exceptions import (
24     InvalidIpForSubnetClient, BadRequest)
25
26 from snaps import file_utils
27 from snaps.config.image import ImageConfig
28 from snaps.config.keypair import KeypairConfig
29 from snaps.config.network import PortConfig, NetworkConfig, SubnetConfig
30 from snaps.config.router import RouterConfig
31 from snaps.config.security_group import (
32     Protocol, SecurityGroupRuleConfig, Direction, SecurityGroupConfig)
33 from snaps.config.vm_inst import (
34     VmInstanceConfig, FloatingIpConfig,  VmInstanceConfigError,
35     FloatingIpConfigError)
36 from snaps.config.volume import VolumeConfig
37 from snaps.openstack import create_network, create_router, create_instance
38 from snaps.openstack.create_flavor import OpenStackFlavor
39 from snaps.openstack.create_image import OpenStackImage
40 from snaps.openstack.create_instance import (
41     VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings)
42 from snaps.openstack.create_keypairs import OpenStackKeypair
43 from snaps.openstack.create_network import OpenStackNetwork
44 from snaps.openstack.create_router import OpenStackRouter
45 from snaps.openstack.create_security_group import OpenStackSecurityGroup
46 from snaps.openstack.create_volume import OpenStackVolume
47 from snaps.openstack.tests import openstack_tests, validation_utils
48 from snaps.openstack.tests.os_source_file_test import (
49     OSIntegrationTestCase, OSComponentTestCase)
50 from snaps.openstack.utils import nova_utils, keystone_utils, neutron_utils
51 from snaps.openstack.utils.nova_utils import RebootType
52 from snaps.openstack.utils import nova_utils, settings_utils, neutron_utils
53
54 __author__ = 'spisarski'
55
56 VM_BOOT_TIMEOUT = 600
57
58 logger = logging.getLogger('create_instance_tests')
59
60
61 class VmInstanceSettingsUnitTests(unittest.TestCase):
62     """
63     Tests the construction of the VmInstanceSettings class
64     """
65
66     def test_no_params(self):
67         with self.assertRaises(VmInstanceConfigError):
68             VmInstanceSettings()
69
70     def test_empty_config(self):
71         with self.assertRaises(VmInstanceConfigError):
72             VmInstanceSettings(config=dict())
73
74     def test_name_only(self):
75         with self.assertRaises(VmInstanceConfigError):
76             VmInstanceSettings(name='foo')
77
78     def test_config_with_name_only(self):
79         with self.assertRaises(VmInstanceConfigError):
80             VmInstanceSettings(config={'name': 'foo'})
81
82     def test_name_flavor_only(self):
83         with self.assertRaises(VmInstanceConfigError):
84             VmInstanceSettings(name='foo', flavor='bar')
85
86     def test_config_with_name_flavor_only(self):
87         with self.assertRaises(VmInstanceConfigError):
88             VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
89
90     def test_name_flavor_port_only(self):
91         port_settings = PortConfig(name='foo-port', network_name='bar-net')
92         settings = VmInstanceSettings(name='foo', flavor='bar',
93                                       port_settings=[port_settings])
94         self.assertEqual('foo', settings.name)
95         self.assertEqual('bar', settings.flavor)
96         self.assertEqual(1, len(settings.port_settings))
97         self.assertEqual('foo-port', settings.port_settings[0].name)
98         self.assertEqual('bar-net', settings.port_settings[0].network_name)
99         self.assertEqual(0, len(settings.security_group_names))
100         self.assertEqual(0, len(settings.floating_ip_settings))
101         self.assertIsNone(settings.sudo_user)
102         self.assertEqual(900, settings.vm_boot_timeout)
103         self.assertEqual(300, settings.vm_delete_timeout)
104         self.assertEqual(180, settings.ssh_connect_timeout)
105         self.assertIsNone(settings.availability_zone)
106         self.assertIsNone(settings.volume_names)
107
108     def test_config_with_name_flavor_port_only(self):
109         port_settings = PortConfig(name='foo-port', network_name='bar-net')
110         settings = VmInstanceSettings(
111             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
112         self.assertEqual('foo', settings.name)
113         self.assertEqual('bar', settings.flavor)
114         self.assertEqual(1, len(settings.port_settings))
115         self.assertEqual('foo-port', settings.port_settings[0].name)
116         self.assertEqual('bar-net', settings.port_settings[0].network_name)
117         self.assertEqual(0, len(settings.security_group_names))
118         self.assertEqual(0, len(settings.floating_ip_settings))
119         self.assertIsNone(settings.sudo_user)
120         self.assertEqual(900, settings.vm_boot_timeout)
121         self.assertEqual(300, settings.vm_delete_timeout)
122         self.assertEqual(180, settings.ssh_connect_timeout)
123         self.assertIsNone(settings.availability_zone)
124         self.assertIsNone(settings.volume_names)
125
126     def test_all(self):
127         port_settings = PortConfig(name='foo-port', network_name='bar-net')
128         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
129                                           router_name='foo-bar-router')
130
131         settings = VmInstanceSettings(
132             name='foo', flavor='bar', port_settings=[port_settings],
133             security_group_names=['sec_grp_1'],
134             floating_ip_settings=[fip_settings], sudo_user='joe',
135             vm_boot_timeout=999, vm_delete_timeout=333,
136             ssh_connect_timeout=111, availability_zone='server name',
137             volume_names=['vol1'])
138         self.assertEqual('foo', settings.name)
139         self.assertEqual('bar', settings.flavor)
140         self.assertEqual(1, len(settings.port_settings))
141         self.assertEqual('foo-port', settings.port_settings[0].name)
142         self.assertEqual('bar-net', settings.port_settings[0].network_name)
143         self.assertEqual(1, len(settings.security_group_names))
144         self.assertEqual('sec_grp_1', settings.security_group_names[0])
145         self.assertEqual(1, len(settings.floating_ip_settings))
146         self.assertEqual('foo-fip', settings.floating_ip_settings[0].name)
147         self.assertEqual('bar-port',
148                          settings.floating_ip_settings[0].port_name)
149         self.assertEqual('foo-bar-router',
150                          settings.floating_ip_settings[0].router_name)
151         self.assertEqual('joe', settings.sudo_user)
152         self.assertEqual(999, settings.vm_boot_timeout)
153         self.assertEqual(333, settings.vm_delete_timeout)
154         self.assertEqual(111, settings.ssh_connect_timeout)
155         self.assertEqual('server name', settings.availability_zone)
156         self.assertEqual('vol1', settings.volume_names[0])
157
158     def test_config_all(self):
159         port_settings = PortConfig(name='foo-port', network_name='bar-net')
160         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
161                                           router_name='foo-bar-router')
162
163         settings = VmInstanceSettings(
164             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings],
165                'security_group_names': ['sec_grp_1'],
166                'floating_ips': [fip_settings], 'sudo_user': 'joe',
167                'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
168                'ssh_connect_timeout': 111, 'availability_zone': 'server name',
169                'volume_names': ['vol2']})
170         self.assertEqual('foo', settings.name)
171         self.assertEqual('bar', settings.flavor)
172         self.assertEqual(1, len(settings.port_settings))
173         self.assertEqual('foo-port', settings.port_settings[0].name)
174         self.assertEqual('bar-net', settings.port_settings[0].network_name)
175         self.assertEqual(1, len(settings.security_group_names))
176         self.assertEqual(1, len(settings.floating_ip_settings))
177         self.assertEqual('foo-fip', settings.floating_ip_settings[0].name)
178         self.assertEqual('bar-port',
179                          settings.floating_ip_settings[0].port_name)
180         self.assertEqual('foo-bar-router',
181                          settings.floating_ip_settings[0].router_name)
182         self.assertEqual('joe', settings.sudo_user)
183         self.assertEqual(999, settings.vm_boot_timeout)
184         self.assertEqual(333, settings.vm_delete_timeout)
185         self.assertEqual(111, settings.ssh_connect_timeout)
186         self.assertEqual('server name', settings.availability_zone)
187         self.assertEqual('vol2', settings.volume_names[0])
188
189
190 class FloatingIpSettingsUnitTests(unittest.TestCase):
191     """
192     Tests the construction of the FloatingIpSettings class
193     """
194
195     def test_no_params(self):
196         with self.assertRaises(FloatingIpConfigError):
197             FloatingIpSettings()
198
199     def test_empty_config(self):
200         with self.assertRaises(FloatingIpConfigError):
201             FloatingIpSettings(**dict())
202
203     def test_name_only(self):
204         with self.assertRaises(FloatingIpConfigError):
205             FloatingIpSettings(name='foo')
206
207     def test_config_with_name_only(self):
208         with self.assertRaises(FloatingIpConfigError):
209             FloatingIpSettings(**{'name': 'foo'})
210
211     def test_name_port_only(self):
212         with self.assertRaises(FloatingIpConfigError):
213             FloatingIpSettings(name='foo', port_name='bar')
214
215     def test_config_with_name_port_only(self):
216         with self.assertRaises(FloatingIpConfigError):
217             FloatingIpSettings(**{'name': 'foo', 'port_name': 'bar'})
218
219     def test_name_router_only(self):
220         with self.assertRaises(FloatingIpConfigError):
221             FloatingIpSettings(name='foo', router_name='bar')
222
223     def test_config_with_name_router_only(self):
224         with self.assertRaises(FloatingIpConfigError):
225             FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'})
226
227     def test_name_port_router_name_only(self):
228         settings = FloatingIpSettings(name='foo', port_name='foo-port',
229                                       router_name='bar-router')
230         self.assertEqual('foo', settings.name)
231         self.assertEqual('foo-port', settings.port_name)
232         self.assertIsNone(settings.port_id)
233         self.assertEqual('bar-router', settings.router_name)
234         self.assertIsNone(settings.subnet_name)
235         self.assertTrue(settings.provisioning)
236
237     def test_name_port_router_id_only(self):
238         settings = FloatingIpSettings(name='foo', port_id='foo-port',
239                                       router_name='bar-router')
240         self.assertEqual('foo', settings.name)
241         self.assertEqual('foo-port', settings.port_id)
242         self.assertIsNone(settings.port_name)
243         self.assertEqual('bar-router', settings.router_name)
244         self.assertIsNone(settings.subnet_name)
245         self.assertTrue(settings.provisioning)
246
247     def test_config_with_name_port_router_only(self):
248         settings = FloatingIpSettings(
249             **{'name': 'foo', 'port_name': 'foo-port',
250                'router_name': 'bar-router'})
251         self.assertEqual('foo', settings.name)
252         self.assertEqual('foo-port', settings.port_name)
253         self.assertIsNone(settings.port_id)
254         self.assertEqual('bar-router', settings.router_name)
255         self.assertIsNone(settings.subnet_name)
256         self.assertTrue(settings.provisioning)
257
258     def test_all(self):
259         settings = FloatingIpSettings(name='foo', port_name='foo-port',
260                                       router_name='bar-router',
261                                       subnet_name='bar-subnet',
262                                       provisioning=False)
263         self.assertEqual('foo', settings.name)
264         self.assertEqual('foo-port', settings.port_name)
265         self.assertIsNone(settings.port_id)
266         self.assertEqual('bar-router', settings.router_name)
267         self.assertEqual('bar-subnet', settings.subnet_name)
268         self.assertFalse(settings.provisioning)
269
270     def test_config_all(self):
271         settings = FloatingIpSettings(
272             **{'name': 'foo', 'port_name': 'foo-port',
273                'router_name': 'bar-router', 'subnet_name': 'bar-subnet',
274                'provisioning': False})
275         self.assertEqual('foo', settings.name)
276         self.assertEqual('foo-port', settings.port_name)
277         self.assertIsNone(settings.port_id)
278         self.assertEqual('bar-router', settings.router_name)
279         self.assertEqual('bar-subnet', settings.subnet_name)
280         self.assertFalse(settings.provisioning)
281
282
283 class SimpleHealthCheck(OSIntegrationTestCase):
284     """
285     Test for the CreateInstance class with a single NIC/Port with Floating IPs
286     """
287
288     def setUp(self):
289         """
290         Instantiates the CreateImage object that is responsible for downloading
291         and creating an OS image file
292         within OpenStack
293         """
294         super(self.__class__, self).__start__()
295
296         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
297         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
298         self.vm_inst_name = guid + '-inst'
299         self.port_1_name = guid + 'port-1'
300
301         # Initialize for tearDown()
302         self.image_creator = None
303         self.network_creator = None
304         self.flavor_creator = None
305         self.inst_creator = None
306
307         self.priv_net_config = openstack_tests.get_priv_net_config(
308             project_name=self.os_creds.project_name,
309             net_name=guid + '-priv-net',
310             subnet_name=guid + '-priv-subnet',
311             netconf_override=self.netconf_override)
312         self.port_settings = PortConfig(
313             name=self.port_1_name,
314             network_name=self.priv_net_config.network_settings.name)
315
316         # Create Image
317         # Set the default image settings, then set any custom parameters sent
318         # from the app
319         os_image_settings = openstack_tests.cirros_image_settings(
320             name=guid + '-image', image_metadata=self.image_metadata)
321
322         try:
323             self.image_creator = OpenStackImage(self.os_creds,
324                                                 os_image_settings)
325             self.image_creator.create()
326
327             # Create Network
328             self.network_creator = OpenStackNetwork(
329                 self.os_creds, self.priv_net_config.network_settings)
330             self.network_creator.create()
331
332             # Create Flavor
333             self.flavor_ram = 256
334             if (self.flavor_metadata and
335                self.flavor_metadata.get('hw:mem_page_size') == 'large'):
336                 self.flavor_ram = 1024
337             flavor_config = openstack_tests.get_flavor_config(
338                 name=guid + '-flavor-name', ram=self.flavor_ram, disk=10,
339                 vcpus=1, metadata=self.flavor_metadata)
340             self.flavor_creator = OpenStackFlavor(
341                 self.admin_os_creds, flavor_config)
342             self.flavor_creator.create()
343         except Exception as e:
344             self.tearDown()
345             raise e
346
347     def tearDown(self):
348         """
349         Cleans the created object
350         """
351         if self.inst_creator:
352             try:
353                 self.inst_creator.clean()
354             except Exception as e:
355                 logger.error(
356                     'Unexpected exception cleaning VM instance with message'
357                     ' - %s', e)
358
359         if self.network_creator:
360             try:
361                 self.network_creator.clean()
362             except Exception as e:
363                 logger.error(
364                     'Unexpected exception cleaning network with message - %s',
365                     e)
366
367         if self.flavor_creator:
368             try:
369                 self.flavor_creator.clean()
370             except Exception as e:
371                 logger.error(
372                     'Unexpected exception cleaning flavor with message - %s',
373                     e)
374
375         if self.image_creator and not self.image_creator.image_settings.exists:
376             try:
377                 self.image_creator.clean()
378             except Exception as e:
379                 logger.error(
380                     'Unexpected exception cleaning image with message - %s',
381                     e)
382
383         super(self.__class__, self).__clean__()
384
385     def test_check_vm_ip_dhcp(self):
386         """
387         Tests the creation of an OpenStack instance with a single port and
388         ensures that it's assigned IP address is the actual.
389         """
390         instance_settings = VmInstanceConfig(
391             name=self.vm_inst_name,
392             flavor=self.flavor_creator.flavor_settings.name,
393             port_settings=[self.port_settings])
394
395         self.inst_creator = OpenStackVmInstance(
396             self.os_creds, instance_settings,
397             self.image_creator.image_settings)
398         self.inst_creator.create()
399
400         ip = self.inst_creator.get_port_ip(self.port_settings.name)
401         self.assertIsNotNone(ip)
402
403         self.assertTrue(self.inst_creator.vm_active(block=True))
404
405         self.assertTrue(check_dhcp_lease(self.inst_creator, ip))
406
407
408 class CreateInstanceSimpleTests(OSIntegrationTestCase):
409     """
410     Simple instance creation tests without any other objects
411     """
412
413     def setUp(self):
414         """
415         Setup the objects required for the test
416         """
417         super(self.__class__, self).__start__()
418
419         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
420         self.vm_inst_name = self.guid + '-inst'
421         self.nova = nova_utils.nova_client(self.os_creds)
422         self.neutron = neutron_utils.neutron_client(self.os_creds)
423         os_image_settings = openstack_tests.cirros_image_settings(
424             name=self.guid + '-image', image_metadata=self.image_metadata)
425
426         # Initialize for tearDown()
427         self.image_creator = None
428         self.flavor_creator = None
429
430         self.network_creator = None
431         self.inst_creator = None
432
433         try:
434             # Create Image
435             self.image_creator = OpenStackImage(self.os_creds,
436                                                 os_image_settings)
437             self.image_creator.create()
438
439             # Create Flavor
440             flavor_config = openstack_tests.get_flavor_config(
441                 name=self.guid + '-flavor-name', ram=256, disk=10,
442                 vcpus=2, metadata=self.flavor_metadata)
443             self.flavor_creator = OpenStackFlavor(
444                 self.admin_os_creds, flavor_config)
445             self.flavor_creator.create()
446             self.network_creator = None
447         except Exception as e:
448             self.tearDown()
449             raise e
450
451     def tearDown(self):
452         """
453         Cleans the created object
454         """
455         if self.inst_creator:
456             try:
457                 self.inst_creator.clean()
458             except Exception as e:
459                 logger.error(
460                     'Unexpected exception cleaning VM instance with message '
461                     '- %s', e)
462
463         if self.flavor_creator:
464             try:
465                 self.flavor_creator.clean()
466             except Exception as e:
467                 logger.error(
468                     'Unexpected exception cleaning flavor with message - %s',
469                     e)
470
471         if self.network_creator:
472             try:
473                 self.network_creator.clean()
474             except Exception as e:
475                 logger.error(
476                     'Unexpected exception cleaning network with message - %s',
477                     e)
478
479         if self.image_creator and not self.image_creator.image_settings.exists:
480             try:
481                 self.image_creator.clean()
482             except Exception as e:
483                 logger.error(
484                     'Unexpected exception cleaning image with message - %s', e)
485
486         super(self.__class__, self).__clean__()
487
488     def test_create_delete_instance(self):
489         """
490         Tests the creation of an OpenStack instance with a single port with a
491         static IP without a Floating IP.
492         """
493         # Create Network
494         net_config = openstack_tests.get_priv_net_config(
495             project_name=self.os_creds.project_name,
496             net_name=self.guid + '-pub-net',
497             subnet_name=self.guid + '-pub-subnet',
498             router_name=self.guid + '-pub-router',
499             external_net=self.ext_net_name,
500             netconf_override=self.netconf_override)
501         self.network_creator = OpenStackNetwork(
502             self.os_creds, net_config.network_settings)
503         self.network_creator.create()
504
505         self.port_settings = PortConfig(
506             name=self.guid + '-port',
507             network_name=net_config.network_settings.name)
508
509         instance_settings = VmInstanceConfig(
510             name=self.vm_inst_name,
511             flavor=self.flavor_creator.flavor_settings.name,
512             port_settings=[self.port_settings])
513
514         self.inst_creator = OpenStackVmInstance(
515             self.os_creds, instance_settings,
516             self.image_creator.image_settings)
517
518         vm_inst = self.inst_creator.create(block=True)
519         vm_inst_get = nova_utils.get_server(
520             self.nova, self.neutron, self.keystone,
521             vm_inst_settings=instance_settings)
522         self.assertEqual(vm_inst, vm_inst_get)
523
524         self.assertIsNotNone(self.inst_creator.get_vm_inst().availability_zone)
525         self.assertIsNone(self.inst_creator.get_vm_inst().compute_host)
526
527         # Delete instance
528         nova_utils.delete_vm_instance(self.nova, vm_inst)
529
530         self.assertTrue(self.inst_creator.vm_deleted(block=True))
531         self.assertIsNone(nova_utils.get_server(
532             self.nova, self.neutron, self.keystone,
533             vm_inst_settings=instance_settings))
534
535         # Exception should not be thrown
536         self.inst_creator.clean()
537
538     def test_create_admin_instance(self):
539         """
540         Tests the creation of an OpenStack instance with a single port with a
541         static IP without a Floating IP.
542         """
543         # Create Network
544         net_config = openstack_tests.get_priv_net_config(
545             project_name=self.os_creds.project_name,
546             net_name=self.guid + '-pub-net',
547             subnet_name=self.guid + '-pub-subnet',
548             router_name=self.guid + '-pub-router',
549             external_net=self.ext_net_name,
550             netconf_override=self.netconf_override)
551         self.network_creator = OpenStackNetwork(
552             self.admin_os_creds, net_config.network_settings)
553         self.network_creator.create()
554
555         self.port_settings = PortConfig(
556             name=self.guid + '-port',
557             network_name=net_config.network_settings.name)
558
559         instance_settings = VmInstanceConfig(
560             name=self.vm_inst_name,
561             flavor=self.flavor_creator.flavor_settings.name,
562             port_settings=[self.port_settings])
563
564         self.inst_creator = OpenStackVmInstance(
565             self.admin_os_creds, instance_settings,
566             self.image_creator.image_settings)
567
568         admin_nova = nova_utils.nova_client(self.admin_os_creds)
569         admin_neutron = neutron_utils.neutron_client(self.admin_os_creds)
570         admin_key = keystone_utils.keystone_client(self.admin_os_creds)
571         vm_inst = self.inst_creator.create(block=True)
572
573         self.assertIsNotNone(vm_inst)
574         vm_inst_get = nova_utils.get_server(
575             admin_nova, admin_neutron, admin_key,
576             vm_inst_settings=instance_settings)
577         self.assertEqual(vm_inst, vm_inst_get)
578
579         self.assertIsNone(nova_utils.get_server(
580             self.nova, self.neutron, self.keystone,
581             vm_inst_settings=instance_settings))
582
583         self.assertIsNotNone(self.inst_creator.get_vm_inst().availability_zone)
584         self.assertIsNotNone(self.inst_creator.get_vm_inst().compute_host)
585
586
587 class CreateInstanceExternalNetTests(OSIntegrationTestCase):
588     """
589     Simple instance creation tests where the network is external
590     """
591
592     def setUp(self):
593         """
594         Instantiates the CreateImage object that is responsible for downloading
595         and creating an OS image file
596         within OpenStack
597         """
598         super(self.__class__, self).__start__()
599
600         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
601         self.vm_inst_name = guid + '-inst'
602         self.nova = nova_utils.nova_client(self.admin_os_creds)
603         self.neutron = neutron_utils.neutron_client(self.admin_os_creds)
604         os_image_settings = openstack_tests.cirros_image_settings(
605             name=guid + '-image', image_metadata=self.image_metadata)
606
607         # Initialize for tearDown()
608         self.image_creator = None
609         self.flavor_creator = None
610         self.inst_creator = None
611
612         try:
613             # Create Image
614             self.image_creator = OpenStackImage(self.os_creds,
615                                                 os_image_settings)
616             self.image_creator.create()
617
618             # Create Flavor
619             flavor_config = openstack_tests.get_flavor_config(
620                 name=guid + '-flavor-name', ram=256, disk=10,
621                 vcpus=2, metadata=self.flavor_metadata)
622             self.flavor_creator = OpenStackFlavor(
623                 self.admin_os_creds, flavor_config)
624             self.flavor_creator.create()
625
626             self.port_settings = PortConfig(
627                 name=guid + '-port',
628                 network_name=self.ext_net_name)
629
630         except Exception as e:
631             self.tearDown()
632             raise e
633
634     def tearDown(self):
635         """
636         Cleans the created object
637         """
638         if self.inst_creator:
639             try:
640                 self.inst_creator.clean()
641             except Exception as e:
642                 logger.error(
643                     'Unexpected exception cleaning VM instance with message '
644                     '- %s', e)
645
646         if self.flavor_creator:
647             try:
648                 self.flavor_creator.clean()
649             except Exception as e:
650                 logger.error(
651                     'Unexpected exception cleaning flavor with message - %s',
652                     e)
653
654         if self.image_creator and not self.image_creator.image_settings.exists:
655             try:
656                 self.image_creator.clean()
657             except Exception as e:
658                 logger.error(
659                     'Unexpected exception cleaning image with message - %s', e)
660
661         super(self.__class__, self).__clean__()
662
663     def test_create_instance_public_net(self):
664         """
665         Tests the creation of an OpenStack instance with a single port to
666         the external network.
667         """
668         instance_settings = VmInstanceConfig(
669             name=self.vm_inst_name,
670             flavor=self.flavor_creator.flavor_settings.name,
671             port_settings=[self.port_settings])
672
673         self.inst_creator = OpenStackVmInstance(
674             self.admin_os_creds, instance_settings,
675             self.image_creator.image_settings)
676
677         vm_inst = self.inst_creator.create(block=True)
678         vm_inst_get = nova_utils.get_server(
679             self.nova, self.neutron, self.keystone,
680             vm_inst_settings=instance_settings)
681         self.assertEqual(vm_inst, vm_inst_get)
682         ip = self.inst_creator.get_port_ip(self.port_settings.name)
683
684         check_dhcp_lease(self.inst_creator, ip)
685
686
687 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
688     """
689     Test for the CreateInstance class with a single NIC/Port with Floating IPs
690     """
691
692     def setUp(self):
693         """
694         Instantiates the CreateImage object that is responsible for downloading
695         and creating an OS image file within OpenStack
696         """
697         super(self.__class__, self).__start__()
698
699         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
700         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
701         self.keypair_priv_filepath = 'tmp/' + guid
702         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
703         self.keypair_name = guid + '-kp'
704         self.vm_inst_name = guid + '-inst'
705         self.port_1_name = guid + 'port-1'
706         self.port_2_name = guid + 'port-2'
707         self.floating_ip_name = guid + 'fip1'
708
709         # Initialize for tearDown()
710         self.image_creator = None
711         self.network_creator = None
712         self.router_creator = None
713         self.flavor_creator = None
714         self.keypair_creator = None
715         self.sec_grp_creator = None
716         self.inst_creators = list()
717
718         self.pub_net_config = openstack_tests.get_pub_net_config(
719             project_name=self.os_creds.project_name,
720             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
721             router_name=guid + '-pub-router', external_net=self.ext_net_name,
722             netconf_override=self.netconf_override)
723         os_image_settings = openstack_tests.cirros_image_settings(
724             name=guid + '-image', image_metadata=self.image_metadata)
725         try:
726             # Create Image
727             self.image_creator = OpenStackImage(self.os_creds,
728                                                 os_image_settings)
729             self.image_creator.create()
730
731             # Create Network
732             self.network_creator = OpenStackNetwork(
733                 self.os_creds, self.pub_net_config.network_settings)
734             self.network_creator.create()
735
736             # Create Router
737             self.router_creator = OpenStackRouter(
738                 self.os_creds, self.pub_net_config.router_settings)
739             self.router_creator.create()
740
741             # Create Flavor
742             flavor_config = openstack_tests.get_flavor_config(
743                 name=guid + '-flavor-name', ram=256, disk=10,
744                 vcpus=2, metadata=self.flavor_metadata)
745             self.flavor_creator = OpenStackFlavor(
746                 self.admin_os_creds, flavor_config)
747             self.flavor_creator.create()
748
749             self.keypair_creator = OpenStackKeypair(
750                 self.os_creds, KeypairConfig(
751                     name=self.keypair_name,
752                     public_filepath=self.keypair_pub_filepath,
753                     private_filepath=self.keypair_priv_filepath))
754             self.keypair_creator.create()
755
756             sec_grp_name = guid + '-sec-grp'
757             rule1 = SecurityGroupRuleConfig(
758                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
759                 protocol=Protocol.icmp)
760             rule2 = SecurityGroupRuleConfig(
761                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
762                 protocol=Protocol.tcp, port_range_min=22, port_range_max=22)
763             self.sec_grp_creator = OpenStackSecurityGroup(
764                 self.os_creds,
765                 SecurityGroupConfig(
766                     name=sec_grp_name, rule_settings=[rule1, rule2]))
767             self.sec_grp_creator.create()
768         except Exception as e:
769             self.tearDown()
770             raise e
771
772     def tearDown(self):
773         """
774         Cleans the created object
775         """
776         for inst_creator in self.inst_creators:
777             try:
778                 inst_creator.clean()
779             except Exception as e:
780                 logger.error(
781                     'Unexpected exception cleaning VM instance with message '
782                     '- %s', e)
783
784         if self.keypair_creator:
785             try:
786                 self.keypair_creator.clean()
787             except Exception as e:
788                 logger.error(
789                     'Unexpected exception cleaning keypair with message - %s',
790                     e)
791
792         if self.flavor_creator:
793             try:
794                 self.flavor_creator.clean()
795             except Exception as e:
796                 logger.error(
797                     'Unexpected exception cleaning flavor with message - %s',
798                     e)
799
800         if self.sec_grp_creator:
801             try:
802                 self.sec_grp_creator.clean()
803             except Exception as e:
804                 logger.error(
805                     'Unexpected exception cleaning security group with message'
806                     ' - %s', e)
807
808         if self.router_creator:
809             try:
810                 self.router_creator.clean()
811             except Exception as e:
812                 logger.error(
813                     'Unexpected exception cleaning router with message - %s',
814                     e)
815
816         if self.network_creator:
817             try:
818                 self.network_creator.clean()
819             except Exception as e:
820                 logger.error(
821                     'Unexpected exception cleaning network with message - %s',
822                     e)
823
824         if self.image_creator and not self.image_creator.image_settings.exists:
825             try:
826                 self.image_creator.clean()
827             except Exception as e:
828                 logger.error(
829                     'Unexpected exception cleaning image with message - %s', e)
830
831         super(self.__class__, self).__clean__()
832
833     def test_single_port_static(self):
834         """
835         Tests the creation of an OpenStack instance with a single port with a
836         static IP without a Floating IP.
837         """
838         ip_1 = '10.55.1.100'
839         sub_settings = self.pub_net_config.network_settings.subnet_settings
840         port_settings = PortConfig(
841             name=self.port_1_name,
842             network_name=self.pub_net_config.network_settings.name,
843             ip_addrs=[
844                 {'subnet_name': sub_settings[0].name, 'ip': ip_1}])
845
846         instance_settings = VmInstanceConfig(
847             name=self.vm_inst_name,
848             flavor=self.flavor_creator.flavor_settings.name,
849             port_settings=[port_settings],
850             floating_ip_settings=[FloatingIpConfig(
851                 name=self.floating_ip_name, port_name=self.port_1_name,
852                 router_name=self.pub_net_config.router_settings.name)])
853
854         inst_creator = OpenStackVmInstance(
855             self.os_creds, instance_settings,
856             self.image_creator.image_settings,
857             keypair_settings=self.keypair_creator.keypair_settings)
858         self.inst_creators.append(inst_creator)
859         vm_inst = inst_creator.create(block=True)
860
861         self.assertEqual(ip_1, inst_creator.get_port_ip(self.port_1_name))
862         self.assertTrue(inst_creator.vm_active(block=True))
863         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
864
865     def test_ssh_client_fip_before_active(self):
866         """
867         Tests the ability to access a VM via SSH and a floating IP when it has
868         been assigned prior to being active.
869         """
870         port_settings = PortConfig(
871             name=self.port_1_name,
872             network_name=self.pub_net_config.network_settings.name)
873
874         instance_settings = VmInstanceConfig(
875             name=self.vm_inst_name,
876             flavor=self.flavor_creator.flavor_settings.name,
877             port_settings=[port_settings],
878             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
879             floating_ip_settings=[FloatingIpConfig(
880                 name=self.floating_ip_name, port_name=self.port_1_name,
881                 router_name=self.pub_net_config.router_settings.name)])
882
883         inst_creator = OpenStackVmInstance(
884             self.os_creds, instance_settings,
885             self.image_creator.image_settings,
886             keypair_settings=self.keypair_creator.keypair_settings)
887         self.inst_creators.append(inst_creator)
888         vm_inst = inst_creator.create()
889         self.assertIsNotNone(vm_inst)
890
891         self.assertTrue(inst_creator.vm_active(block=True))
892
893         ip = inst_creator.get_port_ip(port_settings.name)
894         self.assertTrue(check_dhcp_lease(inst_creator, ip))
895
896         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
897
898         self.assertTrue(validate_ssh_client(inst_creator))
899
900     def test_ssh_client_fip_after_active(self):
901         """
902         Tests the ability to access a VM via SSH and a floating IP when it has
903         been assigned prior to being active.
904         """
905         port_settings = PortConfig(
906             name=self.port_1_name,
907             network_name=self.pub_net_config.network_settings.name)
908
909         instance_settings = VmInstanceConfig(
910             name=self.vm_inst_name,
911             flavor=self.flavor_creator.flavor_settings.name,
912             port_settings=[port_settings],
913             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
914             floating_ip_settings=[FloatingIpConfig(
915                 name=self.floating_ip_name, port_name=self.port_1_name,
916                 router_name=self.pub_net_config.router_settings.name)])
917
918         inst_creator = OpenStackVmInstance(
919             self.os_creds, instance_settings,
920             self.image_creator.image_settings,
921             keypair_settings=self.keypair_creator.keypair_settings)
922         self.inst_creators.append(inst_creator)
923
924         # block=True will force the create() method to block until the
925         vm_inst = inst_creator.create(block=True)
926         self.assertIsNotNone(vm_inst)
927
928         self.assertTrue(inst_creator.vm_active(block=True))
929
930         ip = inst_creator.get_port_ip(port_settings.name)
931         self.assertTrue(check_dhcp_lease(inst_creator, ip))
932
933         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
934
935         self.assertTrue(validate_ssh_client(inst_creator))
936
937     def test_ssh_client_fip_after_reboot(self):
938         """
939         Tests the ability to access a VM via SSH and a floating IP after it has
940         been rebooted.
941         """
942         port_settings = PortConfig(
943             name=self.port_1_name,
944             network_name=self.pub_net_config.network_settings.name)
945
946         instance_settings = VmInstanceConfig(
947             name=self.vm_inst_name,
948             flavor=self.flavor_creator.flavor_settings.name,
949             port_settings=[port_settings],
950             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
951             floating_ip_settings=[FloatingIpConfig(
952                 name=self.floating_ip_name, port_name=self.port_1_name,
953                 router_name=self.pub_net_config.router_settings.name)])
954
955         inst_creator = OpenStackVmInstance(
956             self.os_creds, instance_settings,
957             self.image_creator.image_settings,
958             keypair_settings=self.keypair_creator.keypair_settings)
959         self.inst_creators.append(inst_creator)
960
961         # block=True will force the create() method to block until the
962         vm_inst = inst_creator.create(block=True)
963         self.assertIsNotNone(vm_inst)
964
965         self.assertTrue(inst_creator.vm_active(block=True))
966
967         ip = inst_creator.get_port_ip(port_settings.name)
968         self.assertTrue(check_dhcp_lease(inst_creator, ip))
969
970         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
971
972         self.assertTrue(validate_ssh_client(inst_creator))
973
974         # Test default reboot which should be 'SOFT'
975         inst_creator.reboot()
976         # Lag time to allow for shutdown routine to take effect
977         time.sleep(15)
978         self.assertTrue(check_dhcp_lease(inst_creator, ip))
979         self.assertTrue(validate_ssh_client(inst_creator))
980
981         # Test 'SOFT' reboot
982         inst_creator.reboot(reboot_type=RebootType.soft)
983         time.sleep(15)
984         self.assertTrue(check_dhcp_lease(inst_creator, ip))
985         self.assertTrue(validate_ssh_client(inst_creator))
986
987         # Test 'HARD' reboot
988         inst_creator.reboot(reboot_type=RebootType.hard)
989         time.sleep(15)
990         self.assertTrue(check_dhcp_lease(inst_creator, ip))
991         self.assertTrue(validate_ssh_client(inst_creator))
992
993     def test_ssh_client_fip_after_init(self):
994         """
995         Tests the ability to assign a floating IP to an already initialized
996         OpenStackVmInstance object. After the floating IP has been allocated
997         and assigned, this test will ensure that it can be accessed via SSH.
998         """
999         port_settings = PortConfig(
1000             name=self.port_1_name,
1001             network_name=self.pub_net_config.network_settings.name)
1002
1003         instance_settings = VmInstanceConfig(
1004             name=self.vm_inst_name,
1005             flavor=self.flavor_creator.flavor_settings.name,
1006             port_settings=[port_settings],
1007             security_group_names=[self.sec_grp_creator.sec_grp_settings.name])
1008
1009         inst_creator = OpenStackVmInstance(
1010             self.os_creds, instance_settings,
1011             self.image_creator.image_settings,
1012             keypair_settings=self.keypair_creator.keypair_settings)
1013         self.inst_creators.append(inst_creator)
1014
1015         # block=True will force the create() method to block until the
1016         vm_inst = inst_creator.create(block=True)
1017         self.assertIsNotNone(vm_inst)
1018
1019         self.assertTrue(inst_creator.vm_active(block=True))
1020         ip = inst_creator.get_port_ip(port_settings.name)
1021         self.assertTrue(check_dhcp_lease(inst_creator, ip))
1022         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
1023
1024         inst_creator.add_floating_ip(FloatingIpConfig(
1025             name=self.floating_ip_name, port_name=self.port_1_name,
1026             router_name=self.pub_net_config.router_settings.name))
1027
1028         self.assertTrue(validate_ssh_client(inst_creator))
1029
1030     def test_ssh_client_fip_reverse_engineer(self):
1031         """
1032         Tests the ability to assign a floating IP to a reverse engineered
1033         OpenStackVmInstance object. After the floating IP has been allocated
1034         and assigned, this test will ensure that it can be accessed via SSH.
1035         """
1036         port_settings = PortConfig(
1037             name=self.port_1_name,
1038             network_name=self.pub_net_config.network_settings.name)
1039
1040         instance_settings = VmInstanceConfig(
1041             name=self.vm_inst_name,
1042             flavor=self.flavor_creator.flavor_settings.name,
1043             port_settings=[port_settings],
1044             security_group_names=[self.sec_grp_creator.sec_grp_settings.name])
1045
1046         inst_creator = OpenStackVmInstance(
1047             self.os_creds, instance_settings,
1048             self.image_creator.image_settings,
1049             keypair_settings=self.keypair_creator.keypair_settings)
1050         self.inst_creators.append(inst_creator)
1051
1052         # block=True will force the create() method to block until the
1053         vm_inst = inst_creator.create(block=True)
1054         self.assertIsNotNone(vm_inst)
1055
1056         self.assertTrue(inst_creator.vm_active(block=True))
1057
1058         derived_inst_creator = create_instance.generate_creator(
1059             self.os_creds, vm_inst, self.image_creator.image_settings,
1060             self.os_creds.project_name, self.keypair_creator.keypair_settings)
1061
1062         derived_inst_creator.add_floating_ip(FloatingIpConfig(
1063             name=self.floating_ip_name, port_name=self.port_1_name,
1064             router_name=self.pub_net_config.router_settings.name))
1065         self.inst_creators.append(derived_inst_creator)
1066
1067         self.assertTrue(validate_ssh_client(
1068             derived_inst_creator, fip_name=self.floating_ip_name))
1069
1070     def test_ssh_client_fip_second_creator(self):
1071         """
1072         Tests the ability to access a VM via SSH and a floating IP via a
1073         creator that is identical to the original creator.
1074         """
1075         port_settings = PortConfig(
1076             name=self.port_1_name,
1077             network_name=self.pub_net_config.network_settings.name)
1078
1079         instance_settings = VmInstanceConfig(
1080             name=self.vm_inst_name,
1081             flavor=self.flavor_creator.flavor_settings.name,
1082             port_settings=[port_settings],
1083             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
1084             floating_ip_settings=[FloatingIpConfig(
1085                 name=self.floating_ip_name, port_name=self.port_1_name,
1086                 router_name=self.pub_net_config.router_settings.name)])
1087
1088         inst_creator = OpenStackVmInstance(
1089             self.os_creds, instance_settings,
1090             self.image_creator.image_settings,
1091             keypair_settings=self.keypair_creator.keypair_settings)
1092         self.inst_creators.append(inst_creator)
1093
1094         # block=True will force the create() method to block until the
1095         vm_inst = inst_creator.create(block=True)
1096         self.assertIsNotNone(vm_inst)
1097
1098         self.assertTrue(inst_creator.vm_active(block=True))
1099
1100         ip = inst_creator.get_port_ip(port_settings.name)
1101         self.assertTrue(check_dhcp_lease(inst_creator, ip))
1102
1103         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
1104
1105         self.assertTrue(validate_ssh_client(inst_creator))
1106
1107         inst_creator2 = OpenStackVmInstance(
1108             self.os_creds, instance_settings,
1109             self.image_creator.image_settings,
1110             keypair_settings=self.keypair_creator.keypair_settings)
1111         inst_creator2.create()
1112         self.assertTrue(validate_ssh_client(inst_creator2))
1113
1114
1115 class CreateInstanceIPv6NetworkTests(OSIntegrationTestCase):
1116     """
1117     Test for the CreateInstance class with a single NIC/Port with Floating IPs
1118     """
1119
1120     def setUp(self):
1121         """
1122         Instantiates the CreateImage object that is responsible for downloading
1123         and creating an OS image file within OpenStack
1124         """
1125         super(self.__class__, self).__start__()
1126
1127         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
1128         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1129         self.keypair_priv_filepath = 'tmp/' + self.guid
1130         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1131         self.keypair_name = self.guid + '-kp'
1132         self.vm_inst_name = self.guid + '-inst'
1133         self.port1_name = self.guid + 'port1'
1134         self.port2_name = self.guid + 'port2'
1135
1136         # Initialize for tearDown()
1137         self.image_creator = None
1138         self.network_creator = None
1139         self.router_creator = None
1140         self.flavor_creator = None
1141         self.keypair_creator = None
1142         self.sec_grp_creator = None
1143         self.inst_creator = None
1144
1145         os_image_settings = openstack_tests.cirros_image_settings(
1146             name=self.guid + '-image', image_metadata=self.image_metadata)
1147         try:
1148             self.image_creator = OpenStackImage(
1149                 self.os_creds, os_image_settings)
1150             self.image_creator.create()
1151
1152             flavor_config = openstack_tests.get_flavor_config(
1153                 name=self.guid + '-flavor-name', ram=256, disk=10,
1154                 vcpus=2, metadata=self.flavor_metadata)
1155             self.flavor_creator = OpenStackFlavor(
1156                 self.admin_os_creds, flavor_config)
1157             self.flavor_creator.create()
1158
1159             self.keypair_creator = OpenStackKeypair(
1160                 self.os_creds, KeypairConfig(
1161                     name=self.keypair_name,
1162                     public_filepath=self.keypair_pub_filepath,
1163                     private_filepath=self.keypair_priv_filepath))
1164             self.keypair_creator.create()
1165
1166             sec_grp_name = self.guid + '-sec-grp'
1167             rule1 = SecurityGroupRuleConfig(
1168                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
1169                 protocol=Protocol.icmp)
1170             rule2 = SecurityGroupRuleConfig(
1171                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
1172                 protocol=Protocol.tcp, port_range_min=22, port_range_max=22)
1173             self.sec_grp_creator = OpenStackSecurityGroup(
1174                 self.os_creds,
1175                 SecurityGroupConfig(
1176                     name=sec_grp_name, rule_settings=[rule1, rule2]))
1177             self.sec_grp_creator.create()
1178         except Exception as e:
1179             self.tearDown()
1180             raise e
1181
1182     def tearDown(self):
1183         """
1184         Cleans the created object
1185         """
1186         if self.inst_creator:
1187             try:
1188                 self.inst_creator.clean()
1189             except Exception as e:
1190                 logger.error(
1191                     'Unexpected exception cleaning VM instance with message '
1192                     '- %s', e)
1193
1194         if self.keypair_creator:
1195             try:
1196                 self.keypair_creator.clean()
1197             except Exception as e:
1198                 logger.error(
1199                     'Unexpected exception cleaning keypair with message - %s',
1200                     e)
1201
1202         if self.flavor_creator:
1203             try:
1204                 self.flavor_creator.clean()
1205             except Exception as e:
1206                 logger.error(
1207                     'Unexpected exception cleaning flavor with message - %s',
1208                     e)
1209
1210         if self.sec_grp_creator:
1211             try:
1212                 self.sec_grp_creator.clean()
1213             except Exception as e:
1214                 logger.error(
1215                     'Unexpected exception cleaning security group with message'
1216                     ' - %s', e)
1217
1218         if self.router_creator:
1219             try:
1220                 self.router_creator.clean()
1221             except Exception as e:
1222                 logger.error(
1223                     'Unexpected exception cleaning router with message - %s',
1224                     e)
1225
1226         if self.network_creator:
1227             try:
1228                 self.network_creator.clean()
1229             except Exception as e:
1230                 logger.error(
1231                     'Unexpected exception cleaning network with message - %s',
1232                     e)
1233
1234         if self.image_creator and not self.image_creator.image_settings.exists:
1235             try:
1236                 self.image_creator.clean()
1237             except Exception as e:
1238                 logger.error(
1239                     'Unexpected exception cleaning image with message - %s', e)
1240
1241         super(self.__class__, self).__clean__()
1242
1243     def test_v4fip_v6overlay(self):
1244         """
1245         Tests the ability to assign an IPv4 floating IP to an IPv6 overlay
1246         network when the external network does not have an IPv6 subnet.
1247         """
1248         subnet_settings = SubnetConfig(
1249             name=self.guid + '-subnet', cidr='1:1:0:0:0:0:0:0/64',
1250             ip_version=6)
1251         network_settings = NetworkConfig(
1252             name=self.guid + '-net', subnet_settings=[subnet_settings])
1253         router_settings = RouterConfig(
1254             name=self.guid + '-router', external_gateway=self.ext_net_name,
1255             internal_subnets=[{'subnet': {
1256                 'project_name': self.os_creds.project_name,
1257                 'network_name': network_settings.name,
1258                 'subnet_name': subnet_settings.name}}])
1259
1260         # Create Network
1261         self.network_creator = OpenStackNetwork(
1262             self.os_creds, network_settings)
1263         self.network_creator.create()
1264
1265         # Create Router
1266         self.router_creator = OpenStackRouter(
1267             self.os_creds, router_settings)
1268         self.router_creator.create()
1269
1270         port_settings = PortConfig(
1271             name=self.port1_name, network_name=network_settings.name)
1272
1273         instance_settings = VmInstanceConfig(
1274             name=self.vm_inst_name,
1275             flavor=self.flavor_creator.flavor_settings.name,
1276             port_settings=[port_settings],
1277             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
1278             floating_ip_settings=[FloatingIpConfig(
1279                 name='fip1', port_name=self.port1_name,
1280                 router_name=router_settings.name)])
1281
1282         self.inst_creator = OpenStackVmInstance(
1283             self.os_creds, instance_settings,
1284             self.image_creator.image_settings,
1285             keypair_settings=self.keypair_creator.keypair_settings)
1286
1287         with self.assertRaises(BadRequest):
1288             self.inst_creator.create(block=True)
1289
1290     def test_fip_v4and6_overlay(self):
1291         """
1292         Tests the ability to assign an IPv4 floating IP to an IPv6 overlay
1293         network when the external network does not have an IPv6 subnet.
1294         """
1295         subnet4_settings = SubnetConfig(
1296             name=self.guid + '-subnet4', cidr='10.0.1.0/24',
1297             ip_version=4)
1298         subnet6_settings = SubnetConfig(
1299             name=self.guid + '-subnet6', cidr='1:1:0:0:0:0:0:0/64',
1300             ip_version=6)
1301         network_settings = NetworkConfig(
1302             name=self.guid + '-net',
1303             subnet_settings=[subnet4_settings, subnet6_settings])
1304         router_settings = RouterConfig(
1305             name=self.guid + '-router', external_gateway=self.ext_net_name,
1306             internal_subnets=[{'subnet': {
1307                 'project_name': self.os_creds.project_name,
1308                 'network_name': network_settings.name,
1309                 'subnet_name': subnet4_settings.name}}])
1310
1311         # Create Network
1312         self.network_creator = OpenStackNetwork(
1313             self.os_creds, network_settings)
1314         self.network_creator.create()
1315
1316         # Create Router
1317         self.router_creator = OpenStackRouter(
1318             self.os_creds, router_settings)
1319         self.router_creator.create()
1320
1321         port_settings = PortConfig(
1322             name=self.port1_name, network_name=network_settings.name)
1323
1324         instance_settings = VmInstanceConfig(
1325             name=self.vm_inst_name,
1326             flavor=self.flavor_creator.flavor_settings.name,
1327             port_settings=[port_settings],
1328             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
1329             floating_ip_settings=[FloatingIpConfig(
1330                 name='fip1', port_name=self.port1_name,
1331                 router_name=router_settings.name)])
1332
1333         self.inst_creator = OpenStackVmInstance(
1334             self.os_creds, instance_settings,
1335             self.image_creator.image_settings,
1336             keypair_settings=self.keypair_creator.keypair_settings)
1337
1338         self.inst_creator.create(block=True)
1339         ssh_client = self.inst_creator.ssh_client()
1340         self.assertIsNotNone(ssh_client)
1341
1342
1343 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
1344     """
1345     Test for the CreateInstance class with a single NIC/Port where mac and IP
1346     values are manually set
1347     """
1348
1349     def setUp(self):
1350         """
1351         Instantiates the CreateImage object that is responsible for downloading
1352         and creating an OS image file within OpenStack
1353         """
1354         super(self.__class__, self).__start__()
1355
1356         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1357         self.vm_inst_name = self.guid + '-inst'
1358         self.port_1_name = self.guid + 'port-1'
1359         self.port_2_name = self.guid + 'port-2'
1360         self.floating_ip_name = self.guid + 'fip1'
1361
1362         # Initialize for tearDown()
1363         self.image_creator = None
1364         self.network_creator = None
1365         self.network_creator2 = None
1366         self.flavor_creator = None
1367         self.inst_creator = None
1368
1369         self.net_config = openstack_tests.get_priv_net_config(
1370             project_name=self.os_creds.project_name,
1371             net_name=self.guid + '-pub-net',
1372             subnet_name=self.guid + '-pub-subnet',
1373             router_name=self.guid + '-pub-router',
1374             external_net=self.ext_net_name,
1375             netconf_override=self.netconf_override)
1376         os_image_settings = openstack_tests.cirros_image_settings(
1377             name=self.guid + '-image', image_metadata=self.image_metadata)
1378
1379         try:
1380             # Create Image
1381             self.image_creator = OpenStackImage(self.os_creds,
1382                                                 os_image_settings)
1383             self.image_creator.create()
1384
1385             # Create Network
1386             self.network_creator = OpenStackNetwork(
1387                 self.os_creds, self.net_config.network_settings)
1388             self.network_creator.create()
1389
1390             # Create Flavor
1391             flavor_config = openstack_tests.get_flavor_config(
1392                 name=self.guid + '-flavor-name', ram=256, disk=10,
1393                 vcpus=2, metadata=self.flavor_metadata)
1394             self.flavor_creator = OpenStackFlavor(
1395                 self.admin_os_creds, flavor_config)
1396             self.flavor_creator.create()
1397         except Exception as e:
1398             self.tearDown()
1399             raise e
1400
1401     def tearDown(self):
1402         """
1403         Cleans the created object
1404         """
1405         if self.inst_creator:
1406             try:
1407                 self.inst_creator.clean()
1408             except Exception as e:
1409                 logger.error(
1410                     'Unexpected exception cleaning VM instance with message '
1411                     '- %s', e)
1412
1413         if self.flavor_creator:
1414             try:
1415                 self.flavor_creator.clean()
1416             except Exception as e:
1417                 logger.error(
1418                     'Unexpected exception cleaning flavor with message - %s',
1419                     e)
1420
1421         if self.network_creator:
1422             try:
1423                 self.network_creator.clean()
1424             except Exception as e:
1425                 logger.error(
1426                     'Unexpected exception cleaning network with message - %s',
1427                     e)
1428
1429         if self.image_creator and not self.image_creator.image_settings.exists:
1430             try:
1431                 self.image_creator.clean()
1432             except Exception as e:
1433                 logger.error(
1434                     'Unexpected exception cleaning image with message - %s', e)
1435
1436         super(self.__class__, self).__clean__()
1437
1438     def test_set_custom_valid_ip_one_subnet(self):
1439         """
1440         Tests the creation of an OpenStack instance with a single port with a
1441         static IP on a network with one subnet.
1442         """
1443         ip = '10.55.0.101'
1444         sub_settings = self.net_config.network_settings.subnet_settings
1445         port_settings = PortConfig(
1446             name=self.port_1_name,
1447             network_name=self.net_config.network_settings.name,
1448             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1449
1450         instance_settings = VmInstanceConfig(
1451             name=self.vm_inst_name,
1452             flavor=self.flavor_creator.flavor_settings.name,
1453             port_settings=[port_settings])
1454
1455         self.inst_creator = OpenStackVmInstance(
1456             self.os_creds, instance_settings,
1457             self.image_creator.image_settings)
1458         self.inst_creator.create(block=True)
1459
1460         self.assertEqual(ip, self.inst_creator.get_port_ip(
1461             self.port_1_name,
1462             subnet_name=self.net_config.network_settings.subnet_settings[
1463                 0].name))
1464
1465     def test_set_one_port_two_ip_one_subnet(self):
1466         """
1467         Tests the creation of an OpenStack instance with a single port with a
1468         two static IPs on a network with one subnet.
1469         """
1470         ip1 = '10.55.0.101'
1471         ip2 = '10.55.0.102'
1472         sub_settings = self.net_config.network_settings.subnet_settings
1473         port_settings = PortConfig(
1474             name=self.port_1_name,
1475             network_name=self.net_config.network_settings.name,
1476             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip1},
1477                       {'subnet_name': sub_settings[0].name, 'ip': ip2}])
1478
1479         instance_settings = VmInstanceConfig(
1480             name=self.vm_inst_name,
1481             flavor=self.flavor_creator.flavor_settings.name,
1482             port_settings=[port_settings])
1483
1484         self.inst_creator = OpenStackVmInstance(
1485             self.os_creds, instance_settings,
1486             self.image_creator.image_settings)
1487         vm_inst = self.inst_creator.create(block=True)
1488
1489         self.assertEqual(ip1, vm_inst.ports[0].ips[0]['ip_address'])
1490         self.assertEqual(self.network_creator.get_network().subnets[0].id,
1491                          vm_inst.ports[0].ips[0]['subnet_id'])
1492         self.assertEqual(ip2, vm_inst.ports[0].ips[1]['ip_address'])
1493         self.assertEqual(self.network_creator.get_network().subnets[0].id,
1494                          vm_inst.ports[0].ips[1]['subnet_id'])
1495
1496     def test_set_one_port_two_ip_two_subnets(self):
1497         """
1498         Tests the creation of an OpenStack instance with a single port with a
1499         two static IPs on a network with one subnet.
1500         """
1501         net2_config = NetworkConfig(
1502             name=self.guid + 'net2', subnets=[
1503                 SubnetConfig(name=self.guid + '-subnet1', cidr='10.55.0.0/24'),
1504                 SubnetConfig(name=self.guid + '-subnet2', cidr='10.65.0.0/24'),
1505             ])
1506
1507         # Create Network
1508         self.network_creator2 = OpenStackNetwork(self.os_creds, net2_config)
1509         net2 = self.network_creator2.create()
1510
1511         ip1 = '10.55.0.101'
1512         ip2 = '10.65.0.101'
1513
1514         port_settings = PortConfig(
1515             name=self.port_1_name,
1516             network_name=net2_config.name,
1517             ip_addrs=[
1518                 {'subnet_name': net2_config.subnet_settings[0].name,
1519                  'ip': ip1},
1520                 {'subnet_name': net2_config.subnet_settings[1].name,
1521                  'ip': ip2}])
1522
1523         instance_settings = VmInstanceConfig(
1524             name=self.vm_inst_name,
1525             flavor=self.flavor_creator.flavor_settings.name,
1526             port_settings=[port_settings])
1527
1528         self.inst_creator = OpenStackVmInstance(
1529             self.os_creds, instance_settings,
1530             self.image_creator.image_settings)
1531         vm_inst = self.inst_creator.create(block=True)
1532
1533         subnet1_id = None
1534         subnet2_id = None
1535         for subnet in net2.subnets:
1536             if subnet.name == net2_config.subnet_settings[0].name:
1537                 subnet1_id = subnet.id
1538             if subnet.name == net2_config.subnet_settings[1].name:
1539                 subnet2_id = subnet.id
1540         self.assertEqual(ip1, vm_inst.ports[0].ips[0]['ip_address'])
1541         self.assertEqual(subnet1_id, vm_inst.ports[0].ips[0]['subnet_id'])
1542         self.assertEqual(ip2, vm_inst.ports[0].ips[1]['ip_address'])
1543         self.assertEqual(subnet2_id, vm_inst.ports[0].ips[1]['subnet_id'])
1544
1545     def test_set_custom_invalid_ip_one_subnet(self):
1546         """
1547         Tests the creation of an OpenStack instance with a single port with a
1548         static IP on a network with one subnet.
1549         """
1550         ip = '10.66.0.101'
1551         sub_settings = self.net_config.network_settings.subnet_settings
1552         port_settings = PortConfig(
1553             name=self.port_1_name,
1554             network_name=self.net_config.network_settings.name,
1555             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1556
1557         instance_settings = VmInstanceConfig(
1558             name=self.vm_inst_name,
1559             flavor=self.flavor_creator.flavor_settings.name,
1560             port_settings=[port_settings])
1561
1562         self.inst_creator = OpenStackVmInstance(
1563             self.os_creds, instance_settings,
1564             self.image_creator.image_settings)
1565
1566         with self.assertRaises(InvalidIpForSubnetClient):
1567             self.inst_creator.create()
1568
1569     def test_set_custom_valid_mac(self):
1570         """
1571         Tests the creation of an OpenStack instance with a single port where
1572         the MAC address is assigned.
1573         """
1574         mac_addr = '0a:1b:2c:3d:4e:5f'
1575         port_settings = PortConfig(
1576             name=self.port_1_name,
1577             network_name=self.net_config.network_settings.name,
1578             mac_address=mac_addr)
1579
1580         instance_settings = VmInstanceConfig(
1581             name=self.vm_inst_name,
1582             flavor=self.flavor_creator.flavor_settings.name,
1583             port_settings=[port_settings])
1584
1585         self.inst_creator = OpenStackVmInstance(
1586             self.os_creds, instance_settings,
1587             self.image_creator.image_settings)
1588         self.inst_creator.create(block=True)
1589
1590         self.assertEqual(mac_addr,
1591                          self.inst_creator.get_port_mac(self.port_1_name))
1592
1593     def test_set_custom_invalid_mac(self):
1594         """
1595         Tests the creation of an OpenStack instance with a single port where an
1596         invalid MAC address value is being
1597         assigned. This should raise an Exception
1598         """
1599         port_settings = PortConfig(
1600             name=self.port_1_name,
1601             network_name=self.net_config.network_settings.name,
1602             mac_address='foo')
1603
1604         instance_settings = VmInstanceConfig(
1605             name=self.vm_inst_name,
1606             flavor=self.flavor_creator.flavor_settings.name,
1607             port_settings=[port_settings])
1608
1609         self.inst_creator = OpenStackVmInstance(
1610             self.os_creds, instance_settings,
1611             self.image_creator.image_settings)
1612
1613         with self.assertRaises(Exception):
1614             self.inst_creator.create()
1615
1616     def test_set_custom_mac_and_ip(self):
1617         """
1618         Tests the creation of an OpenStack instance with a single port where
1619         the IP and MAC address is assigned.
1620         """
1621         ip = '10.55.0.101'
1622         mac_addr = '0a:1b:2c:3d:4e:5f'
1623         sub_settings = self.net_config.network_settings.subnet_settings
1624         port_settings = PortConfig(
1625             name=self.port_1_name,
1626             network_name=self.net_config.network_settings.name,
1627             mac_address=mac_addr,
1628             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1629
1630         instance_settings = VmInstanceConfig(
1631             name=self.vm_inst_name,
1632             flavor=self.flavor_creator.flavor_settings.name,
1633             port_settings=[port_settings])
1634
1635         self.inst_creator = OpenStackVmInstance(
1636             self.os_creds, instance_settings,
1637             self.image_creator.image_settings)
1638         self.inst_creator.create(block=True)
1639
1640         self.assertEqual(ip, self.inst_creator.get_port_ip(
1641             self.port_1_name,
1642             subnet_name=self.net_config.network_settings.subnet_settings[
1643                 0].name))
1644         self.assertEqual(mac_addr,
1645                          self.inst_creator.get_port_mac(self.port_1_name))
1646
1647     def test_set_allowed_address_pairs(self):
1648         """
1649         Tests the creation of an OpenStack instance with a single port where
1650         max_allowed_address_pair is set.
1651         """
1652         ip = '10.55.0.101'
1653         mac_addr = '0a:1b:2c:3d:4e:5f'
1654         pair = {'ip_address': ip, 'mac_address': mac_addr}
1655         port_settings = PortConfig(
1656             name=self.port_1_name,
1657             network_name=self.net_config.network_settings.name,
1658             allowed_address_pairs=[pair])
1659
1660         instance_settings = VmInstanceConfig(
1661             name=self.vm_inst_name,
1662             flavor=self.flavor_creator.flavor_settings.name,
1663             port_settings=[port_settings])
1664
1665         self.inst_creator = OpenStackVmInstance(
1666             self.os_creds, instance_settings,
1667             self.image_creator.image_settings)
1668         self.inst_creator.create(block=True)
1669
1670         port = self.inst_creator.get_port_by_name(port_settings.name)
1671         self.assertIsNotNone(port)
1672         self.assertIsNotNone(port.allowed_address_pairs)
1673         self.assertEqual(1, len(port.allowed_address_pairs))
1674         validation_utils.objects_equivalent(pair,
1675                                             port.allowed_address_pairs[0])
1676
1677     def test_set_allowed_address_pairs_bad_mac(self):
1678         """
1679         Tests the creation of an OpenStack instance with a single port where
1680         max_allowed_address_pair is set with an invalid MAC address.
1681         """
1682         ip = '10.55.0.101'
1683         mac_addr = 'foo'
1684         pair = {'ip_address': ip, 'mac_address': mac_addr}
1685         pairs = set()
1686         pairs.add((ip, mac_addr))
1687         port_settings = PortConfig(
1688             name=self.port_1_name,
1689             network_name=self.net_config.network_settings.name,
1690             allowed_address_pairs=[pair])
1691
1692         instance_settings = VmInstanceConfig(
1693             name=self.vm_inst_name,
1694             flavor=self.flavor_creator.flavor_settings.name,
1695             port_settings=[port_settings])
1696
1697         self.inst_creator = OpenStackVmInstance(
1698             self.os_creds, instance_settings,
1699             self.image_creator.image_settings)
1700         with self.assertRaises(Exception):
1701             self.inst_creator.create()
1702
1703     def test_set_allowed_address_pairs_bad_ip(self):
1704         """
1705         Tests the creation of an OpenStack instance with a single port where
1706         max_allowed_address_pair is set with an invalid MAC address.
1707         """
1708         ip = 'foo'
1709         mac_addr = '0a:1b:2c:3d:4e:5f'
1710         pair = {'ip_address': ip, 'mac_address': mac_addr}
1711         pairs = set()
1712         pairs.add((ip, mac_addr))
1713         port_settings = PortConfig(
1714             name=self.port_1_name,
1715             network_name=self.net_config.network_settings.name,
1716             allowed_address_pairs=[pair])
1717
1718         instance_settings = VmInstanceConfig(
1719             name=self.vm_inst_name,
1720             flavor=self.flavor_creator.flavor_settings.name,
1721             port_settings=[port_settings])
1722
1723         self.inst_creator = OpenStackVmInstance(
1724             self.os_creds, instance_settings,
1725             self.image_creator.image_settings)
1726         with self.assertRaises(Exception):
1727             self.inst_creator.create()
1728
1729
1730 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1731     """
1732     Test for the CreateInstance where one VM is deployed to each compute node
1733     """
1734
1735     def setUp(self):
1736         """
1737         Instantiates the CreateImage object that is responsible for downloading
1738         and creating an OS image file within OpenStack
1739         """
1740         super(self.__class__, self).__start__()
1741
1742         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1743         self.vm_inst_name = guid + '-inst'
1744         self.port_base_name = guid + 'port'
1745
1746         # Initialize for tearDown()
1747         self.image_creator = None
1748         self.flavor_creator = None
1749         self.network_creator = None
1750         self.inst_creators = list()
1751
1752         self.priv_net_config = openstack_tests.get_priv_net_config(
1753             project_name=self.os_creds.project_name,
1754             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet',
1755             netconf_override=self.netconf_override)
1756
1757         os_image_settings = openstack_tests.cirros_image_settings(
1758             name=guid + '-image', image_metadata=self.image_metadata)
1759
1760         try:
1761             # Create Network
1762             self.network_creator = OpenStackNetwork(
1763                 self.admin_os_creds, self.priv_net_config.network_settings)
1764             self.network_creator.create()
1765
1766             # Create Flavor
1767             flavor_config = openstack_tests.get_flavor_config(
1768                 name=guid + '-flavor-name', ram=512, disk=1,
1769                 vcpus=1, metadata=self.flavor_metadata)
1770             self.flavor_creator = OpenStackFlavor(
1771                 self.admin_os_creds, flavor_config)
1772             self.flavor_creator.create()
1773
1774             # Create Image
1775             self.image_creator = OpenStackImage(self.os_creds,
1776                                                 os_image_settings)
1777             self.image_creator.create()
1778
1779         except Exception as e:
1780             self.tearDown()
1781             raise e
1782
1783     def tearDown(self):
1784         """
1785         Cleans the created object
1786         """
1787         for inst_creator in self.inst_creators:
1788             try:
1789                 inst_creator.clean()
1790             except Exception as e:
1791                 logger.error(
1792                     'Unexpected exception cleaning VM instance with message '
1793                     '- %s', e)
1794
1795         if self.flavor_creator:
1796             try:
1797                 self.flavor_creator.clean()
1798             except Exception as e:
1799                 logger.error(
1800                     'Unexpected exception cleaning flavor with message - %s',
1801                     e)
1802
1803         if self.network_creator:
1804             try:
1805                 self.network_creator.clean()
1806             except Exception as e:
1807                 logger.error(
1808                     'Unexpected exception cleaning network with message - %s',
1809                     e)
1810
1811         if self.image_creator and not self.image_creator.image_settings.exists:
1812             try:
1813                 self.image_creator.clean()
1814             except Exception as e:
1815                 logger.error(
1816                     'Unexpected exception cleaning image with message - %s', e)
1817
1818         super(self.__class__, self).__clean__()
1819
1820     def test_deploy_vm_to_each_compute_node(self):
1821         """
1822         Tests the creation of OpenStack VM instances to each compute node.
1823         """
1824         from snaps.openstack.utils import nova_utils
1825         nova = nova_utils.nova_client(
1826             self.admin_os_creds, self.admin_os_session)
1827         zone_hosts = nova_utils.get_availability_zone_hosts(nova)
1828
1829         # Create Instance on each server/zone
1830         ctr = 0
1831         for zone in zone_hosts:
1832             inst_name = self.vm_inst_name + '-' + zone
1833             ctr += 1
1834             port_settings = PortConfig(
1835                 name=self.port_base_name + '-' + str(ctr),
1836                 network_name=self.priv_net_config.network_settings.name)
1837
1838             instance_settings = VmInstanceConfig(
1839                 name=inst_name,
1840                 flavor=self.flavor_creator.flavor_settings.name,
1841                 availability_zone=zone,
1842                 port_settings=[port_settings])
1843             inst_creator = OpenStackVmInstance(
1844                 self.admin_os_creds, instance_settings,
1845                 self.image_creator.image_settings)
1846             self.inst_creators.append(inst_creator)
1847             inst_creator.create(block=True)
1848             avail_zone = inst_creator.get_vm_inst().availability_zone
1849             self.assertTrue(avail_zone in zone)
1850             compute_host = inst_creator.get_vm_inst().compute_host
1851             self.assertTrue(compute_host in zone)
1852
1853         # Validate instances to ensure they've been deployed to the correct
1854         # server
1855         index = 0
1856         for zone in zone_hosts:
1857             creator = self.inst_creators[index]
1858             self.assertTrue(creator.vm_active(block=True))
1859             info = creator.get_vm_info()
1860             deployed_zone = info['OS-EXT-AZ:availability_zone']
1861             deployed_host = info['OS-EXT-SRV-ATTR:host']
1862             self.assertEqual(zone, deployed_zone + ':' + deployed_host)
1863             index += 1
1864
1865
1866 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1867     """
1868     Tests that include, add, and remove security groups from VM instances
1869     """
1870
1871     def setUp(self):
1872         """
1873         Instantiates the CreateImage object that is responsible for downloading
1874         and creating an OS image file within OpenStack
1875         """
1876         super(self.__class__, self).__start__()
1877
1878         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1879         self.vm_inst_name = self.guid + '-inst'
1880         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
1881         os_image_settings = openstack_tests.cirros_image_settings(
1882             name=self.guid + '-image', image_metadata=self.image_metadata)
1883
1884         self.vm_inst_name = self.guid + '-inst'
1885         self.port_1_name = self.guid + 'port-1'
1886         self.port_2_name = self.guid + 'port-2'
1887         self.floating_ip_name = self.guid + 'fip1'
1888
1889         net_config = openstack_tests.get_priv_net_config(
1890             project_name=self.os_creds.project_name,
1891             net_name=self.guid + '-pub-net',
1892             subnet_name=self.guid + '-pub-subnet',
1893             router_name=self.guid + '-pub-router',
1894             external_net=self.ext_net_name,
1895             netconf_override=self.netconf_override)
1896
1897         # Initialize for tearDown()
1898         self.image_creator = None
1899         self.flavor_creator = None
1900         self.network_creator = None
1901         self.router_creator = None
1902         self.inst_creator = None
1903         self.sec_grp_creators = list()
1904
1905         try:
1906             # Create Image
1907             self.image_creator = OpenStackImage(self.os_creds,
1908                                                 os_image_settings)
1909             self.image_creator.create()
1910
1911             # Create Network
1912             self.network_creator = OpenStackNetwork(
1913                 self.os_creds, net_config.network_settings)
1914             self.network_creator.create()
1915
1916             # Create Flavor
1917             flavor_config = openstack_tests.get_flavor_config(
1918                 name=self.guid + '-flavor-name', ram=256, disk=10,
1919                 vcpus=2, metadata=self.flavor_metadata)
1920             self.flavor_creator = OpenStackFlavor(
1921                 self.admin_os_creds, flavor_config)
1922             self.flavor_creator.create()
1923
1924             self.port_settings = PortConfig(
1925                 name=self.guid + '-port',
1926                 network_name=net_config.network_settings.name)
1927         except Exception as e:
1928             self.tearDown()
1929             raise e
1930
1931     def tearDown(self):
1932         """
1933         Cleans the created object
1934         """
1935         if self.inst_creator:
1936             try:
1937                 self.inst_creator.clean()
1938             except Exception as e:
1939                 logger.error(
1940                     'Unexpected exception cleaning VM instance with message -'
1941                     ' %s', e)
1942
1943         for sec_grp_creator in self.sec_grp_creators:
1944             try:
1945                 sec_grp_creator.clean()
1946             except Exception as e:
1947                 logger.error(
1948                     'Unexpected exception cleaning security group with message'
1949                     ' - %s', e)
1950
1951         if self.flavor_creator:
1952             try:
1953                 self.flavor_creator.clean()
1954             except Exception as e:
1955                 logger.error(
1956                     'Unexpected exception cleaning flavor with message - %s',
1957                     e)
1958
1959         if self.network_creator:
1960             try:
1961                 self.network_creator.clean()
1962             except Exception as e:
1963                 logger.error(
1964                     'Unexpected exception cleaning network with message - %s',
1965                     e)
1966
1967         if self.image_creator and not self.image_creator.image_settings.exists:
1968             try:
1969                 self.image_creator.clean()
1970             except Exception as e:
1971                 logger.error(
1972                     'Unexpected exception cleaning image with message - %s', e)
1973
1974         super(self.__class__, self).__clean__()
1975
1976     def test_add_security_group(self):
1977         """
1978         Tests the addition of a security group created after the instance.
1979         """
1980         # Create instance
1981         instance_settings = VmInstanceConfig(
1982             name=self.vm_inst_name,
1983             flavor=self.flavor_creator.flavor_settings.name,
1984             port_settings=[self.port_settings])
1985         self.inst_creator = OpenStackVmInstance(
1986             self.os_creds, instance_settings,
1987             self.image_creator.image_settings)
1988         vm_inst = self.inst_creator.create(block=True)
1989         self.assertIsNotNone(vm_inst)
1990
1991         # Create security group object to add to instance
1992         sec_grp_settings = SecurityGroupConfig(
1993             name=self.guid + '-name', description='hello group')
1994         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1995                                                  sec_grp_settings)
1996         sec_grp = sec_grp_creator.create()
1997         self.sec_grp_creators.append(sec_grp_creator)
1998
1999         # Check that group has not been added
2000         self.assertFalse(inst_has_sec_grp(
2001             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2002
2003         # Add security group to instance after activated
2004         self.inst_creator.add_security_group(sec_grp)
2005
2006         # Validate that security group has been added
2007         self.assertTrue(inst_has_sec_grp(
2008             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2009
2010     def test_add_invalid_security_group(self):
2011         """
2012         Tests the addition of a security group that no longer exists.
2013         """
2014         # Create instance
2015         instance_settings = VmInstanceConfig(
2016             name=self.vm_inst_name,
2017             flavor=self.flavor_creator.flavor_settings.name,
2018             port_settings=[self.port_settings])
2019         self.inst_creator = OpenStackVmInstance(
2020             self.os_creds, instance_settings,
2021             self.image_creator.image_settings)
2022         vm_inst = self.inst_creator.create(block=True)
2023         self.assertIsNotNone(vm_inst)
2024
2025         # Create security group object to add to instance
2026         sec_grp_settings = SecurityGroupConfig(
2027             name=self.guid + '-name', description='hello group')
2028         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2029                                                  sec_grp_settings)
2030         sec_grp = sec_grp_creator.create()
2031         sec_grp_creator.clean()
2032         self.sec_grp_creators.append(sec_grp_creator)
2033
2034         # Check that group has not been added
2035         self.assertFalse(inst_has_sec_grp(
2036             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2037
2038         # Add security group to instance after activated
2039         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
2040
2041         # Validate that security group has been added
2042         self.assertFalse(inst_has_sec_grp(
2043             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2044
2045     def test_remove_security_group(self):
2046         """
2047         Tests the removal of a security group created before and added to the
2048         instance.
2049         """
2050         # Create security group object to add to instance
2051         sec_grp_settings = SecurityGroupConfig(
2052             name=self.guid + '-name', description='hello group')
2053         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2054                                                  sec_grp_settings)
2055         sec_grp = sec_grp_creator.create()
2056         self.sec_grp_creators.append(sec_grp_creator)
2057
2058         # Create instance
2059         instance_settings = VmInstanceConfig(
2060             name=self.vm_inst_name,
2061             flavor=self.flavor_creator.flavor_settings.name,
2062             security_group_names=[sec_grp_settings.name],
2063             port_settings=[self.port_settings])
2064         self.inst_creator = OpenStackVmInstance(
2065             self.os_creds, instance_settings,
2066             self.image_creator.image_settings)
2067         vm_inst = self.inst_creator.create(block=True)
2068         self.assertIsNotNone(vm_inst)
2069
2070         # Check that group has been added
2071         self.assertTrue(inst_has_sec_grp(
2072             self.nova, vm_inst, sec_grp_settings.name))
2073
2074         # Add security group to instance after activated
2075         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
2076
2077         # Validate that security group has been added
2078         self.assertFalse(inst_has_sec_grp(
2079             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2080
2081     def test_remove_security_group_never_added(self):
2082         """
2083         Tests the removal of a security group that was never added in the first
2084         place.
2085         """
2086         # Create security group object to add to instance
2087         sec_grp_settings = SecurityGroupConfig(
2088             name=self.guid + '-name', description='hello group')
2089         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2090                                                  sec_grp_settings)
2091         sec_grp = sec_grp_creator.create()
2092         self.sec_grp_creators.append(sec_grp_creator)
2093
2094         # Create instance
2095         instance_settings = VmInstanceConfig(
2096             name=self.vm_inst_name,
2097             flavor=self.flavor_creator.flavor_settings.name,
2098             port_settings=[self.port_settings])
2099         self.inst_creator = OpenStackVmInstance(
2100             self.os_creds, instance_settings,
2101             self.image_creator.image_settings)
2102         vm_inst = self.inst_creator.create(block=True)
2103         self.assertIsNotNone(vm_inst)
2104
2105         # Check that group has been added
2106         self.assertFalse(inst_has_sec_grp(
2107             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2108
2109         # Add security group to instance after activated
2110         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
2111
2112         # Validate that security group has been added
2113         self.assertFalse(inst_has_sec_grp(
2114             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2115
2116     def test_add_same_security_group(self):
2117         """
2118         Tests the addition of a security group created before add added to the
2119         instance.
2120         """
2121         # Create security group object to add to instance
2122         sec_grp_settings = SecurityGroupConfig(
2123             name=self.guid + '-name', description='hello group')
2124         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2125                                                  sec_grp_settings)
2126         sec_grp = sec_grp_creator.create()
2127         self.sec_grp_creators.append(sec_grp_creator)
2128
2129         # Create instance
2130         instance_settings = VmInstanceConfig(
2131             name=self.vm_inst_name,
2132             flavor=self.flavor_creator.flavor_settings.name,
2133             security_group_names=[sec_grp_settings.name],
2134             port_settings=[self.port_settings])
2135         self.inst_creator = OpenStackVmInstance(
2136             self.os_creds, instance_settings,
2137             self.image_creator.image_settings)
2138         vm_inst = self.inst_creator.create(block=True)
2139         self.assertIsNotNone(vm_inst)
2140
2141         # Check that group has been added
2142         self.assertTrue(inst_has_sec_grp(
2143             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2144
2145         # Add security group to instance after activated
2146         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
2147
2148         # Validate that security group has been added
2149         self.assertTrue(inst_has_sec_grp(
2150             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2151
2152
2153 def inst_has_sec_grp(nova, vm_inst, sec_grp_name):
2154     """
2155     Returns true if instance has a security group of a given name
2156     :param nova: the nova client
2157     :param vm_inst: the VmInst domain object
2158     :param sec_grp_name: the name of the security group to validate
2159     :return: T/F
2160     """
2161     sec_grp_names = nova_utils.get_server_security_group_names(nova, vm_inst)
2162     for name in sec_grp_names:
2163         if sec_grp_name == name:
2164             return True
2165     return False
2166
2167
2168 def validate_ssh_client(instance_creator, fip_name=None):
2169     """
2170     Returns True if instance_creator returns an SSH client that is valid
2171     :param instance_creator: the object responsible for creating the VM
2172                              instance
2173     :param fip_name: the name of the floating IP to use
2174     :return: T/F
2175     """
2176     ssh_active = instance_creator.vm_ssh_active(block=True)
2177
2178     if ssh_active:
2179         ssh_client = instance_creator.ssh_client(fip_name=fip_name)
2180         if ssh_client:
2181             try:
2182                 out = ssh_client.exec_command('pwd')[1]
2183                 channel = out.channel
2184                 in_buffer = channel.in_buffer
2185                 pwd_out = in_buffer.read(1024)
2186                 if not pwd_out or len(pwd_out) < 10:
2187                     return False
2188                 return True
2189             finally:
2190                 ssh_client.close()
2191         else:
2192             return False
2193
2194     return False
2195
2196
2197 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
2198     """
2199     Test for the CreateInstance class for creating an image from a 3-part image
2200     """
2201
2202     def setUp(self):
2203         """
2204         Instantiates the CreateImage object that is responsible for downloading
2205         and creating an OS image file within OpenStack
2206         """
2207         super(self.__class__, self).__start__()
2208
2209         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2210         self.image_name = guid
2211         self.vm_inst_name = guid + '-inst'
2212         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
2213
2214         net_config = openstack_tests.get_priv_net_config(
2215             project_name=self.os_creds.project_name,
2216             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
2217             router_name=guid + '-pub-router', external_net=self.ext_net_name,
2218             netconf_override=self.netconf_override)
2219
2220         # Initialize for tearDown()
2221         self.image_creator = None
2222         self.network_creator = None
2223         self.flavor_creator = None
2224         self.inst_creator = None
2225
2226         try:
2227             if self.image_metadata and 'disk_file' in self.image_metadata:
2228                 metadata = self.image_metadata
2229             elif self.image_metadata and 'cirros' in self.image_metadata \
2230                     and 'disk_file' in self.image_metadata['cirros']:
2231                 metadata = self.image_metadata['cirros']
2232             else:
2233                 metadata = {
2234                     'disk_url': openstack_tests.CIRROS_DEFAULT_IMAGE_URL,
2235                     'kernel_url':
2236                         openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL,
2237                     'ramdisk_url':
2238                         openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL}
2239
2240             image_settings = openstack_tests.cirros_image_settings(
2241                 name=self.image_name,
2242                 image_metadata=metadata)
2243
2244             if not image_settings.ramdisk_image_settings or not \
2245                     image_settings.kernel_image_settings:
2246                 logger.warn(
2247                     '3 Part image will not be tested. Image metadata has '
2248                     'overridden this functionality')
2249
2250             self.image_creator = OpenStackImage(self.os_creds, image_settings)
2251             self.image_creator.create()
2252
2253             # Create Flavor
2254             flavor_config = openstack_tests.get_flavor_config(
2255                 name=guid + '-flavor-name', ram=256, disk=10,
2256                 vcpus=2, metadata=self.flavor_metadata)
2257             self.flavor_creator = OpenStackFlavor(
2258                 self.admin_os_creds, flavor_config)
2259             self.flavor_creator.create()
2260
2261             # Create Network
2262             self.network_creator = OpenStackNetwork(
2263                 self.os_creds, net_config.network_settings)
2264             self.network_creator.create()
2265
2266             self.port_settings = PortConfig(
2267                 name=guid + '-port',
2268                 network_name=net_config.network_settings.name)
2269         except Exception as e:
2270             self.tearDown()
2271             raise e
2272
2273     def tearDown(self):
2274         """
2275         Cleans the created object
2276         """
2277         if self.inst_creator:
2278             try:
2279                 self.inst_creator.clean()
2280             except Exception as e:
2281                 logger.error(
2282                     'Unexpected exception cleaning VM instance with message -'
2283                     ' %s', e)
2284
2285         if self.flavor_creator:
2286             try:
2287                 self.flavor_creator.clean()
2288             except Exception as e:
2289                 logger.error(
2290                     'Unexpected exception cleaning flavor with message - %s',
2291                     e)
2292
2293         if self.network_creator:
2294             try:
2295                 self.network_creator.clean()
2296             except Exception as e:
2297                 logger.error(
2298                     'Unexpected exception cleaning network with message - %s',
2299                     e)
2300
2301         if self.image_creator and not self.image_creator.image_settings.exists:
2302             try:
2303                 self.image_creator.clean()
2304             except Exception as e:
2305                 logger.error(
2306                     'Unexpected exception cleaning image with message - %s', e)
2307
2308         super(self.__class__, self).__clean__()
2309
2310     def test_create_instance_from_three_part_image(self):
2311         """
2312         Tests the creation of an OpenStack instance from a 3-part image.
2313         """
2314         instance_settings = VmInstanceConfig(
2315             name=self.vm_inst_name,
2316             flavor=self.flavor_creator.flavor_settings.name,
2317             port_settings=[self.port_settings])
2318
2319         # The last created image is the main image from which we create the
2320         # instance
2321         self.inst_creator = OpenStackVmInstance(
2322             self.os_creds, instance_settings,
2323             self.image_creator.image_settings)
2324
2325         vm_inst = self.inst_creator.create()
2326         self.assertIsNotNone(vm_inst)
2327         self.assertTrue(self.inst_creator.vm_active(block=True))
2328
2329
2330 class CreateInstanceMockOfflineTests(OSComponentTestCase):
2331     """
2332     Tests the custom image_metadata that can be set by clients for handling
2333     images differently than the default behavior of the existing tests
2334     primarily for offline testing
2335     """
2336
2337     def setUp(self):
2338         """
2339         Instantiates the CreateImage object that is responsible for downloading
2340         and creating an OS image file within OpenStack
2341         """
2342         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2343
2344         self.tmpDir = 'tmp/' + str(self.guid)
2345         if not os.path.exists(self.tmpDir):
2346             os.makedirs(self.tmpDir)
2347
2348         self.image_name = self.guid + '-image'
2349         self.vm_inst_name = self.guid + '-inst'
2350         self.port_1_name = self.guid + 'port-1'
2351
2352         # Initialize for tearDown()
2353         self.image_creator = None
2354         self.network_creator = None
2355         self.flavor_creator = None
2356         self.inst_creator = None
2357
2358         self.priv_net_config = openstack_tests.get_priv_net_config(
2359             project_name=self.os_creds.project_name,
2360             net_name=self.guid + '-priv-net',
2361             subnet_name=self.guid + '-priv-subnet')
2362         self.port_settings = PortConfig(
2363             name=self.port_1_name,
2364             network_name=self.priv_net_config.network_settings.name)
2365
2366         try:
2367             # Download image file
2368             self.image_file = file_utils.download(
2369                 openstack_tests.CIRROS_DEFAULT_IMAGE_URL, self.tmpDir)
2370
2371             # Create Network
2372             self.network_creator = OpenStackNetwork(
2373                 self.os_creds, self.priv_net_config.network_settings)
2374             self.network_creator.create()
2375
2376             # Create Flavor
2377             flavor_config = openstack_tests.get_flavor_config(
2378                 name=self.guid + '-flavor-name', ram=256, disk=10,
2379                 vcpus=2, metadata=self.flavor_metadata)
2380             self.flavor_creator = OpenStackFlavor(
2381                 self.os_creds, flavor_config)
2382             self.flavor_creator.create()
2383         except Exception as e:
2384             self.tearDown()
2385             raise e
2386
2387     def tearDown(self):
2388         """
2389         Cleans the created object
2390         """
2391         if self.inst_creator:
2392             try:
2393                 self.inst_creator.clean()
2394             except Exception as e:
2395                 logger.error(
2396                     'Unexpected exception cleaning VM instance with message - '
2397                     '%s', e)
2398
2399         if self.network_creator:
2400             try:
2401                 self.network_creator.clean()
2402             except Exception as e:
2403                 logger.error(
2404                     'Unexpected exception cleaning network with message - %s',
2405                     e)
2406
2407         if self.flavor_creator:
2408             try:
2409                 self.flavor_creator.clean()
2410             except Exception as e:
2411                 logger.error(
2412                     'Unexpected exception cleaning flavor with message - %s',
2413                     e)
2414
2415         if self.image_creator:
2416             try:
2417                 self.image_creator.clean()
2418             except Exception as e:
2419                 logger.error(
2420                     'Unexpected exception cleaning image with message - %s', e)
2421
2422         if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir):
2423             shutil.rmtree(self.tmpDir)
2424
2425         super(self.__class__, self).__clean__()
2426
2427     def test_inst_from_file_image_simple_flat(self):
2428         """
2429         Creates a VM instance from a locally sourced file image using simply
2430         the 'disk_file' attribute vs. using the 'config' option which
2431         completely overrides all image settings
2432         :return: 
2433         """
2434         metadata = {'disk_file': self.image_file.name}
2435
2436         os_image_settings = openstack_tests.cirros_image_settings(
2437             name=self.image_name, image_metadata=metadata)
2438         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2439         self.assertEqual(openstack_tests.CIRROS_USER,
2440                          os_image_settings.image_user)
2441         self.assertIsNone(os_image_settings.url)
2442         self.assertFalse(os_image_settings.exists)
2443         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2444                          os_image_settings.format)
2445
2446         self.assertIsNone(os_image_settings.kernel_image_settings)
2447         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2448
2449         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2450         self.image_creator.create()
2451
2452         instance_settings = VmInstanceConfig(
2453             name=self.vm_inst_name,
2454             flavor=self.flavor_creator.flavor_settings.name,
2455             port_settings=[self.port_settings])
2456         self.inst_creator = OpenStackVmInstance(
2457             self.os_creds, instance_settings,
2458             self.image_creator.image_settings)
2459         self.inst_creator.create()
2460
2461         self.assertTrue(self.inst_creator.vm_active(block=True))
2462
2463     def test_inst_from_file_image_simple_nested(self):
2464         """
2465         Creates a VM instance from a locally sourced file image using simply
2466         the 'disk_file' attribute under 'cirros' vs. using the 'config' option
2467         which completely overrides all image settings
2468         :return: 
2469         """
2470         metadata = {'cirros': {'disk_file': self.image_file.name}}
2471
2472         os_image_settings = openstack_tests.cirros_image_settings(
2473             name=self.image_name, image_metadata=metadata)
2474         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2475         self.assertEqual(openstack_tests.CIRROS_USER,
2476                          os_image_settings.image_user)
2477         self.assertIsNone(os_image_settings.url)
2478         self.assertFalse(os_image_settings.exists)
2479         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2480                          os_image_settings.format)
2481
2482         self.assertIsNone(os_image_settings.kernel_image_settings)
2483         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2484
2485         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2486         self.image_creator.create()
2487
2488         instance_settings = VmInstanceConfig(
2489             name=self.vm_inst_name,
2490             flavor=self.flavor_creator.flavor_settings.name,
2491             port_settings=[self.port_settings])
2492         self.inst_creator = OpenStackVmInstance(
2493             self.os_creds, instance_settings,
2494             self.image_creator.image_settings)
2495         self.inst_creator.create()
2496
2497         self.assertTrue(self.inst_creator.vm_active(block=True))
2498
2499     def test_inst_from_existing(self):
2500         """
2501         Creates a VM instance from a image creator that has been configured to
2502         use an existing image
2503         :return: 
2504         """
2505         os_image_settings = openstack_tests.cirros_image_settings(
2506             name=self.image_name)
2507         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2508         self.image_creator.create()
2509
2510         image_settings = self.image_creator.image_settings
2511         test_image_creator = OpenStackImage(
2512             self.os_creds,
2513             ImageConfig(
2514                 name=image_settings.name, image_user=image_settings.image_user,
2515                 exists=True))
2516         test_image_creator.create()
2517         self.assertEqual(self.image_creator.get_image().id,
2518                          test_image_creator.get_image().id)
2519
2520         instance_settings = VmInstanceConfig(
2521             name=self.vm_inst_name,
2522             flavor=self.flavor_creator.flavor_settings.name,
2523             port_settings=[self.port_settings])
2524         self.inst_creator = OpenStackVmInstance(
2525             self.os_creds, instance_settings,
2526             test_image_creator.image_settings)
2527         self.inst_creator.create()
2528
2529         self.assertTrue(self.inst_creator.vm_active(block=True))
2530
2531     def test_inst_from_file_image_complex(self):
2532         """
2533         Creates a VM instance from a locally sourced file image by overriding
2534         the default settings by using a dict() that can be read in by
2535         ImageSettings
2536         :return: 
2537         """
2538
2539         os_image_settings = openstack_tests.cirros_image_settings(
2540             name=self.image_name)
2541         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2542         self.image_creator.create()
2543
2544         metadata = {
2545             'cirros': {
2546                 'config': {
2547                     'name': os_image_settings.name,
2548                     'image_user': os_image_settings.image_user,
2549                     'exists': True}}}
2550         test_image_settings = openstack_tests.cirros_image_settings(
2551             image_metadata=metadata)
2552         test_image = OpenStackImage(self.os_creds, test_image_settings)
2553         test_image.create()
2554
2555         instance_settings = VmInstanceConfig(
2556             name=self.vm_inst_name,
2557             flavor=self.flavor_creator.flavor_settings.name,
2558             port_settings=[self.port_settings])
2559         self.inst_creator = OpenStackVmInstance(self.os_creds,
2560                                                 instance_settings,
2561                                                 test_image_settings)
2562         self.inst_creator.create()
2563
2564         self.assertTrue(self.inst_creator.vm_active(block=True))
2565
2566     def test_inst_from_file_3part_image_complex(self):
2567         """
2568         Creates a VM instance from a locally sourced file image by overriding
2569         the default settings by using a dict() that can be read in by
2570         ImageSettings
2571         :return: 
2572         """
2573
2574         kernel_file = file_utils.download(
2575             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2576         ramdisk_file = file_utils.download(
2577             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2578
2579         metadata = {
2580             'cirros': {
2581                 'config': {
2582                     'name': self.image_name,
2583                     'image_user': openstack_tests.CIRROS_USER,
2584                     'image_file': self.image_file.name,
2585                     'format': openstack_tests.DEFAULT_IMAGE_FORMAT,
2586                     'kernel_image_settings': {
2587                         'name': self.image_name + '-kernel',
2588                         'image_user': openstack_tests.CIRROS_USER,
2589                         'image_file': kernel_file.name,
2590                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT},
2591                     'ramdisk_image_settings': {
2592                         'name': self.image_name + '-ramdisk',
2593                         'image_user': openstack_tests.CIRROS_USER,
2594                         'image_file': ramdisk_file.name,
2595                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}}
2596
2597         os_image_settings = openstack_tests.cirros_image_settings(
2598             name=self.image_name, image_metadata=metadata)
2599         self.assertEqual(self.image_name, os_image_settings.name)
2600         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2601         self.assertEqual(openstack_tests.CIRROS_USER,
2602                          os_image_settings.image_user)
2603         self.assertIsNone(os_image_settings.url)
2604         self.assertFalse(os_image_settings.exists)
2605         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2606                          os_image_settings.format)
2607
2608         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2609         self.assertEqual(self.image_name + '-kernel',
2610                          os_image_settings.kernel_image_settings.name)
2611         self.assertEqual(kernel_file.name,
2612                          os_image_settings.kernel_image_settings.image_file)
2613         self.assertEqual(openstack_tests.CIRROS_USER,
2614                          os_image_settings.kernel_image_settings.image_user)
2615         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2616         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2617         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2618                          os_image_settings.kernel_image_settings.format)
2619
2620         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2621         self.assertEqual(self.image_name + '-ramdisk',
2622                          os_image_settings.ramdisk_image_settings.name)
2623         self.assertEqual(ramdisk_file.name,
2624                          os_image_settings.ramdisk_image_settings.image_file)
2625         self.assertEqual(openstack_tests.CIRROS_USER,
2626                          os_image_settings.ramdisk_image_settings.image_user)
2627         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2628         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2629         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2630                          os_image_settings.ramdisk_image_settings.format)
2631
2632         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2633         self.image_creator.create()
2634
2635         instance_settings = VmInstanceConfig(
2636             name=self.vm_inst_name,
2637             flavor=self.flavor_creator.flavor_settings.name,
2638             port_settings=[self.port_settings])
2639         self.inst_creator = OpenStackVmInstance(
2640             self.os_creds, instance_settings,
2641             self.image_creator.image_settings)
2642         self.inst_creator.create()
2643
2644         self.assertTrue(self.inst_creator.vm_active(block=True))
2645
2646     def test_inst_from_file_3part_image_simple_flat(self):
2647         """
2648         Creates a VM instance from a 3-part image locally sourced from file
2649         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2650         attributes vs. using the 'config' option which completely overrides all
2651         image settings
2652         :return: 
2653         """
2654         kernel_file = file_utils.download(
2655             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2656         ramdisk_file = file_utils.download(
2657             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2658
2659         metadata = {'disk_file': self.image_file.name,
2660                     'kernel_file': kernel_file.name,
2661                     'ramdisk_file': ramdisk_file.name}
2662
2663         os_image_settings = openstack_tests.cirros_image_settings(
2664             name=self.image_name, image_metadata=metadata)
2665
2666         self.assertEqual(self.image_name, os_image_settings.name)
2667         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2668         self.assertEqual(openstack_tests.CIRROS_USER,
2669                          os_image_settings.image_user)
2670         self.assertIsNone(os_image_settings.url)
2671         self.assertFalse(os_image_settings.exists)
2672         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2673                          os_image_settings.format)
2674
2675         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2676         self.assertEqual(self.image_name + '-kernel',
2677                          os_image_settings.kernel_image_settings.name)
2678         self.assertEqual(kernel_file.name,
2679                          os_image_settings.kernel_image_settings.image_file)
2680         self.assertEqual(openstack_tests.CIRROS_USER,
2681                          os_image_settings.kernel_image_settings.image_user)
2682         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2683         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2684         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2685                          os_image_settings.kernel_image_settings.format)
2686
2687         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2688         self.assertEqual(self.image_name + '-ramdisk',
2689                          os_image_settings.ramdisk_image_settings.name)
2690         self.assertEqual(ramdisk_file.name,
2691                          os_image_settings.ramdisk_image_settings.image_file)
2692         self.assertEqual(openstack_tests.CIRROS_USER,
2693                          os_image_settings.ramdisk_image_settings.image_user)
2694         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2695         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2696         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2697                          os_image_settings.ramdisk_image_settings.format)
2698
2699         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2700         self.image_creator.create()
2701
2702         self.assertIsNotNone(self.image_creator.get_kernel_image())
2703         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2704
2705         instance_settings = VmInstanceConfig(
2706             name=self.vm_inst_name,
2707             flavor=self.flavor_creator.flavor_settings.name,
2708             port_settings=[self.port_settings])
2709         self.inst_creator = OpenStackVmInstance(
2710             self.os_creds, instance_settings,
2711             self.image_creator.image_settings)
2712         self.inst_creator.create()
2713
2714         self.assertTrue(self.inst_creator.vm_active(block=True))
2715
2716     def test_inst_from_file_3part_image_simple_nested(self):
2717         """
2718         Creates a VM instance from a 3-part image locally sourced from file
2719         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2720         attributes under 'cirros' vs. using the 'config' option which
2721         completely overrides all image settings
2722         :return: 
2723         """
2724         kernel_file = file_utils.download(
2725             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2726         ramdisk_file = file_utils.download(
2727             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2728
2729         metadata = {'cirros': {'disk_file': self.image_file.name,
2730                                'kernel_file': kernel_file.name,
2731                                'ramdisk_file': ramdisk_file.name}}
2732
2733         os_image_settings = openstack_tests.cirros_image_settings(
2734             name=self.image_name, image_metadata=metadata)
2735
2736         self.assertEqual(self.image_name, os_image_settings.name)
2737         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2738         self.assertEqual(openstack_tests.CIRROS_USER,
2739                          os_image_settings.image_user)
2740         self.assertIsNone(os_image_settings.url)
2741         self.assertFalse(os_image_settings.exists)
2742         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2743                          os_image_settings.format)
2744
2745         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2746         self.assertEqual(self.image_name + '-kernel',
2747                          os_image_settings.kernel_image_settings.name)
2748         self.assertEqual(kernel_file.name,
2749                          os_image_settings.kernel_image_settings.image_file)
2750         self.assertEqual(openstack_tests.CIRROS_USER,
2751                          os_image_settings.kernel_image_settings.image_user)
2752         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2753         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2754         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2755                          os_image_settings.kernel_image_settings.format)
2756
2757         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2758         self.assertEqual(self.image_name + '-ramdisk',
2759                          os_image_settings.ramdisk_image_settings.name)
2760         self.assertEqual(ramdisk_file.name,
2761                          os_image_settings.ramdisk_image_settings.image_file)
2762         self.assertEqual(openstack_tests.CIRROS_USER,
2763                          os_image_settings.ramdisk_image_settings.image_user)
2764         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2765         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2766         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2767                          os_image_settings.ramdisk_image_settings.format)
2768
2769         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2770         self.image_creator.create()
2771
2772         self.assertIsNotNone(self.image_creator.get_kernel_image())
2773         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2774
2775         instance_settings = VmInstanceConfig(
2776             name=self.vm_inst_name,
2777             flavor=self.flavor_creator.flavor_settings.name,
2778             port_settings=[self.port_settings])
2779         self.inst_creator = OpenStackVmInstance(
2780             self.os_creds, instance_settings,
2781             self.image_creator.image_settings)
2782         self.inst_creator.create()
2783
2784         self.assertTrue(self.inst_creator.vm_active(block=True))
2785
2786     def test_inst_from_file_3part_image_existing(self):
2787         """
2788         Creates a VM instance from a 3-part image that is existing
2789         :return: 
2790         """
2791         kernel_file = file_utils.download(
2792             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2793         ramdisk_file = file_utils.download(
2794             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2795
2796         metadata = {'cirros': {'disk_file': self.image_file.name,
2797                                'kernel_file': kernel_file.name,
2798                                'ramdisk_file': ramdisk_file.name}}
2799
2800         os_image_settings = openstack_tests.cirros_image_settings(
2801             name=self.image_name, image_metadata=metadata)
2802         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2803         self.image_creator.create()
2804
2805         image_settings = self.image_creator.image_settings
2806         test_image_creator = OpenStackImage(
2807             self.os_creds,
2808             ImageConfig(
2809                 name=image_settings.name, image_user=image_settings.image_user,
2810                 exists=True))
2811         test_image_creator.create()
2812         self.assertEqual(self.image_creator.get_image().id,
2813                          test_image_creator.get_image().id)
2814
2815         instance_settings = VmInstanceConfig(
2816             name=self.vm_inst_name,
2817             flavor=self.flavor_creator.flavor_settings.name,
2818             port_settings=[self.port_settings])
2819         self.inst_creator = OpenStackVmInstance(
2820             self.os_creds, instance_settings,
2821             test_image_creator.image_settings)
2822         self.inst_creator.create()
2823
2824         self.assertTrue(self.inst_creator.vm_active(block=True))
2825
2826
2827 class CreateInstanceTwoNetTests(OSIntegrationTestCase):
2828     """
2829     Tests the ability of two VMs to communicate when attached to separate
2830     private networks that are tied together with a router.
2831     """
2832
2833     def setUp(self):
2834         """
2835         Instantiates the CreateImage object that is responsible for downloading
2836         and creating an OS image file within OpenStack
2837         """
2838         super(self.__class__, self).__start__()
2839
2840         cidr1 = '10.200.201.0/24'
2841         cidr2 = '10.200.202.0/24'
2842         static_gateway_ip1 = '10.200.201.1'
2843         static_gateway_ip2 = '10.200.202.1'
2844         self.ip1 = '10.200.201.5'
2845         self.ip2 = '10.200.202.5'
2846
2847         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
2848
2849         # Initialize for tearDown()
2850         self.image_creator = None
2851         self.network_creators = list()
2852         self.router_creator = None
2853         self.flavor_creator = None
2854         self.sec_grp_creator = None
2855         self.inst_creators = list()
2856
2857         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2858         self.vm_inst1_name = self.guid + '-inst1'
2859         self.vm_inst2_name = self.guid + '-inst2'
2860         self.port_1_name = self.guid + '-vm1-port'
2861         self.port_2_name = self.guid + '-vm2-port'
2862         self.net_config_1 = NetworkConfig(
2863             name=self.guid + '-net1',
2864             subnet_settings=[
2865                 create_network.SubnetConfig(
2866                     cidr=cidr1, name=self.guid + '-subnet1',
2867                     gateway_ip=static_gateway_ip1)])
2868         self.net_config_2 = NetworkConfig(
2869             name=self.guid + '-net2',
2870             subnet_settings=[
2871                 create_network.SubnetConfig(
2872                     cidr=cidr2, name=self.guid + '-subnet2',
2873                     gateway_ip=static_gateway_ip2)])
2874
2875         image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
2876         os_image_settings = openstack_tests.cirros_image_settings(
2877             name=image_name, image_metadata=self.image_metadata)
2878
2879         try:
2880             # Create Image
2881             self.image_creator = OpenStackImage(
2882                 self.os_creds, os_image_settings)
2883             self.image_creator.create()
2884
2885             # First network is public
2886             self.network_creators.append(OpenStackNetwork(
2887                 self.os_creds, self.net_config_1))
2888
2889             # Second network is private
2890             self.network_creators.append(OpenStackNetwork(
2891                 self.os_creds, self.net_config_2))
2892             for network_creator in self.network_creators:
2893                 network_creator.create()
2894
2895             port_settings = [
2896                 PortConfig(
2897                     name=self.guid + '-router-port1',
2898                     ip_addrs=[{
2899                         'subnet_name':
2900                             self.net_config_1.subnet_settings[0].name,
2901                         'ip': static_gateway_ip1
2902                     }],
2903                     network_name=self.net_config_1.name),
2904                 PortConfig(
2905                     name=self.guid + '-router-port2',
2906                     ip_addrs=[{
2907                         'subnet_name':
2908                             self.net_config_2.subnet_settings[0].name,
2909                         'ip': static_gateway_ip2
2910                     }],
2911                     network_name=self.net_config_2.name)]
2912
2913             router_settings = RouterConfig(
2914                 name=self.guid + '-pub-router', port_settings=port_settings)
2915             self.router_creator = OpenStackRouter(
2916                 self.os_creds, router_settings)
2917             self.router_creator.create()
2918
2919             flavor_config = openstack_tests.get_flavor_config(
2920                 name=self.guid + '-flavor-name', ram=512, disk=10,
2921                 vcpus=2, metadata=self.flavor_metadata)
2922             self.flavor_creator = OpenStackFlavor(
2923                 self.admin_os_creds, flavor_config)
2924             self.flavor_creator.create()
2925
2926             self.sec_grp_name = self.guid + '-sec-grp'
2927             rule1 = SecurityGroupRuleConfig(
2928                 sec_grp_name=self.sec_grp_name, direction=Direction.ingress,
2929                 protocol=Protocol.icmp)
2930             rule2 = SecurityGroupRuleConfig(
2931                 sec_grp_name=self.sec_grp_name, direction=Direction.egress,
2932                 protocol=Protocol.icmp)
2933             self.sec_grp_creator = OpenStackSecurityGroup(
2934                 self.os_creds,
2935                 SecurityGroupConfig(
2936                     name=self.sec_grp_name, rule_settings=[rule1, rule2]))
2937             self.sec_grp_creator.create()
2938         except:
2939             self.tearDown()
2940             raise
2941
2942     def tearDown(self):
2943         """
2944         Cleans the created objects
2945         """
2946         for inst_creator in self.inst_creators:
2947             try:
2948                 inst_creator.clean()
2949             except Exception as e:
2950                 logger.error(
2951                     'Unexpected exception cleaning VM instance with message '
2952                     '- %s', e)
2953
2954         if self.flavor_creator:
2955             try:
2956                 self.flavor_creator.clean()
2957             except Exception as e:
2958                 logger.error(
2959                     'Unexpected exception cleaning flavor with message - %s',
2960                     e)
2961
2962         if self.router_creator:
2963             try:
2964                 self.router_creator.clean()
2965             except Exception as e:
2966                 logger.error(
2967                     'Unexpected exception cleaning router with message - %s',
2968                     e)
2969
2970         for network_creator in self.network_creators:
2971             try:
2972                 network_creator.clean()
2973             except Exception as e:
2974                 logger.error(
2975                     'Unexpected exception cleaning network with message - %s',
2976                     e)
2977
2978         if self.sec_grp_creator:
2979             try:
2980                 self.sec_grp_creator.clean()
2981             except Exception as e:
2982                 logger.error(
2983                     'Unexpected exception cleaning security group with message'
2984                     ' - %s', e)
2985
2986         if self.image_creator and not self.image_creator.image_settings.exists:
2987             try:
2988                 self.image_creator.clean()
2989             except Exception as e:
2990                 logger.error(
2991                     'Unexpected exception cleaning image with message - %s', e)
2992
2993         super(self.__class__, self).__clean__()
2994
2995     def test_ping_via_router(self):
2996         """
2997         Tests the creation of two OpenStack instances with one port on
2998         different private networks wit a router in between to ensure that they
2999         can ping
3000         through
3001         """
3002         # Create ports/NICs for instance
3003         ports_settings = []
3004         ctr = 1
3005         for network_creator in self.network_creators:
3006             ports_settings.append(PortConfig(
3007                 name=self.guid + '-port-' + str(ctr),
3008                 network_name=network_creator.network_settings.name))
3009             ctr += 1
3010
3011         # Configure instances
3012         instance1_settings = VmInstanceConfig(
3013             name=self.vm_inst1_name,
3014             flavor=self.flavor_creator.flavor_settings.name,
3015             userdata=_get_ping_userdata(self.ip2),
3016             security_group_names=self.sec_grp_name,
3017             port_settings=[PortConfig(
3018                 name=self.port_1_name,
3019                 ip_addrs=[{
3020                     'subnet_name':
3021                         self.net_config_1.subnet_settings[0].name,
3022                     'ip': self.ip1
3023                 }],
3024                 network_name=self.network_creators[0].network_settings.name)])
3025         instance2_settings = VmInstanceConfig(
3026             name=self.vm_inst2_name,
3027             flavor=self.flavor_creator.flavor_settings.name,
3028             userdata=_get_ping_userdata(self.ip1),
3029             security_group_names=self.sec_grp_name,
3030             port_settings=[PortConfig(
3031                 name=self.port_2_name,
3032                 ip_addrs=[{
3033                     'subnet_name':
3034                         self.net_config_2.subnet_settings[0].name,
3035                     'ip': self.ip2
3036                 }],
3037                 network_name=self.network_creators[1].network_settings.name)])
3038
3039         # Create instances
3040         self.inst_creators.append(OpenStackVmInstance(
3041             self.os_creds, instance1_settings,
3042             self.image_creator.image_settings))
3043         self.inst_creators.append(OpenStackVmInstance(
3044             self.os_creds, instance2_settings,
3045             self.image_creator.image_settings))
3046
3047         for inst_creator in self.inst_creators:
3048             inst_creator.create(block=True)
3049
3050         # Check for DHCP lease
3051         self.assertTrue(check_dhcp_lease(self.inst_creators[0], self.ip1))
3052         self.assertTrue(check_dhcp_lease(self.inst_creators[1], self.ip2))
3053
3054         # Effectively blocks until VM has been properly activated
3055         self.assertTrue(check_ping(self.inst_creators[0]))
3056         self.assertTrue(check_ping(self.inst_creators[1]))
3057
3058
3059 class CreateInstanceVolumeTests(OSIntegrationTestCase):
3060     """
3061     Simple instance creation with an attached volume
3062     """
3063
3064     def setUp(self):
3065         """
3066         Instantiates the CreateImage object that is responsible for downloading
3067         and creating an OS image file
3068         within OpenStack
3069         """
3070         super(self.__class__, self).__start__()
3071
3072         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
3073         self.vm_inst_name = guid + '-inst'
3074         self.nova = nova_utils.nova_client(
3075             self.os_creds, self.os_session)
3076         self.neutron = neutron_utils.neutron_client(
3077             self.os_creds, self.os_session)
3078         os_image_settings = openstack_tests.cirros_image_settings(
3079             name=guid + '-image', image_metadata=self.image_metadata)
3080
3081         net_config = openstack_tests.get_priv_net_config(
3082             project_name=self.os_creds.project_name,
3083             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
3084             router_name=guid + '-pub-router', external_net=self.ext_net_name,
3085             netconf_override=self.netconf_override)
3086
3087         self.volume_settings1 = VolumeConfig(
3088             name=self.__class__.__name__ + '-' + str(guid) + '-1')
3089         self.volume_settings2 = VolumeConfig(
3090             name=self.__class__.__name__ + '-' + str(guid) + '-2')
3091
3092         # Initialize for tearDown()
3093         self.image_creator = None
3094         self.flavor_creator = None
3095
3096         self.network_creator = None
3097         self.inst_creator = None
3098         self.volume_creator1 = None
3099         self.volume_creator2 = None
3100
3101         try:
3102             # Create Image
3103             self.image_creator = OpenStackImage(self.os_creds,
3104                                                 os_image_settings)
3105             self.image_creator.create()
3106
3107             # Create Flavor
3108             flavor_config = openstack_tests.get_flavor_config(
3109                 name=guid + '-flavor-name', ram=256, disk=1,
3110                 vcpus=2, metadata=self.flavor_metadata)
3111             self.flavor_creator = OpenStackFlavor(
3112                 self.admin_os_creds, flavor_config)
3113             self.flavor_creator.create()
3114
3115             # Create Network
3116             self.network_creator = OpenStackNetwork(
3117                 self.os_creds, net_config.network_settings)
3118             self.network_creator.create()
3119
3120             self.port_settings = PortConfig(
3121                 name=guid + '-port',
3122                 network_name=net_config.network_settings.name)
3123
3124             self.volume_creator1 = OpenStackVolume(
3125                 self.os_creds, self.volume_settings1)
3126             self.volume_creator1.create(block=True)
3127
3128             self.volume_creator2 = OpenStackVolume(
3129                 self.os_creds, self.volume_settings2)
3130             self.volume_creator2.create(block=True)
3131
3132         except Exception as e:
3133             self.tearDown()
3134             raise e
3135
3136     def tearDown(self):
3137         """
3138         Cleans the created object
3139         """
3140         if self.inst_creator:
3141             try:
3142                 self.inst_creator.clean()
3143             except Exception as e:
3144                 logger.error(
3145                     'Unexpected exception cleaning VM instance with message '
3146                     '- %s', e)
3147
3148         if self.flavor_creator:
3149             try:
3150                 self.flavor_creator.clean()
3151             except Exception as e:
3152                 logger.error(
3153                     'Unexpected exception cleaning flavor with message - %s',
3154                     e)
3155
3156         if self.network_creator:
3157             try:
3158                 self.network_creator.clean()
3159             except Exception as e:
3160                 logger.error(
3161                     'Unexpected exception cleaning network with message - %s',
3162                     e)
3163
3164         if self.volume_creator2:
3165             try:
3166                 self.volume_creator2.clean()
3167             except Exception as e:
3168                 logger.error(
3169                     'Unexpected exception cleaning volume with message - %s',
3170                     e)
3171
3172         if self.volume_creator1:
3173             try:
3174                 self.volume_creator1.clean()
3175             except Exception as e:
3176                 logger.error(
3177                     'Unexpected exception cleaning volume with message - %s',
3178                     e)
3179
3180         if self.image_creator and not self.image_creator.image_settings.exists:
3181             try:
3182                 self.image_creator.clean()
3183             except Exception as e:
3184                 logger.error(
3185                     'Unexpected exception cleaning image with message - %s', e)
3186
3187         super(self.__class__, self).__clean__()
3188
3189     def test_create_instance_with_one_volume(self):
3190         """
3191         Tests the creation of an OpenStack instance with a single volume.
3192         """
3193         instance_settings = VmInstanceConfig(
3194             name=self.vm_inst_name,
3195             flavor=self.flavor_creator.flavor_settings.name,
3196             port_settings=[self.port_settings],
3197             volume_names=[self.volume_settings1.name])
3198
3199         self.inst_creator = OpenStackVmInstance(
3200             self.os_creds, instance_settings,
3201             self.image_creator.image_settings)
3202
3203         vm_inst = self.inst_creator.create(block=True)
3204         self.assertIsNotNone(nova_utils.get_server(
3205             self.nova, self.neutron, self.keystone,
3206             vm_inst_settings=instance_settings))
3207
3208         self.assertIsNotNone(vm_inst)
3209         self.assertEqual(1, len(vm_inst.volume_ids))
3210         self.assertEqual(self.volume_creator1.get_volume().id,
3211                          vm_inst.volume_ids[0]['id'])
3212
3213     def test_create_instance_with_two_volumes(self):
3214         """
3215         Tests the creation of an OpenStack instance with a single volume.
3216         """
3217         instance_settings = VmInstanceConfig(
3218             name=self.vm_inst_name,
3219             flavor=self.flavor_creator.flavor_settings.name,
3220             port_settings=[self.port_settings],
3221             volume_names=[self.volume_settings1.name,
3222                           self.volume_settings2.name])
3223
3224         self.inst_creator = OpenStackVmInstance(
3225             self.os_creds, instance_settings,
3226             self.image_creator.image_settings)
3227
3228         vm_inst = self.inst_creator.create(block=True)
3229         self.assertIsNotNone(nova_utils.get_server(
3230             self.nova, self.neutron, self.keystone,
3231             vm_inst_settings=instance_settings))
3232
3233         self.assertIsNotNone(vm_inst)
3234         self.assertEqual(2, len(vm_inst.volume_ids))
3235         self.assertEqual(self.volume_creator1.get_volume().id,
3236                          vm_inst.volume_ids[0]['id'])
3237         self.assertEqual(self.volume_creator2.get_volume().id,
3238                          vm_inst.volume_ids[1]['id'])
3239
3240
3241 def check_dhcp_lease(inst_creator, ip, timeout=160):
3242     """
3243     Returns true if the expected DHCP lease has been acquired
3244     :param inst_creator: the SNAPS OpenStackVmInstance object
3245     :param ip: the IP address to look for
3246     :param timeout: how long to query for IP address
3247     :return:
3248     """
3249     found = False
3250     start_time = time.time()
3251
3252     logger.info("Looking for IP %s in the console log" % ip)
3253     full_log = ''
3254     while timeout > time.time() - start_time:
3255         output = inst_creator.get_console_output()
3256         full_log = full_log + output
3257         if re.search(ip, output):
3258             logger.info('DHCP lease obtained logged in console')
3259             found = True
3260             break
3261
3262     if not found:
3263         logger.error('Full console output -\n' + full_log)
3264     else:
3265         logger.debug('Full console output -\n' + full_log)
3266
3267     return found
3268
3269
3270 def _get_ping_userdata(test_ip):
3271     """
3272     Returns the post VM creation script to be added into the VM's userdata
3273     :param test_ip: the IP value to substitute into the script
3274     :return: the bash script contents
3275     """
3276     if test_ip:
3277         return ("#!/bin/sh\n\n"
3278                 "while true; do\n"
3279                 " ping -c 1 %s 2>&1 >/dev/null\n"
3280                 " RES=$?\n"
3281                 " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
3282                 "  echo 'vPing OK'\n"
3283                 "  break\n"
3284                 " else\n"
3285                 "  echo 'vPing KO'\n"
3286                 " fi\n"
3287                 " sleep 1\n"
3288                 "done\n" % test_ip)
3289     return None
3290
3291
3292 def check_ping(vm_creator, timeout=160):
3293     """
3294     Check for VM for ping result
3295     """
3296     tries = 0
3297
3298     while tries < timeout:
3299         time.sleep(1)
3300         p_console = vm_creator.get_console_output()
3301         if "vPing OK" in p_console:
3302             return True
3303         elif "failed to read iid from metadata" in p_console or tries > 5:
3304             return False
3305         tries += 1
3306
3307     return False