a45654fb3c4b2a18aed0affcb3c0ba1a03c39725
[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.image_creator and not self.image_creator.image_settings.exists:
1458             try:
1459                 self.image_creator.clean()
1460             except Exception as e:
1461                 logger.error(
1462                     'Unexpected exception cleaning image with message - %s', e)
1463
1464         super(self.__class__, self).__clean__()
1465
1466     def test_set_custom_valid_ip_one_subnet(self):
1467         """
1468         Tests the creation of an OpenStack instance with a single port with a
1469         static IP on a network with one subnet.
1470         """
1471         ip = '10.55.0.101'
1472         sub_settings = self.net_config.network_settings.subnet_settings
1473         port_settings = PortConfig(
1474             name=self.port_1_name,
1475             network_name=self.net_config.network_settings.name,
1476             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1477
1478         instance_settings = VmInstanceConfig(
1479             name=self.vm_inst_name,
1480             flavor=self.flavor_creator.flavor_settings.name,
1481             port_settings=[port_settings])
1482
1483         self.inst_creator = OpenStackVmInstance(
1484             self.os_creds, instance_settings,
1485             self.image_creator.image_settings)
1486         self.inst_creator.create(block=True)
1487
1488         self.assertEqual(ip, self.inst_creator.get_port_ip(
1489             self.port_1_name,
1490             subnet_name=self.net_config.network_settings.subnet_settings[
1491                 0].name))
1492
1493     def test_set_one_port_two_ip_one_subnet(self):
1494         """
1495         Tests the creation of an OpenStack instance with a single port with a
1496         two static IPs on a network with one subnet.
1497         """
1498         ip1 = '10.55.0.101'
1499         ip2 = '10.55.0.102'
1500         sub_settings = self.net_config.network_settings.subnet_settings
1501         port_settings = PortConfig(
1502             name=self.port_1_name,
1503             network_name=self.net_config.network_settings.name,
1504             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip1},
1505                       {'subnet_name': sub_settings[0].name, 'ip': ip2}])
1506
1507         instance_settings = VmInstanceConfig(
1508             name=self.vm_inst_name,
1509             flavor=self.flavor_creator.flavor_settings.name,
1510             port_settings=[port_settings])
1511
1512         self.inst_creator = OpenStackVmInstance(
1513             self.os_creds, instance_settings,
1514             self.image_creator.image_settings)
1515         vm_inst = self.inst_creator.create(block=True)
1516
1517         self.assertEqual(ip1, vm_inst.ports[0].ips[0]['ip_address'])
1518         self.assertEqual(self.network_creator.get_network().subnets[0].id,
1519                          vm_inst.ports[0].ips[0]['subnet_id'])
1520         self.assertEqual(ip2, vm_inst.ports[0].ips[1]['ip_address'])
1521         self.assertEqual(self.network_creator.get_network().subnets[0].id,
1522                          vm_inst.ports[0].ips[1]['subnet_id'])
1523
1524     def test_set_one_port_two_ip_two_subnets(self):
1525         """
1526         Tests the creation of an OpenStack instance with a single port with a
1527         two static IPs on a network with one subnet.
1528         """
1529         net2_config = NetworkConfig(
1530             name=self.guid + 'net2', subnets=[
1531                 SubnetConfig(name=self.guid + '-subnet1', cidr='10.55.0.0/24'),
1532                 SubnetConfig(name=self.guid + '-subnet2', cidr='10.65.0.0/24'),
1533             ])
1534
1535         # Create Network
1536         self.network_creator2 = OpenStackNetwork(self.os_creds, net2_config)
1537         net2 = self.network_creator2.create()
1538
1539         ip1 = '10.55.0.101'
1540         ip2 = '10.65.0.101'
1541
1542         port_settings = PortConfig(
1543             name=self.port_1_name,
1544             network_name=net2_config.name,
1545             ip_addrs=[
1546                 {'subnet_name': net2_config.subnet_settings[0].name,
1547                  'ip': ip1},
1548                 {'subnet_name': net2_config.subnet_settings[1].name,
1549                  'ip': ip2}])
1550
1551         instance_settings = VmInstanceConfig(
1552             name=self.vm_inst_name,
1553             flavor=self.flavor_creator.flavor_settings.name,
1554             port_settings=[port_settings])
1555
1556         self.inst_creator = OpenStackVmInstance(
1557             self.os_creds, instance_settings,
1558             self.image_creator.image_settings)
1559         vm_inst = self.inst_creator.create(block=True)
1560
1561         subnet1_id = None
1562         subnet2_id = None
1563         for subnet in net2.subnets:
1564             if subnet.name == net2_config.subnet_settings[0].name:
1565                 subnet1_id = subnet.id
1566             if subnet.name == net2_config.subnet_settings[1].name:
1567                 subnet2_id = subnet.id
1568         self.assertEqual(ip1, vm_inst.ports[0].ips[0]['ip_address'])
1569         self.assertEqual(subnet1_id, vm_inst.ports[0].ips[0]['subnet_id'])
1570         self.assertEqual(ip2, vm_inst.ports[0].ips[1]['ip_address'])
1571         self.assertEqual(subnet2_id, vm_inst.ports[0].ips[1]['subnet_id'])
1572
1573     def test_set_custom_invalid_ip_one_subnet(self):
1574         """
1575         Tests the creation of an OpenStack instance with a single port with a
1576         static IP on a network with one subnet.
1577         """
1578         ip = '10.66.0.101'
1579         sub_settings = self.net_config.network_settings.subnet_settings
1580         port_settings = PortConfig(
1581             name=self.port_1_name,
1582             network_name=self.net_config.network_settings.name,
1583             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1584
1585         instance_settings = VmInstanceConfig(
1586             name=self.vm_inst_name,
1587             flavor=self.flavor_creator.flavor_settings.name,
1588             port_settings=[port_settings])
1589
1590         self.inst_creator = OpenStackVmInstance(
1591             self.os_creds, instance_settings,
1592             self.image_creator.image_settings)
1593
1594         with self.assertRaises(InvalidIpForSubnetClient):
1595             self.inst_creator.create()
1596
1597     def test_set_custom_valid_mac(self):
1598         """
1599         Tests the creation of an OpenStack instance with a single port where
1600         the MAC address is assigned.
1601         """
1602         mac_addr = '0a:1b:2c:3d:4e:5f'
1603         port_settings = PortConfig(
1604             name=self.port_1_name,
1605             network_name=self.net_config.network_settings.name,
1606             mac_address=mac_addr)
1607
1608         instance_settings = VmInstanceConfig(
1609             name=self.vm_inst_name,
1610             flavor=self.flavor_creator.flavor_settings.name,
1611             port_settings=[port_settings])
1612
1613         self.inst_creator = OpenStackVmInstance(
1614             self.os_creds, instance_settings,
1615             self.image_creator.image_settings)
1616         self.inst_creator.create(block=True)
1617
1618         self.assertEqual(mac_addr,
1619                          self.inst_creator.get_port_mac(self.port_1_name))
1620
1621     def test_set_custom_invalid_mac(self):
1622         """
1623         Tests the creation of an OpenStack instance with a single port where an
1624         invalid MAC address value is being
1625         assigned. This should raise an Exception
1626         """
1627         port_settings = PortConfig(
1628             name=self.port_1_name,
1629             network_name=self.net_config.network_settings.name,
1630             mac_address='foo')
1631
1632         instance_settings = VmInstanceConfig(
1633             name=self.vm_inst_name,
1634             flavor=self.flavor_creator.flavor_settings.name,
1635             port_settings=[port_settings])
1636
1637         self.inst_creator = OpenStackVmInstance(
1638             self.os_creds, instance_settings,
1639             self.image_creator.image_settings)
1640
1641         with self.assertRaises(Exception):
1642             self.inst_creator.create()
1643
1644     def test_set_custom_mac_and_ip(self):
1645         """
1646         Tests the creation of an OpenStack instance with a single port where
1647         the IP and MAC address is assigned.
1648         """
1649         ip = '10.55.0.101'
1650         mac_addr = '0a:1b:2c:3d:4e:5f'
1651         sub_settings = self.net_config.network_settings.subnet_settings
1652         port_settings = PortConfig(
1653             name=self.port_1_name,
1654             network_name=self.net_config.network_settings.name,
1655             mac_address=mac_addr,
1656             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1657
1658         instance_settings = VmInstanceConfig(
1659             name=self.vm_inst_name,
1660             flavor=self.flavor_creator.flavor_settings.name,
1661             port_settings=[port_settings])
1662
1663         self.inst_creator = OpenStackVmInstance(
1664             self.os_creds, instance_settings,
1665             self.image_creator.image_settings)
1666         self.inst_creator.create(block=True)
1667
1668         self.assertEqual(ip, self.inst_creator.get_port_ip(
1669             self.port_1_name,
1670             subnet_name=self.net_config.network_settings.subnet_settings[
1671                 0].name))
1672         self.assertEqual(mac_addr,
1673                          self.inst_creator.get_port_mac(self.port_1_name))
1674
1675     def test_set_allowed_address_pairs(self):
1676         """
1677         Tests the creation of an OpenStack instance with a single port where
1678         max_allowed_address_pair is set.
1679         """
1680         ip = '10.55.0.101'
1681         mac_addr = '0a:1b:2c:3d:4e:5f'
1682         pair = {'ip_address': ip, 'mac_address': mac_addr}
1683         port_settings = PortConfig(
1684             name=self.port_1_name,
1685             network_name=self.net_config.network_settings.name,
1686             allowed_address_pairs=[pair])
1687
1688         instance_settings = VmInstanceConfig(
1689             name=self.vm_inst_name,
1690             flavor=self.flavor_creator.flavor_settings.name,
1691             port_settings=[port_settings])
1692
1693         self.inst_creator = OpenStackVmInstance(
1694             self.os_creds, instance_settings,
1695             self.image_creator.image_settings)
1696         self.inst_creator.create(block=True)
1697
1698         port = self.inst_creator.get_port_by_name(port_settings.name)
1699         self.assertIsNotNone(port)
1700         self.assertIsNotNone(port.allowed_address_pairs)
1701         self.assertEqual(1, len(port.allowed_address_pairs))
1702         validation_utils.objects_equivalent(pair,
1703                                             port.allowed_address_pairs[0])
1704
1705     def test_set_allowed_address_pairs_bad_mac(self):
1706         """
1707         Tests the creation of an OpenStack instance with a single port where
1708         max_allowed_address_pair is set with an invalid MAC address.
1709         """
1710         ip = '10.55.0.101'
1711         mac_addr = 'foo'
1712         pair = {'ip_address': ip, 'mac_address': mac_addr}
1713         pairs = set()
1714         pairs.add((ip, mac_addr))
1715         port_settings = PortConfig(
1716             name=self.port_1_name,
1717             network_name=self.net_config.network_settings.name,
1718             allowed_address_pairs=[pair])
1719
1720         instance_settings = VmInstanceConfig(
1721             name=self.vm_inst_name,
1722             flavor=self.flavor_creator.flavor_settings.name,
1723             port_settings=[port_settings])
1724
1725         self.inst_creator = OpenStackVmInstance(
1726             self.os_creds, instance_settings,
1727             self.image_creator.image_settings)
1728         with self.assertRaises(Exception):
1729             self.inst_creator.create()
1730
1731     def test_set_allowed_address_pairs_bad_ip(self):
1732         """
1733         Tests the creation of an OpenStack instance with a single port where
1734         max_allowed_address_pair is set with an invalid MAC address.
1735         """
1736         ip = 'foo'
1737         mac_addr = '0a:1b:2c:3d:4e:5f'
1738         pair = {'ip_address': ip, 'mac_address': mac_addr}
1739         pairs = set()
1740         pairs.add((ip, mac_addr))
1741         port_settings = PortConfig(
1742             name=self.port_1_name,
1743             network_name=self.net_config.network_settings.name,
1744             allowed_address_pairs=[pair])
1745
1746         instance_settings = VmInstanceConfig(
1747             name=self.vm_inst_name,
1748             flavor=self.flavor_creator.flavor_settings.name,
1749             port_settings=[port_settings])
1750
1751         self.inst_creator = OpenStackVmInstance(
1752             self.os_creds, instance_settings,
1753             self.image_creator.image_settings)
1754         with self.assertRaises(Exception):
1755             self.inst_creator.create()
1756
1757
1758 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1759     """
1760     Test for the CreateInstance where one VM is deployed to each compute node
1761     """
1762
1763     def setUp(self):
1764         """
1765         Instantiates the CreateImage object that is responsible for downloading
1766         and creating an OS image file within OpenStack
1767         """
1768         super(self.__class__, self).__start__()
1769
1770         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1771         self.vm_inst_name = guid + '-inst'
1772         self.port_base_name = guid + 'port'
1773
1774         # Initialize for tearDown()
1775         self.image_creator = None
1776         self.flavor_creator = None
1777         self.network_creator = None
1778         self.inst_creators = list()
1779
1780         self.priv_net_config = openstack_tests.get_priv_net_config(
1781             project_name=self.os_creds.project_name,
1782             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet',
1783             netconf_override=self.netconf_override)
1784
1785         os_image_settings = openstack_tests.cirros_image_settings(
1786             name=guid + '-image', image_metadata=self.image_metadata)
1787
1788         try:
1789             # Create Network
1790             self.network_creator = OpenStackNetwork(
1791                 self.admin_os_creds, self.priv_net_config.network_settings)
1792             self.network_creator.create()
1793
1794             # Create Flavor
1795             flavor_config = openstack_tests.get_flavor_config(
1796                 name=guid + '-flavor-name', ram=512, disk=1,
1797                 vcpus=1, metadata=self.flavor_metadata)
1798             self.flavor_creator = OpenStackFlavor(
1799                 self.admin_os_creds, flavor_config)
1800             self.flavor_creator.create()
1801
1802             # Create Image
1803             self.image_creator = OpenStackImage(self.os_creds,
1804                                                 os_image_settings)
1805             self.image_creator.create()
1806
1807         except Exception as e:
1808             self.tearDown()
1809             raise e
1810
1811     def tearDown(self):
1812         """
1813         Cleans the created object
1814         """
1815         for inst_creator in self.inst_creators:
1816             try:
1817                 inst_creator.clean()
1818             except Exception as e:
1819                 logger.error(
1820                     'Unexpected exception cleaning VM instance with message '
1821                     '- %s', e)
1822
1823         if self.flavor_creator:
1824             try:
1825                 self.flavor_creator.clean()
1826             except Exception as e:
1827                 logger.error(
1828                     'Unexpected exception cleaning flavor with message - %s',
1829                     e)
1830
1831         if self.network_creator:
1832             try:
1833                 self.network_creator.clean()
1834             except Exception as e:
1835                 logger.error(
1836                     'Unexpected exception cleaning network with message - %s',
1837                     e)
1838
1839         if self.image_creator and not self.image_creator.image_settings.exists:
1840             try:
1841                 self.image_creator.clean()
1842             except Exception as e:
1843                 logger.error(
1844                     'Unexpected exception cleaning image with message - %s', e)
1845
1846         super(self.__class__, self).__clean__()
1847
1848     def test_deploy_vm_to_each_compute_node(self):
1849         """
1850         Tests the creation of OpenStack VM instances to each compute node.
1851         """
1852         from snaps.openstack.utils import nova_utils
1853         nova = nova_utils.nova_client(
1854             self.admin_os_creds, self.admin_os_session)
1855         zone_hosts = nova_utils.get_availability_zone_hosts(nova)
1856
1857         # Create Instance on each server/zone
1858         ctr = 0
1859         for zone in zone_hosts:
1860             inst_name = self.vm_inst_name + '-' + zone
1861             ctr += 1
1862             port_settings = PortConfig(
1863                 name=self.port_base_name + '-' + str(ctr),
1864                 network_name=self.priv_net_config.network_settings.name)
1865
1866             instance_settings = VmInstanceConfig(
1867                 name=inst_name,
1868                 flavor=self.flavor_creator.flavor_settings.name,
1869                 availability_zone=zone,
1870                 port_settings=[port_settings])
1871             inst_creator = OpenStackVmInstance(
1872                 self.admin_os_creds, instance_settings,
1873                 self.image_creator.image_settings)
1874             self.inst_creators.append(inst_creator)
1875             inst_creator.create(block=True)
1876             avail_zone = inst_creator.get_vm_inst().availability_zone
1877             self.assertTrue(avail_zone in zone)
1878             compute_host = inst_creator.get_vm_inst().compute_host
1879             self.assertTrue(compute_host in zone)
1880
1881         # Validate instances to ensure they've been deployed to the correct
1882         # server
1883         index = 0
1884         for zone in zone_hosts:
1885             creator = self.inst_creators[index]
1886             self.assertTrue(creator.vm_active(block=True))
1887             info = creator.get_vm_info()
1888             deployed_zone = info['OS-EXT-AZ:availability_zone']
1889             deployed_host = info['OS-EXT-SRV-ATTR:host']
1890             self.assertEqual(zone, deployed_zone + ':' + deployed_host)
1891             index += 1
1892
1893
1894 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1895     """
1896     Tests that include, add, and remove security groups from VM instances
1897     """
1898
1899     def setUp(self):
1900         """
1901         Instantiates the CreateImage object that is responsible for downloading
1902         and creating an OS image file within OpenStack
1903         """
1904         super(self.__class__, self).__start__()
1905
1906         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1907         self.vm_inst_name = self.guid + '-inst'
1908         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
1909         os_image_settings = openstack_tests.cirros_image_settings(
1910             name=self.guid + '-image', image_metadata=self.image_metadata)
1911
1912         self.vm_inst_name = self.guid + '-inst'
1913         self.port_1_name = self.guid + 'port-1'
1914         self.port_2_name = self.guid + 'port-2'
1915         self.floating_ip_name = self.guid + 'fip1'
1916
1917         net_config = openstack_tests.get_priv_net_config(
1918             project_name=self.os_creds.project_name,
1919             net_name=self.guid + '-pub-net',
1920             subnet_name=self.guid + '-pub-subnet',
1921             router_name=self.guid + '-pub-router',
1922             external_net=self.ext_net_name,
1923             netconf_override=self.netconf_override)
1924
1925         # Initialize for tearDown()
1926         self.image_creator = None
1927         self.flavor_creator = None
1928         self.network_creator = None
1929         self.router_creator = None
1930         self.inst_creator = None
1931         self.sec_grp_creators = list()
1932
1933         try:
1934             # Create Image
1935             self.image_creator = OpenStackImage(self.os_creds,
1936                                                 os_image_settings)
1937             self.image_creator.create()
1938
1939             # Create Network
1940             self.network_creator = OpenStackNetwork(
1941                 self.os_creds, net_config.network_settings)
1942             self.network_creator.create()
1943
1944             # Create Flavor
1945             flavor_config = openstack_tests.get_flavor_config(
1946                 name=self.guid + '-flavor-name', ram=256, disk=10,
1947                 vcpus=2, metadata=self.flavor_metadata)
1948             self.flavor_creator = OpenStackFlavor(
1949                 self.admin_os_creds, flavor_config)
1950             self.flavor_creator.create()
1951
1952             self.port_settings = PortConfig(
1953                 name=self.guid + '-port',
1954                 network_name=net_config.network_settings.name)
1955         except Exception as e:
1956             self.tearDown()
1957             raise e
1958
1959     def tearDown(self):
1960         """
1961         Cleans the created object
1962         """
1963         if self.inst_creator:
1964             try:
1965                 self.inst_creator.clean()
1966             except Exception as e:
1967                 logger.error(
1968                     'Unexpected exception cleaning VM instance with message -'
1969                     ' %s', e)
1970
1971         for sec_grp_creator in self.sec_grp_creators:
1972             try:
1973                 sec_grp_creator.clean()
1974             except Exception as e:
1975                 logger.error(
1976                     'Unexpected exception cleaning security group with message'
1977                     ' - %s', e)
1978
1979         if self.flavor_creator:
1980             try:
1981                 self.flavor_creator.clean()
1982             except Exception as e:
1983                 logger.error(
1984                     'Unexpected exception cleaning flavor with message - %s',
1985                     e)
1986
1987         if self.network_creator:
1988             try:
1989                 self.network_creator.clean()
1990             except Exception as e:
1991                 logger.error(
1992                     'Unexpected exception cleaning network with message - %s',
1993                     e)
1994
1995         if self.image_creator and not self.image_creator.image_settings.exists:
1996             try:
1997                 self.image_creator.clean()
1998             except Exception as e:
1999                 logger.error(
2000                     'Unexpected exception cleaning image with message - %s', e)
2001
2002         super(self.__class__, self).__clean__()
2003
2004     def test_add_security_group(self):
2005         """
2006         Tests the addition of a security group created after the instance.
2007         """
2008         # Create instance
2009         instance_settings = VmInstanceConfig(
2010             name=self.vm_inst_name,
2011             flavor=self.flavor_creator.flavor_settings.name,
2012             port_settings=[self.port_settings])
2013         self.inst_creator = OpenStackVmInstance(
2014             self.os_creds, instance_settings,
2015             self.image_creator.image_settings)
2016         vm_inst = self.inst_creator.create(block=True)
2017         self.assertIsNotNone(vm_inst)
2018
2019         # Create security group object to add to instance
2020         sec_grp_settings = SecurityGroupConfig(
2021             name=self.guid + '-name', description='hello group')
2022         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2023                                                  sec_grp_settings)
2024         sec_grp = sec_grp_creator.create()
2025         self.sec_grp_creators.append(sec_grp_creator)
2026
2027         # Check that group has not been added
2028         self.assertFalse(inst_has_sec_grp(
2029             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2030
2031         # Add security group to instance after activated
2032         self.inst_creator.add_security_group(sec_grp)
2033
2034         # Validate that security group has been added
2035         self.assertTrue(inst_has_sec_grp(
2036             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2037
2038     def test_add_invalid_security_group(self):
2039         """
2040         Tests the addition of a security group that no longer exists.
2041         """
2042         # Create instance
2043         instance_settings = VmInstanceConfig(
2044             name=self.vm_inst_name,
2045             flavor=self.flavor_creator.flavor_settings.name,
2046             port_settings=[self.port_settings])
2047         self.inst_creator = OpenStackVmInstance(
2048             self.os_creds, instance_settings,
2049             self.image_creator.image_settings)
2050         vm_inst = self.inst_creator.create(block=True)
2051         self.assertIsNotNone(vm_inst)
2052
2053         # Create security group object to add to instance
2054         sec_grp_settings = SecurityGroupConfig(
2055             name=self.guid + '-name', description='hello group')
2056         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2057                                                  sec_grp_settings)
2058         sec_grp = sec_grp_creator.create()
2059         sec_grp_creator.clean()
2060         self.sec_grp_creators.append(sec_grp_creator)
2061
2062         # Check that group has not been added
2063         self.assertFalse(inst_has_sec_grp(
2064             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2065
2066         # Add security group to instance after activated
2067         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
2068
2069         # Validate that security group has been added
2070         self.assertFalse(inst_has_sec_grp(
2071             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2072
2073     def test_remove_security_group(self):
2074         """
2075         Tests the removal of a security group created before and added to the
2076         instance.
2077         """
2078         # Create security group object to add to instance
2079         sec_grp_settings = SecurityGroupConfig(
2080             name=self.guid + '-name', description='hello group')
2081         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2082                                                  sec_grp_settings)
2083         sec_grp = sec_grp_creator.create()
2084         self.sec_grp_creators.append(sec_grp_creator)
2085
2086         # Create instance
2087         instance_settings = VmInstanceConfig(
2088             name=self.vm_inst_name,
2089             flavor=self.flavor_creator.flavor_settings.name,
2090             security_group_names=[sec_grp_settings.name],
2091             port_settings=[self.port_settings])
2092         self.inst_creator = OpenStackVmInstance(
2093             self.os_creds, instance_settings,
2094             self.image_creator.image_settings)
2095         vm_inst = self.inst_creator.create(block=True)
2096         self.assertIsNotNone(vm_inst)
2097
2098         # Check that group has been added
2099         self.assertTrue(inst_has_sec_grp(
2100             self.nova, vm_inst, sec_grp_settings.name))
2101
2102         # Add security group to instance after activated
2103         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
2104
2105         # Validate that security group has been added
2106         self.assertFalse(inst_has_sec_grp(
2107             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2108
2109     def test_remove_security_group_never_added(self):
2110         """
2111         Tests the removal of a security group that was never added in the first
2112         place.
2113         """
2114         # Create security group object to add to instance
2115         sec_grp_settings = SecurityGroupConfig(
2116             name=self.guid + '-name', description='hello group')
2117         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2118                                                  sec_grp_settings)
2119         sec_grp = sec_grp_creator.create()
2120         self.sec_grp_creators.append(sec_grp_creator)
2121
2122         # Create instance
2123         instance_settings = VmInstanceConfig(
2124             name=self.vm_inst_name,
2125             flavor=self.flavor_creator.flavor_settings.name,
2126             port_settings=[self.port_settings])
2127         self.inst_creator = OpenStackVmInstance(
2128             self.os_creds, instance_settings,
2129             self.image_creator.image_settings)
2130         vm_inst = self.inst_creator.create(block=True)
2131         self.assertIsNotNone(vm_inst)
2132
2133         # Check that group has been added
2134         self.assertFalse(inst_has_sec_grp(
2135             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2136
2137         # Add security group to instance after activated
2138         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
2139
2140         # Validate that security group has been added
2141         self.assertFalse(inst_has_sec_grp(
2142             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2143
2144     def test_add_same_security_group(self):
2145         """
2146         Tests the addition of a security group created before add added to the
2147         instance.
2148         """
2149         # Create security group object to add to instance
2150         sec_grp_settings = SecurityGroupConfig(
2151             name=self.guid + '-name', description='hello group')
2152         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2153                                                  sec_grp_settings)
2154         sec_grp = sec_grp_creator.create()
2155         self.sec_grp_creators.append(sec_grp_creator)
2156
2157         # Create instance
2158         instance_settings = VmInstanceConfig(
2159             name=self.vm_inst_name,
2160             flavor=self.flavor_creator.flavor_settings.name,
2161             security_group_names=[sec_grp_settings.name],
2162             port_settings=[self.port_settings])
2163         self.inst_creator = OpenStackVmInstance(
2164             self.os_creds, instance_settings,
2165             self.image_creator.image_settings)
2166         vm_inst = self.inst_creator.create(block=True)
2167         self.assertIsNotNone(vm_inst)
2168
2169         # Check that group has been added
2170         self.assertTrue(inst_has_sec_grp(
2171             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2172
2173         # Add security group to instance after activated
2174         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
2175
2176         # Validate that security group has been added
2177         self.assertTrue(inst_has_sec_grp(
2178             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2179
2180
2181 def inst_has_sec_grp(nova, vm_inst, sec_grp_name):
2182     """
2183     Returns true if instance has a security group of a given name
2184     :param nova: the nova client
2185     :param vm_inst: the VmInst domain object
2186     :param sec_grp_name: the name of the security group to validate
2187     :return: T/F
2188     """
2189     sec_grp_names = nova_utils.get_server_security_group_names(nova, vm_inst)
2190     for name in sec_grp_names:
2191         if sec_grp_name == name:
2192             return True
2193     return False
2194
2195
2196 def validate_ssh_client(instance_creator, fip_name=None):
2197     """
2198     Returns True if instance_creator returns an SSH client that is valid
2199     :param instance_creator: the object responsible for creating the VM
2200                              instance
2201     :param fip_name: the name of the floating IP to use
2202     :return: T/F
2203     """
2204     ssh_active = instance_creator.vm_ssh_active(block=True)
2205
2206     if ssh_active:
2207         ssh_client = instance_creator.ssh_client(fip_name=fip_name)
2208         if ssh_client:
2209             try:
2210                 out = ssh_client.exec_command('pwd')[1]
2211                 channel = out.channel
2212                 in_buffer = channel.in_buffer
2213                 pwd_out = in_buffer.read(1024)
2214                 if not pwd_out or len(pwd_out) < 10:
2215                     return False
2216                 return True
2217             finally:
2218                 ssh_client.close()
2219         else:
2220             return False
2221
2222     return False
2223
2224
2225 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
2226     """
2227     Test for the CreateInstance class for creating an image from a 3-part image
2228     """
2229
2230     def setUp(self):
2231         """
2232         Instantiates the CreateImage object that is responsible for downloading
2233         and creating an OS image file within OpenStack
2234         """
2235         super(self.__class__, self).__start__()
2236
2237         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2238         self.image_name = guid
2239         self.vm_inst_name = guid + '-inst'
2240         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
2241
2242         net_config = openstack_tests.get_priv_net_config(
2243             project_name=self.os_creds.project_name,
2244             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
2245             router_name=guid + '-pub-router', external_net=self.ext_net_name,
2246             netconf_override=self.netconf_override)
2247
2248         # Initialize for tearDown()
2249         self.image_creator = None
2250         self.network_creator = None
2251         self.flavor_creator = None
2252         self.inst_creator = None
2253
2254         try:
2255             if self.image_metadata and 'disk_file' in self.image_metadata:
2256                 metadata = self.image_metadata
2257             elif self.image_metadata and 'cirros' in self.image_metadata \
2258                     and 'disk_file' in self.image_metadata['cirros']:
2259                 metadata = self.image_metadata['cirros']
2260             else:
2261                 metadata = {
2262                     'disk_url': openstack_tests.CIRROS_DEFAULT_IMAGE_URL,
2263                     'kernel_url':
2264                         openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL,
2265                     'ramdisk_url':
2266                         openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL}
2267
2268             image_settings = openstack_tests.cirros_image_settings(
2269                 name=self.image_name,
2270                 image_metadata=metadata)
2271
2272             if not image_settings.ramdisk_image_settings or not \
2273                     image_settings.kernel_image_settings:
2274                 logger.warn(
2275                     '3 Part image will not be tested. Image metadata has '
2276                     'overridden this functionality')
2277
2278             self.image_creator = OpenStackImage(self.os_creds, image_settings)
2279             self.image_creator.create()
2280
2281             # Create Flavor
2282             flavor_config = openstack_tests.get_flavor_config(
2283                 name=guid + '-flavor-name', ram=256, disk=10,
2284                 vcpus=2, metadata=self.flavor_metadata)
2285             self.flavor_creator = OpenStackFlavor(
2286                 self.admin_os_creds, flavor_config)
2287             self.flavor_creator.create()
2288
2289             # Create Network
2290             self.network_creator = OpenStackNetwork(
2291                 self.os_creds, net_config.network_settings)
2292             self.network_creator.create()
2293
2294             self.port_settings = PortConfig(
2295                 name=guid + '-port',
2296                 network_name=net_config.network_settings.name)
2297         except Exception as e:
2298             self.tearDown()
2299             raise e
2300
2301     def tearDown(self):
2302         """
2303         Cleans the created object
2304         """
2305         if self.inst_creator:
2306             try:
2307                 self.inst_creator.clean()
2308             except Exception as e:
2309                 logger.error(
2310                     'Unexpected exception cleaning VM instance with message -'
2311                     ' %s', e)
2312
2313         if self.flavor_creator:
2314             try:
2315                 self.flavor_creator.clean()
2316             except Exception as e:
2317                 logger.error(
2318                     'Unexpected exception cleaning flavor with message - %s',
2319                     e)
2320
2321         if self.network_creator:
2322             try:
2323                 self.network_creator.clean()
2324             except Exception as e:
2325                 logger.error(
2326                     'Unexpected exception cleaning network with message - %s',
2327                     e)
2328
2329         if self.image_creator and not self.image_creator.image_settings.exists:
2330             try:
2331                 self.image_creator.clean()
2332             except Exception as e:
2333                 logger.error(
2334                     'Unexpected exception cleaning image with message - %s', e)
2335
2336         super(self.__class__, self).__clean__()
2337
2338     def test_create_instance_from_three_part_image(self):
2339         """
2340         Tests the creation of an OpenStack instance from a 3-part image.
2341         """
2342         instance_settings = VmInstanceConfig(
2343             name=self.vm_inst_name,
2344             flavor=self.flavor_creator.flavor_settings.name,
2345             port_settings=[self.port_settings])
2346
2347         # The last created image is the main image from which we create the
2348         # instance
2349         self.inst_creator = OpenStackVmInstance(
2350             self.os_creds, instance_settings,
2351             self.image_creator.image_settings)
2352
2353         vm_inst = self.inst_creator.create()
2354         self.assertIsNotNone(vm_inst)
2355         self.assertTrue(self.inst_creator.vm_active(block=True))
2356
2357
2358 class CreateInstanceMockOfflineTests(OSComponentTestCase):
2359     """
2360     Tests the custom image_metadata that can be set by clients for handling
2361     images differently than the default behavior of the existing tests
2362     primarily for offline testing
2363     """
2364
2365     def setUp(self):
2366         """
2367         Instantiates the CreateImage object that is responsible for downloading
2368         and creating an OS image file within OpenStack
2369         """
2370         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2371
2372         self.tmpDir = 'tmp/' + str(self.guid)
2373         if not os.path.exists(self.tmpDir):
2374             os.makedirs(self.tmpDir)
2375
2376         self.image_name = self.guid + '-image'
2377         self.vm_inst_name = self.guid + '-inst'
2378         self.port_1_name = self.guid + 'port-1'
2379
2380         # Initialize for tearDown()
2381         self.image_creator = None
2382         self.network_creator = None
2383         self.flavor_creator = None
2384         self.inst_creator = None
2385
2386         self.priv_net_config = openstack_tests.get_priv_net_config(
2387             project_name=self.os_creds.project_name,
2388             net_name=self.guid + '-priv-net',
2389             subnet_name=self.guid + '-priv-subnet')
2390         self.port_settings = PortConfig(
2391             name=self.port_1_name,
2392             network_name=self.priv_net_config.network_settings.name)
2393
2394         try:
2395             # Download image file
2396             self.image_file = file_utils.download(
2397                 openstack_tests.CIRROS_DEFAULT_IMAGE_URL, self.tmpDir)
2398
2399             # Create Network
2400             self.network_creator = OpenStackNetwork(
2401                 self.os_creds, self.priv_net_config.network_settings)
2402             self.network_creator.create()
2403
2404             # Create Flavor
2405             flavor_config = openstack_tests.get_flavor_config(
2406                 name=self.guid + '-flavor-name', ram=256, disk=10,
2407                 vcpus=2, metadata=self.flavor_metadata)
2408             self.flavor_creator = OpenStackFlavor(
2409                 self.os_creds, flavor_config)
2410             self.flavor_creator.create()
2411         except Exception as e:
2412             self.tearDown()
2413             raise e
2414
2415     def tearDown(self):
2416         """
2417         Cleans the created object
2418         """
2419         if self.inst_creator:
2420             try:
2421                 self.inst_creator.clean()
2422             except Exception as e:
2423                 logger.error(
2424                     'Unexpected exception cleaning VM instance with message - '
2425                     '%s', e)
2426
2427         if self.network_creator:
2428             try:
2429                 self.network_creator.clean()
2430             except Exception as e:
2431                 logger.error(
2432                     'Unexpected exception cleaning network with message - %s',
2433                     e)
2434
2435         if self.flavor_creator:
2436             try:
2437                 self.flavor_creator.clean()
2438             except Exception as e:
2439                 logger.error(
2440                     'Unexpected exception cleaning flavor with message - %s',
2441                     e)
2442
2443         if self.image_creator:
2444             try:
2445                 self.image_creator.clean()
2446             except Exception as e:
2447                 logger.error(
2448                     'Unexpected exception cleaning image with message - %s', e)
2449
2450         if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir):
2451             shutil.rmtree(self.tmpDir)
2452
2453         super(self.__class__, self).__clean__()
2454
2455     def test_inst_from_file_image_simple_flat(self):
2456         """
2457         Creates a VM instance from a locally sourced file image using simply
2458         the 'disk_file' attribute vs. using the 'config' option which
2459         completely overrides all image settings
2460         :return: 
2461         """
2462         metadata = {'disk_file': self.image_file.name}
2463
2464         os_image_settings = openstack_tests.cirros_image_settings(
2465             name=self.image_name, image_metadata=metadata)
2466         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2467         self.assertEqual(openstack_tests.CIRROS_USER,
2468                          os_image_settings.image_user)
2469         self.assertIsNone(os_image_settings.url)
2470         self.assertFalse(os_image_settings.exists)
2471         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2472                          os_image_settings.format)
2473
2474         self.assertIsNone(os_image_settings.kernel_image_settings)
2475         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2476
2477         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2478         self.image_creator.create()
2479
2480         instance_settings = VmInstanceConfig(
2481             name=self.vm_inst_name,
2482             flavor=self.flavor_creator.flavor_settings.name,
2483             port_settings=[self.port_settings])
2484         self.inst_creator = OpenStackVmInstance(
2485             self.os_creds, instance_settings,
2486             self.image_creator.image_settings)
2487         self.inst_creator.create()
2488
2489         self.assertTrue(self.inst_creator.vm_active(block=True))
2490
2491     def test_inst_from_file_image_simple_nested(self):
2492         """
2493         Creates a VM instance from a locally sourced file image using simply
2494         the 'disk_file' attribute under 'cirros' vs. using the 'config' option
2495         which completely overrides all image settings
2496         :return: 
2497         """
2498         metadata = {'cirros': {'disk_file': self.image_file.name}}
2499
2500         os_image_settings = openstack_tests.cirros_image_settings(
2501             name=self.image_name, image_metadata=metadata)
2502         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2503         self.assertEqual(openstack_tests.CIRROS_USER,
2504                          os_image_settings.image_user)
2505         self.assertIsNone(os_image_settings.url)
2506         self.assertFalse(os_image_settings.exists)
2507         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2508                          os_image_settings.format)
2509
2510         self.assertIsNone(os_image_settings.kernel_image_settings)
2511         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2512
2513         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2514         self.image_creator.create()
2515
2516         instance_settings = VmInstanceConfig(
2517             name=self.vm_inst_name,
2518             flavor=self.flavor_creator.flavor_settings.name,
2519             port_settings=[self.port_settings])
2520         self.inst_creator = OpenStackVmInstance(
2521             self.os_creds, instance_settings,
2522             self.image_creator.image_settings)
2523         self.inst_creator.create()
2524
2525         self.assertTrue(self.inst_creator.vm_active(block=True))
2526
2527     def test_inst_from_existing(self):
2528         """
2529         Creates a VM instance from a image creator that has been configured to
2530         use an existing image
2531         :return: 
2532         """
2533         os_image_settings = openstack_tests.cirros_image_settings(
2534             name=self.image_name)
2535         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2536         self.image_creator.create()
2537
2538         image_settings = self.image_creator.image_settings
2539         test_image_creator = OpenStackImage(
2540             self.os_creds,
2541             ImageConfig(
2542                 name=image_settings.name, image_user=image_settings.image_user,
2543                 exists=True))
2544         test_image_creator.create()
2545         self.assertEqual(self.image_creator.get_image().id,
2546                          test_image_creator.get_image().id)
2547
2548         instance_settings = VmInstanceConfig(
2549             name=self.vm_inst_name,
2550             flavor=self.flavor_creator.flavor_settings.name,
2551             port_settings=[self.port_settings])
2552         self.inst_creator = OpenStackVmInstance(
2553             self.os_creds, instance_settings,
2554             test_image_creator.image_settings)
2555         self.inst_creator.create()
2556
2557         self.assertTrue(self.inst_creator.vm_active(block=True))
2558
2559     def test_inst_from_file_image_complex(self):
2560         """
2561         Creates a VM instance from a locally sourced file image by overriding
2562         the default settings by using a dict() that can be read in by
2563         ImageSettings
2564         :return: 
2565         """
2566
2567         os_image_settings = openstack_tests.cirros_image_settings(
2568             name=self.image_name)
2569         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2570         self.image_creator.create()
2571
2572         metadata = {
2573             'cirros': {
2574                 'config': {
2575                     'name': os_image_settings.name,
2576                     'image_user': os_image_settings.image_user,
2577                     'exists': True}}}
2578         test_image_settings = openstack_tests.cirros_image_settings(
2579             image_metadata=metadata)
2580         test_image = OpenStackImage(self.os_creds, test_image_settings)
2581         test_image.create()
2582
2583         instance_settings = VmInstanceConfig(
2584             name=self.vm_inst_name,
2585             flavor=self.flavor_creator.flavor_settings.name,
2586             port_settings=[self.port_settings])
2587         self.inst_creator = OpenStackVmInstance(self.os_creds,
2588                                                 instance_settings,
2589                                                 test_image_settings)
2590         self.inst_creator.create()
2591
2592         self.assertTrue(self.inst_creator.vm_active(block=True))
2593
2594     def test_inst_from_file_3part_image_complex(self):
2595         """
2596         Creates a VM instance from a locally sourced file image by overriding
2597         the default settings by using a dict() that can be read in by
2598         ImageSettings
2599         :return: 
2600         """
2601
2602         kernel_file = file_utils.download(
2603             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2604         ramdisk_file = file_utils.download(
2605             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2606
2607         metadata = {
2608             'cirros': {
2609                 'config': {
2610                     'name': self.image_name,
2611                     'image_user': openstack_tests.CIRROS_USER,
2612                     'image_file': self.image_file.name,
2613                     'format': openstack_tests.DEFAULT_IMAGE_FORMAT,
2614                     'kernel_image_settings': {
2615                         'name': self.image_name + '-kernel',
2616                         'image_user': openstack_tests.CIRROS_USER,
2617                         'image_file': kernel_file.name,
2618                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT},
2619                     'ramdisk_image_settings': {
2620                         'name': self.image_name + '-ramdisk',
2621                         'image_user': openstack_tests.CIRROS_USER,
2622                         'image_file': ramdisk_file.name,
2623                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}}
2624
2625         os_image_settings = openstack_tests.cirros_image_settings(
2626             name=self.image_name, image_metadata=metadata)
2627         self.assertEqual(self.image_name, os_image_settings.name)
2628         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2629         self.assertEqual(openstack_tests.CIRROS_USER,
2630                          os_image_settings.image_user)
2631         self.assertIsNone(os_image_settings.url)
2632         self.assertFalse(os_image_settings.exists)
2633         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2634                          os_image_settings.format)
2635
2636         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2637         self.assertEqual(self.image_name + '-kernel',
2638                          os_image_settings.kernel_image_settings.name)
2639         self.assertEqual(kernel_file.name,
2640                          os_image_settings.kernel_image_settings.image_file)
2641         self.assertEqual(openstack_tests.CIRROS_USER,
2642                          os_image_settings.kernel_image_settings.image_user)
2643         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2644         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2645         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2646                          os_image_settings.kernel_image_settings.format)
2647
2648         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2649         self.assertEqual(self.image_name + '-ramdisk',
2650                          os_image_settings.ramdisk_image_settings.name)
2651         self.assertEqual(ramdisk_file.name,
2652                          os_image_settings.ramdisk_image_settings.image_file)
2653         self.assertEqual(openstack_tests.CIRROS_USER,
2654                          os_image_settings.ramdisk_image_settings.image_user)
2655         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2656         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2657         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2658                          os_image_settings.ramdisk_image_settings.format)
2659
2660         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2661         self.image_creator.create()
2662
2663         instance_settings = VmInstanceConfig(
2664             name=self.vm_inst_name,
2665             flavor=self.flavor_creator.flavor_settings.name,
2666             port_settings=[self.port_settings])
2667         self.inst_creator = OpenStackVmInstance(
2668             self.os_creds, instance_settings,
2669             self.image_creator.image_settings)
2670         self.inst_creator.create()
2671
2672         self.assertTrue(self.inst_creator.vm_active(block=True))
2673
2674     def test_inst_from_file_3part_image_simple_flat(self):
2675         """
2676         Creates a VM instance from a 3-part image locally sourced from file
2677         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2678         attributes vs. using the 'config' option which completely overrides all
2679         image settings
2680         :return: 
2681         """
2682         kernel_file = file_utils.download(
2683             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2684         ramdisk_file = file_utils.download(
2685             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2686
2687         metadata = {'disk_file': self.image_file.name,
2688                     'kernel_file': kernel_file.name,
2689                     'ramdisk_file': ramdisk_file.name}
2690
2691         os_image_settings = openstack_tests.cirros_image_settings(
2692             name=self.image_name, image_metadata=metadata)
2693
2694         self.assertEqual(self.image_name, os_image_settings.name)
2695         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2696         self.assertEqual(openstack_tests.CIRROS_USER,
2697                          os_image_settings.image_user)
2698         self.assertIsNone(os_image_settings.url)
2699         self.assertFalse(os_image_settings.exists)
2700         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2701                          os_image_settings.format)
2702
2703         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2704         self.assertEqual(self.image_name + '-kernel',
2705                          os_image_settings.kernel_image_settings.name)
2706         self.assertEqual(kernel_file.name,
2707                          os_image_settings.kernel_image_settings.image_file)
2708         self.assertEqual(openstack_tests.CIRROS_USER,
2709                          os_image_settings.kernel_image_settings.image_user)
2710         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2711         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2712         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2713                          os_image_settings.kernel_image_settings.format)
2714
2715         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2716         self.assertEqual(self.image_name + '-ramdisk',
2717                          os_image_settings.ramdisk_image_settings.name)
2718         self.assertEqual(ramdisk_file.name,
2719                          os_image_settings.ramdisk_image_settings.image_file)
2720         self.assertEqual(openstack_tests.CIRROS_USER,
2721                          os_image_settings.ramdisk_image_settings.image_user)
2722         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2723         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2724         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2725                          os_image_settings.ramdisk_image_settings.format)
2726
2727         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2728         self.image_creator.create()
2729
2730         self.assertIsNotNone(self.image_creator.get_kernel_image())
2731         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2732
2733         instance_settings = VmInstanceConfig(
2734             name=self.vm_inst_name,
2735             flavor=self.flavor_creator.flavor_settings.name,
2736             port_settings=[self.port_settings])
2737         self.inst_creator = OpenStackVmInstance(
2738             self.os_creds, instance_settings,
2739             self.image_creator.image_settings)
2740         self.inst_creator.create()
2741
2742         self.assertTrue(self.inst_creator.vm_active(block=True))
2743
2744     def test_inst_from_file_3part_image_simple_nested(self):
2745         """
2746         Creates a VM instance from a 3-part image locally sourced from file
2747         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2748         attributes under 'cirros' vs. using the 'config' option which
2749         completely overrides all image settings
2750         :return: 
2751         """
2752         kernel_file = file_utils.download(
2753             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2754         ramdisk_file = file_utils.download(
2755             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2756
2757         metadata = {'cirros': {'disk_file': self.image_file.name,
2758                                'kernel_file': kernel_file.name,
2759                                'ramdisk_file': ramdisk_file.name}}
2760
2761         os_image_settings = openstack_tests.cirros_image_settings(
2762             name=self.image_name, image_metadata=metadata)
2763
2764         self.assertEqual(self.image_name, os_image_settings.name)
2765         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2766         self.assertEqual(openstack_tests.CIRROS_USER,
2767                          os_image_settings.image_user)
2768         self.assertIsNone(os_image_settings.url)
2769         self.assertFalse(os_image_settings.exists)
2770         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2771                          os_image_settings.format)
2772
2773         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2774         self.assertEqual(self.image_name + '-kernel',
2775                          os_image_settings.kernel_image_settings.name)
2776         self.assertEqual(kernel_file.name,
2777                          os_image_settings.kernel_image_settings.image_file)
2778         self.assertEqual(openstack_tests.CIRROS_USER,
2779                          os_image_settings.kernel_image_settings.image_user)
2780         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2781         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2782         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2783                          os_image_settings.kernel_image_settings.format)
2784
2785         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2786         self.assertEqual(self.image_name + '-ramdisk',
2787                          os_image_settings.ramdisk_image_settings.name)
2788         self.assertEqual(ramdisk_file.name,
2789                          os_image_settings.ramdisk_image_settings.image_file)
2790         self.assertEqual(openstack_tests.CIRROS_USER,
2791                          os_image_settings.ramdisk_image_settings.image_user)
2792         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2793         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2794         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2795                          os_image_settings.ramdisk_image_settings.format)
2796
2797         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2798         self.image_creator.create()
2799
2800         self.assertIsNotNone(self.image_creator.get_kernel_image())
2801         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2802
2803         instance_settings = VmInstanceConfig(
2804             name=self.vm_inst_name,
2805             flavor=self.flavor_creator.flavor_settings.name,
2806             port_settings=[self.port_settings])
2807         self.inst_creator = OpenStackVmInstance(
2808             self.os_creds, instance_settings,
2809             self.image_creator.image_settings)
2810         self.inst_creator.create()
2811
2812         self.assertTrue(self.inst_creator.vm_active(block=True))
2813
2814     def test_inst_from_file_3part_image_existing(self):
2815         """
2816         Creates a VM instance from a 3-part image that is existing
2817         :return: 
2818         """
2819         kernel_file = file_utils.download(
2820             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2821         ramdisk_file = file_utils.download(
2822             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2823
2824         metadata = {'cirros': {'disk_file': self.image_file.name,
2825                                'kernel_file': kernel_file.name,
2826                                'ramdisk_file': ramdisk_file.name}}
2827
2828         os_image_settings = openstack_tests.cirros_image_settings(
2829             name=self.image_name, image_metadata=metadata)
2830         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2831         self.image_creator.create()
2832
2833         image_settings = self.image_creator.image_settings
2834         test_image_creator = OpenStackImage(
2835             self.os_creds,
2836             ImageConfig(
2837                 name=image_settings.name, image_user=image_settings.image_user,
2838                 exists=True))
2839         test_image_creator.create()
2840         self.assertEqual(self.image_creator.get_image().id,
2841                          test_image_creator.get_image().id)
2842
2843         instance_settings = VmInstanceConfig(
2844             name=self.vm_inst_name,
2845             flavor=self.flavor_creator.flavor_settings.name,
2846             port_settings=[self.port_settings])
2847         self.inst_creator = OpenStackVmInstance(
2848             self.os_creds, instance_settings,
2849             test_image_creator.image_settings)
2850         self.inst_creator.create()
2851
2852         self.assertTrue(self.inst_creator.vm_active(block=True))
2853
2854
2855 class CreateInstanceTwoNetTests(OSIntegrationTestCase):
2856     """
2857     Tests the ability of two VMs to communicate when attached to separate
2858     private networks that are tied together with a router.
2859     """
2860
2861     def setUp(self):
2862         """
2863         Instantiates the CreateImage object that is responsible for downloading
2864         and creating an OS image file within OpenStack
2865         """
2866         super(self.__class__, self).__start__()
2867
2868         cidr1 = '10.200.201.0/24'
2869         cidr2 = '10.200.202.0/24'
2870         static_gateway_ip1 = '10.200.201.1'
2871         static_gateway_ip2 = '10.200.202.1'
2872         self.ip1 = '10.200.201.5'
2873         self.ip2 = '10.200.202.5'
2874
2875         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
2876
2877         # Initialize for tearDown()
2878         self.image_creator = None
2879         self.network_creators = list()
2880         self.router_creator = None
2881         self.flavor_creator = None
2882         self.sec_grp_creator = None
2883         self.inst_creators = list()
2884
2885         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2886         self.vm_inst1_name = self.guid + '-inst1'
2887         self.vm_inst2_name = self.guid + '-inst2'
2888         self.port_1_name = self.guid + '-vm1-port'
2889         self.port_2_name = self.guid + '-vm2-port'
2890         self.net_config_1 = NetworkConfig(
2891             name=self.guid + '-net1',
2892             subnet_settings=[
2893                 create_network.SubnetConfig(
2894                     cidr=cidr1, name=self.guid + '-subnet1',
2895                     gateway_ip=static_gateway_ip1)])
2896         self.net_config_2 = NetworkConfig(
2897             name=self.guid + '-net2',
2898             subnet_settings=[
2899                 create_network.SubnetConfig(
2900                     cidr=cidr2, name=self.guid + '-subnet2',
2901                     gateway_ip=static_gateway_ip2)])
2902
2903         image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
2904         os_image_settings = openstack_tests.cirros_image_settings(
2905             name=image_name, image_metadata=self.image_metadata)
2906
2907         try:
2908             # Create Image
2909             self.image_creator = OpenStackImage(
2910                 self.os_creds, os_image_settings)
2911             self.image_creator.create()
2912
2913             # First network is public
2914             self.network_creators.append(OpenStackNetwork(
2915                 self.os_creds, self.net_config_1))
2916
2917             # Second network is private
2918             self.network_creators.append(OpenStackNetwork(
2919                 self.os_creds, self.net_config_2))
2920             for network_creator in self.network_creators:
2921                 network_creator.create()
2922
2923             port_settings = [
2924                 PortConfig(
2925                     name=self.guid + '-router-port1',
2926                     ip_addrs=[{
2927                         'subnet_name':
2928                             self.net_config_1.subnet_settings[0].name,
2929                         'ip': static_gateway_ip1
2930                     }],
2931                     network_name=self.net_config_1.name),
2932                 PortConfig(
2933                     name=self.guid + '-router-port2',
2934                     ip_addrs=[{
2935                         'subnet_name':
2936                             self.net_config_2.subnet_settings[0].name,
2937                         'ip': static_gateway_ip2
2938                     }],
2939                     network_name=self.net_config_2.name)]
2940
2941             router_settings = RouterConfig(
2942                 name=self.guid + '-pub-router', port_settings=port_settings)
2943             self.router_creator = OpenStackRouter(
2944                 self.os_creds, router_settings)
2945             self.router_creator.create()
2946
2947             flavor_config = openstack_tests.get_flavor_config(
2948                 name=self.guid + '-flavor-name', ram=512, disk=10,
2949                 vcpus=2, metadata=self.flavor_metadata)
2950             self.flavor_creator = OpenStackFlavor(
2951                 self.admin_os_creds, flavor_config)
2952             self.flavor_creator.create()
2953
2954             self.sec_grp_name = self.guid + '-sec-grp'
2955             rule1 = SecurityGroupRuleConfig(
2956                 sec_grp_name=self.sec_grp_name, direction=Direction.ingress,
2957                 protocol=Protocol.icmp)
2958             rule2 = SecurityGroupRuleConfig(
2959                 sec_grp_name=self.sec_grp_name, direction=Direction.egress,
2960                 protocol=Protocol.icmp)
2961             self.sec_grp_creator = OpenStackSecurityGroup(
2962                 self.os_creds,
2963                 SecurityGroupConfig(
2964                     name=self.sec_grp_name, rule_settings=[rule1, rule2]))
2965             self.sec_grp_creator.create()
2966         except:
2967             self.tearDown()
2968             raise
2969
2970     def tearDown(self):
2971         """
2972         Cleans the created objects
2973         """
2974         for inst_creator in self.inst_creators:
2975             try:
2976                 inst_creator.clean()
2977             except Exception as e:
2978                 logger.error(
2979                     'Unexpected exception cleaning VM instance with message '
2980                     '- %s', e)
2981
2982         if self.flavor_creator:
2983             try:
2984                 self.flavor_creator.clean()
2985             except Exception as e:
2986                 logger.error(
2987                     'Unexpected exception cleaning flavor with message - %s',
2988                     e)
2989
2990         if self.router_creator:
2991             try:
2992                 self.router_creator.clean()
2993             except Exception as e:
2994                 logger.error(
2995                     'Unexpected exception cleaning router with message - %s',
2996                     e)
2997
2998         for network_creator in self.network_creators:
2999             try:
3000                 network_creator.clean()
3001             except Exception as e:
3002                 logger.error(
3003                     'Unexpected exception cleaning network with message - %s',
3004                     e)
3005
3006         if self.sec_grp_creator:
3007             try:
3008                 self.sec_grp_creator.clean()
3009             except Exception as e:
3010                 logger.error(
3011                     'Unexpected exception cleaning security group with message'
3012                     ' - %s', e)
3013
3014         if self.image_creator and not self.image_creator.image_settings.exists:
3015             try:
3016                 self.image_creator.clean()
3017             except Exception as e:
3018                 logger.error(
3019                     'Unexpected exception cleaning image with message - %s', e)
3020
3021         super(self.__class__, self).__clean__()
3022
3023     def test_ping_via_router(self):
3024         """
3025         Tests the creation of two OpenStack instances with one port on
3026         different private networks wit a router in between to ensure that they
3027         can ping
3028         through
3029         """
3030         # Create ports/NICs for instance
3031         ports_settings = []
3032         ctr = 1
3033         for network_creator in self.network_creators:
3034             ports_settings.append(PortConfig(
3035                 name=self.guid + '-port-' + str(ctr),
3036                 network_name=network_creator.network_settings.name))
3037             ctr += 1
3038
3039         # Configure instances
3040         instance1_settings = VmInstanceConfig(
3041             name=self.vm_inst1_name,
3042             flavor=self.flavor_creator.flavor_settings.name,
3043             userdata=_get_ping_userdata(self.ip2),
3044             security_group_names=self.sec_grp_name,
3045             port_settings=[PortConfig(
3046                 name=self.port_1_name,
3047                 ip_addrs=[{
3048                     'subnet_name':
3049                         self.net_config_1.subnet_settings[0].name,
3050                     'ip': self.ip1
3051                 }],
3052                 network_name=self.network_creators[0].network_settings.name)])
3053         instance2_settings = VmInstanceConfig(
3054             name=self.vm_inst2_name,
3055             flavor=self.flavor_creator.flavor_settings.name,
3056             userdata=_get_ping_userdata(self.ip1),
3057             security_group_names=self.sec_grp_name,
3058             port_settings=[PortConfig(
3059                 name=self.port_2_name,
3060                 ip_addrs=[{
3061                     'subnet_name':
3062                         self.net_config_2.subnet_settings[0].name,
3063                     'ip': self.ip2
3064                 }],
3065                 network_name=self.network_creators[1].network_settings.name)])
3066
3067         # Create instances
3068         self.inst_creators.append(OpenStackVmInstance(
3069             self.os_creds, instance1_settings,
3070             self.image_creator.image_settings))
3071         self.inst_creators.append(OpenStackVmInstance(
3072             self.os_creds, instance2_settings,
3073             self.image_creator.image_settings))
3074
3075         for inst_creator in self.inst_creators:
3076             inst_creator.create(block=True)
3077
3078         # Check for DHCP lease
3079         self.assertTrue(check_dhcp_lease(self.inst_creators[0], self.ip1))
3080         self.assertTrue(check_dhcp_lease(self.inst_creators[1], self.ip2))
3081
3082         # Effectively blocks until VM has been properly activated
3083         self.assertTrue(check_ping(self.inst_creators[0]))
3084         self.assertTrue(check_ping(self.inst_creators[1]))
3085
3086
3087 class CreateInstanceVolumeTests(OSIntegrationTestCase):
3088     """
3089     Simple instance creation with an attached volume
3090     """
3091
3092     def setUp(self):
3093         """
3094         Instantiates the CreateImage object that is responsible for downloading
3095         and creating an OS image file
3096         within OpenStack
3097         """
3098         super(self.__class__, self).__start__()
3099
3100         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
3101         self.vm_inst_name = guid + '-inst'
3102         self.nova = nova_utils.nova_client(
3103             self.os_creds, self.os_session)
3104         self.neutron = neutron_utils.neutron_client(
3105             self.os_creds, self.os_session)
3106         os_image_settings = openstack_tests.cirros_image_settings(
3107             name=guid + '-image', image_metadata=self.image_metadata)
3108
3109         net_config = openstack_tests.get_priv_net_config(
3110             project_name=self.os_creds.project_name,
3111             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
3112             router_name=guid + '-pub-router', external_net=self.ext_net_name,
3113             netconf_override=self.netconf_override)
3114
3115         self.volume_settings1 = VolumeConfig(
3116             name=self.__class__.__name__ + '-' + str(guid) + '-1')
3117         self.volume_settings2 = VolumeConfig(
3118             name=self.__class__.__name__ + '-' + str(guid) + '-2')
3119
3120         # Initialize for tearDown()
3121         self.image_creator = None
3122         self.flavor_creator = None
3123
3124         self.network_creator = None
3125         self.inst_creator = None
3126         self.volume_creator1 = None
3127         self.volume_creator2 = None
3128
3129         try:
3130             # Create Image
3131             self.image_creator = OpenStackImage(self.os_creds,
3132                                                 os_image_settings)
3133             self.image_creator.create()
3134
3135             # Create Flavor
3136             flavor_config = openstack_tests.get_flavor_config(
3137                 name=guid + '-flavor-name', ram=256, disk=1,
3138                 vcpus=2, metadata=self.flavor_metadata)
3139             self.flavor_creator = OpenStackFlavor(
3140                 self.admin_os_creds, flavor_config)
3141             self.flavor_creator.create()
3142
3143             # Create Network
3144             self.network_creator = OpenStackNetwork(
3145                 self.os_creds, net_config.network_settings)
3146             self.network_creator.create()
3147
3148             self.port_settings = PortConfig(
3149                 name=guid + '-port',
3150                 network_name=net_config.network_settings.name)
3151
3152             self.volume_creator1 = OpenStackVolume(
3153                 self.os_creds, self.volume_settings1)
3154             self.volume_creator1.create(block=True)
3155
3156             self.volume_creator2 = OpenStackVolume(
3157                 self.os_creds, self.volume_settings2)
3158             self.volume_creator2.create(block=True)
3159
3160         except Exception as e:
3161             self.tearDown()
3162             raise e
3163
3164     def tearDown(self):
3165         """
3166         Cleans the created object
3167         """
3168         if self.inst_creator:
3169             try:
3170                 self.inst_creator.clean()
3171             except Exception as e:
3172                 logger.error(
3173                     'Unexpected exception cleaning VM instance with message '
3174                     '- %s', e)
3175
3176         if self.flavor_creator:
3177             try:
3178                 self.flavor_creator.clean()
3179             except Exception as e:
3180                 logger.error(
3181                     'Unexpected exception cleaning flavor with message - %s',
3182                     e)
3183
3184         if self.network_creator:
3185             try:
3186                 self.network_creator.clean()
3187             except Exception as e:
3188                 logger.error(
3189                     'Unexpected exception cleaning network with message - %s',
3190                     e)
3191
3192         if self.volume_creator2:
3193             try:
3194                 self.volume_creator2.clean()
3195             except Exception as e:
3196                 logger.error(
3197                     'Unexpected exception cleaning volume with message - %s',
3198                     e)
3199
3200         if self.volume_creator1:
3201             try:
3202                 self.volume_creator1.clean()
3203             except Exception as e:
3204                 logger.error(
3205                     'Unexpected exception cleaning volume with message - %s',
3206                     e)
3207
3208         if self.image_creator and not self.image_creator.image_settings.exists:
3209             try:
3210                 self.image_creator.clean()
3211             except Exception as e:
3212                 logger.error(
3213                     'Unexpected exception cleaning image with message - %s', e)
3214
3215         super(self.__class__, self).__clean__()
3216
3217     def test_create_instance_with_one_volume(self):
3218         """
3219         Tests the creation of an OpenStack instance with a single volume.
3220         """
3221         instance_settings = VmInstanceConfig(
3222             name=self.vm_inst_name,
3223             flavor=self.flavor_creator.flavor_settings.name,
3224             port_settings=[self.port_settings],
3225             volume_names=[self.volume_settings1.name])
3226
3227         self.inst_creator = OpenStackVmInstance(
3228             self.os_creds, instance_settings,
3229             self.image_creator.image_settings)
3230
3231         vm_inst = self.inst_creator.create(block=True)
3232         self.assertIsNotNone(nova_utils.get_server(
3233             self.nova, self.neutron, self.keystone,
3234             vm_inst_settings=instance_settings))
3235
3236         self.assertIsNotNone(vm_inst)
3237         self.assertEqual(1, len(vm_inst.volume_ids))
3238         self.assertEqual(self.volume_creator1.get_volume().id,
3239                          vm_inst.volume_ids[0]['id'])
3240
3241     def test_create_instance_with_two_volumes(self):
3242         """
3243         Tests the creation of an OpenStack instance with a single volume.
3244         """
3245         instance_settings = VmInstanceConfig(
3246             name=self.vm_inst_name,
3247             flavor=self.flavor_creator.flavor_settings.name,
3248             port_settings=[self.port_settings],
3249             volume_names=[self.volume_settings1.name,
3250                           self.volume_settings2.name])
3251
3252         self.inst_creator = OpenStackVmInstance(
3253             self.os_creds, instance_settings,
3254             self.image_creator.image_settings)
3255
3256         vm_inst = self.inst_creator.create(block=True)
3257         self.assertIsNotNone(nova_utils.get_server(
3258             self.nova, self.neutron, self.keystone,
3259             vm_inst_settings=instance_settings))
3260
3261         self.assertIsNotNone(vm_inst)
3262         self.assertEqual(2, len(vm_inst.volume_ids))
3263         self.assertEqual(self.volume_creator1.get_volume().id,
3264                          vm_inst.volume_ids[0]['id'])
3265         self.assertEqual(self.volume_creator2.get_volume().id,
3266                          vm_inst.volume_ids[1]['id'])
3267
3268
3269 def check_dhcp_lease(inst_creator, ip, timeout=160):
3270     """
3271     Returns true if the expected DHCP lease has been acquired
3272     :param inst_creator: the SNAPS OpenStackVmInstance object
3273     :param ip: the IP address to look for
3274     :param timeout: how long to query for IP address
3275     :return:
3276     """
3277     found = False
3278     start_time = time.time()
3279
3280     logger.info("Looking for IP %s in the console log" % ip)
3281     full_log = ''
3282     while timeout > time.time() - start_time:
3283         output = inst_creator.get_console_output()
3284         full_log = full_log + output
3285         if re.search(ip, output):
3286             logger.info('DHCP lease obtained logged in console')
3287             found = True
3288             break
3289
3290     if not found:
3291         logger.error('Full console output -\n' + full_log)
3292     else:
3293         logger.debug('Full console output -\n' + full_log)
3294
3295     return found
3296
3297
3298 def _get_ping_userdata(test_ip):
3299     """
3300     Returns the post VM creation script to be added into the VM's userdata
3301     :param test_ip: the IP value to substitute into the script
3302     :return: the bash script contents
3303     """
3304     if test_ip:
3305         return ("#!/bin/sh\n\n"
3306                 "while true; do\n"
3307                 " ping -c 1 %s 2>&1 >/dev/null\n"
3308                 " RES=$?\n"
3309                 " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
3310                 "  echo 'vPing OK'\n"
3311                 "  break\n"
3312                 " else\n"
3313                 "  echo 'vPing KO'\n"
3314                 " fi\n"
3315                 " sleep 1\n"
3316                 "done\n" % test_ip)
3317     return None
3318
3319
3320 def check_ping(vm_creator, timeout=160):
3321     """
3322     Check for VM for ping result
3323     """
3324     tries = 0
3325
3326     while tries < timeout:
3327         time.sleep(1)
3328         p_console = vm_creator.get_console_output()
3329         if "vPing OK" in p_console:
3330             return True
3331         elif "failed to read iid from metadata" in p_console or tries > 5:
3332             return False
3333         tries += 1
3334
3335     return False