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