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