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