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