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