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