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