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