19173d247962aba87d85e0d543355e7b2d8f9681
[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
25 from snaps import file_utils
26 from snaps.openstack import create_network, create_router
27 from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
28 from snaps.openstack.create_image import OpenStackImage, ImageSettings
29 from snaps.openstack.create_instance import (
30     VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings,
31     VmInstanceSettingsError, FloatingIpSettingsError)
32 from snaps.openstack.create_keypairs import OpenStackKeypair, KeypairSettings
33 from snaps.openstack.create_network import (
34     OpenStackNetwork, PortSettings, NetworkSettings)
35 from snaps.openstack.create_router import OpenStackRouter, RouterSettings
36 from snaps.openstack.create_security_group import (
37     SecurityGroupSettings, OpenStackSecurityGroup, SecurityGroupRuleSettings,
38     Direction, Protocol)
39 from snaps.openstack.tests import openstack_tests, validation_utils
40 from snaps.openstack.tests.os_source_file_test import (
41     OSIntegrationTestCase, OSComponentTestCase)
42 from snaps.openstack.utils import nova_utils
43
44 __author__ = 'spisarski'
45
46 VM_BOOT_TIMEOUT = 600
47
48 logger = logging.getLogger('create_instance_tests')
49
50
51 class VmInstanceSettingsUnitTests(unittest.TestCase):
52     """
53     Tests the construction of the VmInstanceSettings class
54     """
55
56     def test_no_params(self):
57         with self.assertRaises(VmInstanceSettingsError):
58             VmInstanceSettings()
59
60     def test_empty_config(self):
61         with self.assertRaises(VmInstanceSettingsError):
62             VmInstanceSettings(config=dict())
63
64     def test_name_only(self):
65         with self.assertRaises(VmInstanceSettingsError):
66             VmInstanceSettings(name='foo')
67
68     def test_config_with_name_only(self):
69         with self.assertRaises(VmInstanceSettingsError):
70             VmInstanceSettings(config={'name': 'foo'})
71
72     def test_name_flavor_only(self):
73         with self.assertRaises(VmInstanceSettingsError):
74             VmInstanceSettings(name='foo', flavor='bar')
75
76     def test_config_with_name_flavor_only(self):
77         with self.assertRaises(VmInstanceSettingsError):
78             VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
79
80     def test_name_flavor_port_only(self):
81         port_settings = PortSettings(name='foo-port', network_name='bar-net')
82         settings = VmInstanceSettings(name='foo', flavor='bar',
83                                       port_settings=[port_settings])
84         self.assertEqual('foo', settings.name)
85         self.assertEqual('bar', settings.flavor)
86         self.assertEqual(1, len(settings.port_settings))
87         self.assertEqual('foo-port', settings.port_settings[0].name)
88         self.assertEqual('bar-net', settings.port_settings[0].network_name)
89         self.assertEqual(0, len(settings.security_group_names))
90         self.assertEqual(0, len(settings.floating_ip_settings))
91         self.assertIsNone(settings.sudo_user)
92         self.assertEqual(900, settings.vm_boot_timeout)
93         self.assertEqual(300, settings.vm_delete_timeout)
94         self.assertEqual(180, settings.ssh_connect_timeout)
95         self.assertIsNone(settings.availability_zone)
96
97     def test_config_with_name_flavor_port_only(self):
98         port_settings = PortSettings(name='foo-port', network_name='bar-net')
99         settings = VmInstanceSettings(
100             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
101         self.assertEqual('foo', settings.name)
102         self.assertEqual('bar', settings.flavor)
103         self.assertEqual(1, len(settings.port_settings))
104         self.assertEqual('foo-port', settings.port_settings[0].name)
105         self.assertEqual('bar-net', settings.port_settings[0].network_name)
106         self.assertEqual(0, len(settings.security_group_names))
107         self.assertEqual(0, len(settings.floating_ip_settings))
108         self.assertIsNone(settings.sudo_user)
109         self.assertEqual(900, settings.vm_boot_timeout)
110         self.assertEqual(300, settings.vm_delete_timeout)
111         self.assertEqual(180, settings.ssh_connect_timeout)
112         self.assertIsNone(settings.availability_zone)
113
114     def test_all(self):
115         port_settings = PortSettings(name='foo-port', network_name='bar-net')
116         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
117                                           router_name='foo-bar-router')
118
119         settings = VmInstanceSettings(name='foo', flavor='bar',
120                                       port_settings=[port_settings],
121                                       security_group_names=['sec_grp_1'],
122                                       floating_ip_settings=[fip_settings],
123                                       sudo_user='joe', vm_boot_timeout=999,
124                                       vm_delete_timeout=333,
125                                       ssh_connect_timeout=111,
126                                       availability_zone='server name')
127         self.assertEqual('foo', settings.name)
128         self.assertEqual('bar', settings.flavor)
129         self.assertEqual(1, len(settings.port_settings))
130         self.assertEqual('foo-port', settings.port_settings[0].name)
131         self.assertEqual('bar-net', settings.port_settings[0].network_name)
132         self.assertEqual(1, len(settings.security_group_names))
133         self.assertEqual('sec_grp_1', settings.security_group_names[0])
134         self.assertEqual(1, len(settings.floating_ip_settings))
135         self.assertEqual('foo-fip', settings.floating_ip_settings[0].name)
136         self.assertEqual('bar-port',
137                          settings.floating_ip_settings[0].port_name)
138         self.assertEqual('foo-bar-router',
139                          settings.floating_ip_settings[0].router_name)
140         self.assertEqual('joe', settings.sudo_user)
141         self.assertEqual(999, settings.vm_boot_timeout)
142         self.assertEqual(333, settings.vm_delete_timeout)
143         self.assertEqual(111, settings.ssh_connect_timeout)
144         self.assertEqual('server name', settings.availability_zone)
145
146     def test_config_all(self):
147         port_settings = PortSettings(name='foo-port', network_name='bar-net')
148         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
149                                           router_name='foo-bar-router')
150
151         settings = VmInstanceSettings(
152             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings],
153                'security_group_names': ['sec_grp_1'],
154                'floating_ips': [fip_settings], 'sudo_user': 'joe',
155                'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
156                'ssh_connect_timeout': 111, 'availability_zone': 'server name'})
157         self.assertEqual('foo', settings.name)
158         self.assertEqual('bar', settings.flavor)
159         self.assertEqual(1, len(settings.port_settings))
160         self.assertEqual('foo-port', settings.port_settings[0].name)
161         self.assertEqual('bar-net', settings.port_settings[0].network_name)
162         self.assertEqual(1, len(settings.security_group_names))
163         self.assertEqual(1, len(settings.floating_ip_settings))
164         self.assertEqual('foo-fip', settings.floating_ip_settings[0].name)
165         self.assertEqual('bar-port',
166                          settings.floating_ip_settings[0].port_name)
167         self.assertEqual('foo-bar-router',
168                          settings.floating_ip_settings[0].router_name)
169         self.assertEqual('joe', settings.sudo_user)
170         self.assertEqual(999, settings.vm_boot_timeout)
171         self.assertEqual(333, settings.vm_delete_timeout)
172         self.assertEqual(111, settings.ssh_connect_timeout)
173         self.assertEqual('server name', settings.availability_zone)
174
175
176 class FloatingIpSettingsUnitTests(unittest.TestCase):
177     """
178     Tests the construction of the FloatingIpSettings class
179     """
180
181     def test_no_params(self):
182         with self.assertRaises(FloatingIpSettingsError):
183             FloatingIpSettings()
184
185     def test_empty_config(self):
186         with self.assertRaises(FloatingIpSettingsError):
187             FloatingIpSettings(**dict())
188
189     def test_name_only(self):
190         with self.assertRaises(FloatingIpSettingsError):
191             FloatingIpSettings(name='foo')
192
193     def test_config_with_name_only(self):
194         with self.assertRaises(FloatingIpSettingsError):
195             FloatingIpSettings(**{'name': 'foo'})
196
197     def test_name_port_only(self):
198         with self.assertRaises(FloatingIpSettingsError):
199             FloatingIpSettings(name='foo', port_name='bar')
200
201     def test_config_with_name_port_only(self):
202         with self.assertRaises(FloatingIpSettingsError):
203             FloatingIpSettings(**{'name': 'foo', 'port_name': 'bar'})
204
205     def test_name_router_only(self):
206         with self.assertRaises(FloatingIpSettingsError):
207             FloatingIpSettings(name='foo', router_name='bar')
208
209     def test_config_with_name_router_only(self):
210         with self.assertRaises(FloatingIpSettingsError):
211             FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'})
212
213     def test_name_port_router_only(self):
214         settings = FloatingIpSettings(name='foo', port_name='foo-port',
215                                       router_name='bar-router')
216         self.assertEqual('foo', settings.name)
217         self.assertEqual('foo-port', settings.port_name)
218         self.assertEqual('bar-router', settings.router_name)
219         self.assertIsNone(settings.subnet_name)
220         self.assertTrue(settings.provisioning)
221
222     def test_config_with_name_port_router_only(self):
223         settings = FloatingIpSettings(
224             **{'name': 'foo', 'port_name': 'foo-port',
225                'router_name': 'bar-router'})
226         self.assertEqual('foo', settings.name)
227         self.assertEqual('foo-port', settings.port_name)
228         self.assertEqual('bar-router', settings.router_name)
229         self.assertIsNone(settings.subnet_name)
230         self.assertTrue(settings.provisioning)
231
232     def test_all(self):
233         settings = FloatingIpSettings(name='foo', port_name='foo-port',
234                                       router_name='bar-router',
235                                       subnet_name='bar-subnet',
236                                       provisioning=False)
237         self.assertEqual('foo', settings.name)
238         self.assertEqual('foo-port', settings.port_name)
239         self.assertEqual('bar-router', settings.router_name)
240         self.assertEqual('bar-subnet', settings.subnet_name)
241         self.assertFalse(settings.provisioning)
242
243     def test_config_all(self):
244         settings = FloatingIpSettings(
245             **{'name': 'foo', 'port_name': 'foo-port',
246                'router_name': 'bar-router', 'subnet_name': 'bar-subnet',
247                'provisioning': False})
248         self.assertEqual('foo', settings.name)
249         self.assertEqual('foo-port', settings.port_name)
250         self.assertEqual('bar-router', settings.router_name)
251         self.assertEqual('bar-subnet', settings.subnet_name)
252         self.assertFalse(settings.provisioning)
253
254
255 class SimpleHealthCheck(OSIntegrationTestCase):
256     """
257     Test for the CreateInstance class with a single NIC/Port with Floating IPs
258     """
259
260     def setUp(self):
261         """
262         Instantiates the CreateImage object that is responsible for downloading
263         and creating an OS image file
264         within OpenStack
265         """
266         super(self.__class__, self).__start__()
267
268         self.nova = nova_utils.nova_client(self.os_creds)
269         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
270         self.vm_inst_name = guid + '-inst'
271         self.port_1_name = guid + 'port-1'
272
273         # Initialize for tearDown()
274         self.image_creator = None
275         self.network_creator = None
276         self.flavor_creator = None
277         self.inst_creator = None
278
279         self.priv_net_config = openstack_tests.get_priv_net_config(
280             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
281         self.port_settings = PortSettings(
282             name=self.port_1_name,
283             network_name=self.priv_net_config.network_settings.name)
284
285         # Create Image
286         # Set the default image settings, then set any custom parameters sent
287         # from the app
288         os_image_settings = openstack_tests.cirros_image_settings(
289             name=guid + '-image', image_metadata=self.image_metadata)
290
291         try:
292             self.image_creator = OpenStackImage(self.os_creds,
293                                                 os_image_settings)
294             self.image_creator.create()
295
296             # Create Network
297             self.network_creator = OpenStackNetwork(
298                 self.os_creds, self.priv_net_config.network_settings)
299             self.network_creator.create()
300
301             # Create Flavor
302             self.flavor_creator = OpenStackFlavor(
303                 self.admin_os_creds,
304                 FlavorSettings(name=guid + '-flavor-name', ram=256, disk=10,
305                                vcpus=1, metadata=self.flavor_metadata))
306             self.flavor_creator.create()
307         except Exception as e:
308             self.tearDown()
309             raise e
310
311     def tearDown(self):
312         """
313         Cleans the created object
314         """
315         if self.inst_creator:
316             try:
317                 self.inst_creator.clean()
318             except Exception as e:
319                 logger.error(
320                     'Unexpected exception cleaning VM instance with message'
321                     ' - %s', e)
322
323         if self.network_creator:
324             try:
325                 self.network_creator.clean()
326             except Exception as e:
327                 logger.error(
328                     'Unexpected exception cleaning network with message - %s',
329                     e)
330
331         if self.flavor_creator:
332             try:
333                 self.flavor_creator.clean()
334             except Exception as e:
335                 logger.error(
336                     'Unexpected exception cleaning flavor with message - %s',
337                     e)
338
339         if self.image_creator and not self.image_creator.image_settings.exists:
340             try:
341                 self.image_creator.clean()
342             except Exception as e:
343                 logger.error(
344                     'Unexpected exception cleaning image with message - %s',
345                     e)
346
347         super(self.__class__, self).__clean__()
348
349     def test_check_vm_ip_dhcp(self):
350         """
351         Tests the creation of an OpenStack instance with a single port and
352         ensures that it's assigned IP address is the actual.
353         """
354         instance_settings = VmInstanceSettings(
355             name=self.vm_inst_name,
356             flavor=self.flavor_creator.flavor_settings.name,
357             port_settings=[self.port_settings])
358
359         self.inst_creator = OpenStackVmInstance(
360             self.os_creds, instance_settings,
361             self.image_creator.image_settings)
362         self.inst_creator.create()
363
364         ip = self.inst_creator.get_port_ip(self.port_settings.name)
365         self.assertIsNotNone(ip)
366
367         self.assertTrue(self.inst_creator.vm_active(block=True))
368
369         self.assertTrue(check_dhcp_lease(self.inst_creator, ip))
370
371
372 class CreateInstanceSimpleTests(OSIntegrationTestCase):
373     """
374     Simple instance creation tests without any other objects
375     """
376
377     def setUp(self):
378         """
379         Instantiates the CreateImage object that is responsible for downloading
380         and creating an OS image file
381         within OpenStack
382         """
383         super(self.__class__, self).__start__()
384
385         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
386         self.vm_inst_name = guid + '-inst'
387         self.nova = nova_utils.nova_client(self.os_creds)
388         os_image_settings = openstack_tests.cirros_image_settings(
389             name=guid + '-image', image_metadata=self.image_metadata)
390
391         net_config = openstack_tests.get_priv_net_config(
392             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
393             router_name=guid + '-pub-router', external_net=self.ext_net_name)
394
395         # Initialize for tearDown()
396         self.image_creator = None
397         self.flavor_creator = None
398
399         self.network_creator = None
400         self.inst_creator = None
401
402         try:
403             # Create Image
404             self.image_creator = OpenStackImage(self.os_creds,
405                                                 os_image_settings)
406             self.image_creator.create()
407
408             # Create Flavor
409             self.flavor_creator = OpenStackFlavor(
410                 self.admin_os_creds,
411                 FlavorSettings(name=guid + '-flavor-name', ram=256, disk=10,
412                                vcpus=2, metadata=self.flavor_metadata))
413             self.flavor_creator.create()
414
415             # Create Network
416             self.network_creator = OpenStackNetwork(
417                 self.os_creds, net_config.network_settings)
418             self.network_creator.create()
419
420             self.port_settings = PortSettings(
421                 name=guid + '-port',
422                 network_name=net_config.network_settings.name)
423
424         except Exception as e:
425             self.tearDown()
426             raise e
427
428     def tearDown(self):
429         """
430         Cleans the created object
431         """
432         if self.inst_creator:
433             try:
434                 self.inst_creator.clean()
435             except Exception as e:
436                 logger.error(
437                     'Unexpected exception cleaning VM instance with message '
438                     '- %s', e)
439
440         if self.flavor_creator:
441             try:
442                 self.flavor_creator.clean()
443             except Exception as e:
444                 logger.error(
445                     'Unexpected exception cleaning flavor with message - %s',
446                     e)
447
448         if self.network_creator:
449             try:
450                 self.network_creator.clean()
451             except Exception as e:
452                 logger.error(
453                     'Unexpected exception cleaning network with message - %s',
454                     e)
455
456         if self.image_creator and not self.image_creator.image_settings.exists:
457             try:
458                 self.image_creator.clean()
459             except Exception as e:
460                 logger.error(
461                     'Unexpected exception cleaning image with message - %s', e)
462
463         super(self.__class__, self).__clean__()
464
465     def test_create_delete_instance(self):
466         """
467         Tests the creation of an OpenStack instance with a single port with a
468         static IP without a Floating IP.
469         """
470         instance_settings = VmInstanceSettings(
471             name=self.vm_inst_name,
472             flavor=self.flavor_creator.flavor_settings.name,
473             port_settings=[self.port_settings])
474
475         self.inst_creator = OpenStackVmInstance(
476             self.os_creds, instance_settings,
477             self.image_creator.image_settings)
478
479         vm_inst = self.inst_creator.create()
480         self.assertIsNotNone(nova_utils.get_server(
481             self.nova, vm_inst_settings=instance_settings))
482
483         # Delete instance
484         nova_utils.delete_vm_instance(self.nova, vm_inst)
485
486         self.assertTrue(self.inst_creator.vm_deleted(block=True))
487         self.assertIsNone(nova_utils.get_server(
488             self.nova, vm_inst_settings=instance_settings))
489
490         # Exception should not be thrown
491         self.inst_creator.clean()
492
493
494 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
495     """
496     Test for the CreateInstance class with a single NIC/Port with Floating IPs
497     """
498
499     def setUp(self):
500         """
501         Instantiates the CreateImage object that is responsible for downloading
502         and creating an OS image file within OpenStack
503         """
504         super(self.__class__, self).__start__()
505
506         self.nova = nova_utils.nova_client(self.os_creds)
507         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
508         self.keypair_priv_filepath = 'tmp/' + guid
509         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
510         self.keypair_name = guid + '-kp'
511         self.vm_inst_name = guid + '-inst'
512         self.port_1_name = guid + 'port-1'
513         self.port_2_name = guid + 'port-2'
514         self.floating_ip_name = guid + 'fip1'
515
516         # Initialize for tearDown()
517         self.image_creator = None
518         self.network_creator = None
519         self.router_creator = None
520         self.flavor_creator = None
521         self.keypair_creator = None
522         self.sec_grp_creator = None
523         self.inst_creators = list()
524
525         self.pub_net_config = openstack_tests.get_pub_net_config(
526             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
527             router_name=guid + '-pub-router', external_net=self.ext_net_name)
528         os_image_settings = openstack_tests.cirros_image_settings(
529             name=guid + '-image', image_metadata=self.image_metadata)
530         try:
531             # Create Image
532             self.image_creator = OpenStackImage(self.os_creds,
533                                                 os_image_settings)
534             self.image_creator.create()
535
536             # Create Network
537             self.network_creator = OpenStackNetwork(
538                 self.os_creds, self.pub_net_config.network_settings)
539             self.network_creator.create()
540
541             # Create Router
542             self.router_creator = OpenStackRouter(
543                 self.os_creds, self.pub_net_config.router_settings)
544             self.router_creator.create()
545
546             # Create Flavor
547             self.flavor_creator = OpenStackFlavor(
548                 self.admin_os_creds,
549                 FlavorSettings(name=guid + '-flavor-name', ram=256, disk=10,
550                                vcpus=2, metadata=self.flavor_metadata))
551             self.flavor_creator.create()
552
553             self.keypair_creator = OpenStackKeypair(
554                 self.os_creds, KeypairSettings(
555                     name=self.keypair_name,
556                     public_filepath=self.keypair_pub_filepath,
557                     private_filepath=self.keypair_priv_filepath))
558             self.keypair_creator.create()
559
560             sec_grp_name = guid + '-sec-grp'
561             rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
562                                               direction=Direction.ingress,
563                                               protocol=Protocol.icmp)
564             rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
565                                               direction=Direction.ingress,
566                                               protocol=Protocol.tcp,
567                                               port_range_min=22,
568                                               port_range_max=22)
569             self.sec_grp_creator = OpenStackSecurityGroup(
570                 self.os_creds,
571                 SecurityGroupSettings(name=sec_grp_name,
572                                       rule_settings=[rule1, rule2]))
573             self.sec_grp_creator.create()
574         except Exception as e:
575             self.tearDown()
576             raise e
577
578     def tearDown(self):
579         """
580         Cleans the created object
581         """
582         for inst_creator in self.inst_creators:
583             try:
584                 inst_creator.clean()
585             except Exception as e:
586                 logger.error(
587                     'Unexpected exception cleaning VM instance with message '
588                     '- %s', e)
589
590         if self.keypair_creator:
591             try:
592                 self.keypair_creator.clean()
593             except Exception as e:
594                 logger.error(
595                     'Unexpected exception cleaning keypair with message - %s',
596                     e)
597
598         if os.path.isfile(self.keypair_pub_filepath):
599             os.remove(self.keypair_pub_filepath)
600
601         if os.path.isfile(self.keypair_priv_filepath):
602             os.remove(self.keypair_priv_filepath)
603
604         if self.flavor_creator:
605             try:
606                 self.flavor_creator.clean()
607             except Exception as e:
608                 logger.error(
609                     'Unexpected exception cleaning flavor with message - %s',
610                     e)
611
612         if self.sec_grp_creator:
613             try:
614                 self.sec_grp_creator.clean()
615             except Exception as e:
616                 logger.error(
617                     'Unexpected exception cleaning security group with message'
618                     ' - %s', e)
619
620         if self.router_creator:
621             try:
622                 self.router_creator.clean()
623             except Exception as e:
624                 logger.error(
625                     'Unexpected exception cleaning router with message - %s',
626                     e)
627
628         if self.network_creator:
629             try:
630                 self.network_creator.clean()
631             except Exception as e:
632                 logger.error(
633                     'Unexpected exception cleaning network with message - %s',
634                     e)
635
636         if self.image_creator and not self.image_creator.image_settings.exists:
637             try:
638                 self.image_creator.clean()
639             except Exception as e:
640                 logger.error(
641                     'Unexpected exception cleaning image with message - %s', e)
642
643         super(self.__class__, self).__clean__()
644
645     def test_single_port_static(self):
646         """
647         Tests the creation of an OpenStack instance with a single port with a
648         static IP without a Floating IP.
649         """
650         ip_1 = '10.55.1.100'
651         sub_settings = self.pub_net_config.network_settings.subnet_settings
652         port_settings = PortSettings(
653             name=self.port_1_name,
654             network_name=self.pub_net_config.network_settings.name,
655             ip_addrs=[
656                 {'subnet_name': sub_settings[0].name, 'ip': ip_1}])
657
658         instance_settings = VmInstanceSettings(
659             name=self.vm_inst_name,
660             flavor=self.flavor_creator.flavor_settings.name,
661             port_settings=[port_settings],
662             floating_ip_settings=[FloatingIpSettings(
663                 name=self.floating_ip_name, port_name=self.port_1_name,
664                 router_name=self.pub_net_config.router_settings.name)])
665
666         inst_creator = OpenStackVmInstance(
667             self.os_creds, instance_settings,
668             self.image_creator.image_settings,
669             keypair_settings=self.keypair_creator.keypair_settings)
670         self.inst_creators.append(inst_creator)
671         vm_inst = inst_creator.create()
672
673         self.assertEqual(ip_1, inst_creator.get_port_ip(self.port_1_name))
674         self.assertTrue(inst_creator.vm_active(block=True))
675         self.assertEqual(vm_inst, inst_creator.get_vm_inst())
676
677     def test_ssh_client_fip_before_active(self):
678         """
679         Tests the ability to access a VM via SSH and a floating IP when it has
680         been assigned prior to being active.
681         """
682         port_settings = PortSettings(
683             name=self.port_1_name,
684             network_name=self.pub_net_config.network_settings.name)
685
686         instance_settings = VmInstanceSettings(
687             name=self.vm_inst_name,
688             flavor=self.flavor_creator.flavor_settings.name,
689             port_settings=[port_settings],
690             floating_ip_settings=[FloatingIpSettings(
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()
700         self.assertIsNotNone(vm_inst)
701
702         self.assertTrue(inst_creator.vm_active(block=True))
703
704         ip = inst_creator.get_port_ip(port_settings.name)
705         self.assertTrue(check_dhcp_lease(inst_creator, ip))
706
707         inst_creator.add_security_group(
708             self.sec_grp_creator.get_security_group())
709         self.assertEqual(vm_inst, inst_creator.get_vm_inst())
710
711         self.assertTrue(validate_ssh_client(inst_creator))
712
713     def test_ssh_client_fip_after_active(self):
714         """
715         Tests the ability to access a VM via SSH and a floating IP when it has
716         been assigned prior to being active.
717         """
718         port_settings = PortSettings(
719             name=self.port_1_name,
720             network_name=self.pub_net_config.network_settings.name)
721
722         instance_settings = VmInstanceSettings(
723             name=self.vm_inst_name,
724             flavor=self.flavor_creator.flavor_settings.name,
725             port_settings=[port_settings],
726             floating_ip_settings=[FloatingIpSettings(
727                 name=self.floating_ip_name, port_name=self.port_1_name,
728                 router_name=self.pub_net_config.router_settings.name)])
729
730         inst_creator = OpenStackVmInstance(
731             self.os_creds, instance_settings,
732             self.image_creator.image_settings,
733             keypair_settings=self.keypair_creator.keypair_settings)
734         self.inst_creators.append(inst_creator)
735
736         # block=True will force the create() method to block until the
737         vm_inst = inst_creator.create(block=True)
738         self.assertIsNotNone(vm_inst)
739
740         self.assertTrue(inst_creator.vm_active(block=True))
741
742         ip = inst_creator.get_port_ip(port_settings.name)
743         self.assertTrue(check_dhcp_lease(inst_creator, ip))
744
745         inst_creator.add_security_group(
746             self.sec_grp_creator.get_security_group())
747         self.assertEqual(vm_inst, inst_creator.get_vm_inst())
748
749         self.assertTrue(validate_ssh_client(inst_creator))
750
751     def test_ssh_client_fip_second_creator(self):
752         """
753         Tests the ability to access a VM via SSH and a floating IP via a
754         creator that is identical to the original creator.
755         """
756         port_settings = PortSettings(
757             name=self.port_1_name,
758             network_name=self.pub_net_config.network_settings.name)
759
760         instance_settings = VmInstanceSettings(
761             name=self.vm_inst_name,
762             flavor=self.flavor_creator.flavor_settings.name,
763             port_settings=[port_settings],
764             floating_ip_settings=[FloatingIpSettings(
765                 name=self.floating_ip_name, port_name=self.port_1_name,
766                 router_name=self.pub_net_config.router_settings.name)])
767
768         inst_creator = OpenStackVmInstance(
769             self.os_creds, instance_settings,
770             self.image_creator.image_settings,
771             keypair_settings=self.keypair_creator.keypair_settings)
772         self.inst_creators.append(inst_creator)
773
774         # block=True will force the create() method to block until the
775         vm_inst = inst_creator.create(block=True)
776         self.assertIsNotNone(vm_inst)
777
778         self.assertTrue(inst_creator.vm_active(block=True))
779
780         ip = inst_creator.get_port_ip(port_settings.name)
781         self.assertTrue(check_dhcp_lease(inst_creator, ip))
782
783         inst_creator.add_security_group(
784             self.sec_grp_creator.get_security_group())
785         self.assertEqual(vm_inst, inst_creator.get_vm_inst())
786
787         self.assertTrue(validate_ssh_client(inst_creator))
788
789         inst_creator2 = OpenStackVmInstance(
790             self.os_creds, instance_settings,
791             self.image_creator.image_settings,
792             keypair_settings=self.keypair_creator.keypair_settings)
793         inst_creator2.create()
794         self.assertTrue(validate_ssh_client(inst_creator2))
795
796
797 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
798     """
799     Test for the CreateInstance class with a single NIC/Port where mac and IP
800     values are manually set
801     """
802
803     def setUp(self):
804         """
805         Instantiates the CreateImage object that is responsible for downloading
806         and creating an OS image file within OpenStack
807         """
808         super(self.__class__, self).__start__()
809
810         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
811         self.vm_inst_name = guid + '-inst'
812         self.port_1_name = guid + 'port-1'
813         self.port_2_name = guid + 'port-2'
814         self.floating_ip_name = guid + 'fip1'
815
816         # Initialize for tearDown()
817         self.image_creator = None
818         self.network_creator = None
819         self.flavor_creator = None
820         self.inst_creator = None
821
822         self.net_config = openstack_tests.get_priv_net_config(
823             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
824             router_name=guid + '-pub-router', external_net=self.ext_net_name)
825         os_image_settings = openstack_tests.cirros_image_settings(
826             name=guid + '-image', image_metadata=self.image_metadata)
827
828         try:
829             # Create Image
830             self.image_creator = OpenStackImage(self.os_creds,
831                                                 os_image_settings)
832             self.image_creator.create()
833
834             # Create Network
835             self.network_creator = OpenStackNetwork(
836                 self.os_creds, self.net_config.network_settings)
837             self.network_creator.create()
838
839             # Create Flavor
840             self.flavor_creator = OpenStackFlavor(
841                 self.admin_os_creds,
842                 FlavorSettings(name=guid + '-flavor-name', ram=256, disk=10,
843                                vcpus=2, metadata=self.flavor_metadata))
844             self.flavor_creator.create()
845         except Exception as e:
846             self.tearDown()
847             raise e
848
849     def tearDown(self):
850         """
851         Cleans the created object
852         """
853         if self.inst_creator:
854             try:
855                 self.inst_creator.clean()
856             except Exception as e:
857                 logger.error(
858                     'Unexpected exception cleaning VM instance with message '
859                     '- %s', e)
860
861         if self.flavor_creator:
862             try:
863                 self.flavor_creator.clean()
864             except Exception as e:
865                 logger.error(
866                     'Unexpected exception cleaning flavor with message - %s',
867                     e)
868
869         if self.network_creator:
870             try:
871                 self.network_creator.clean()
872             except Exception as e:
873                 logger.error(
874                     'Unexpected exception cleaning network with message - %s',
875                     e)
876
877         if self.image_creator and not self.image_creator.image_settings.exists:
878             try:
879                 self.image_creator.clean()
880             except Exception as e:
881                 logger.error(
882                     'Unexpected exception cleaning image with message - %s', e)
883
884         super(self.__class__, self).__clean__()
885
886     def test_set_custom_valid_ip_one_subnet(self):
887         """
888         Tests the creation of an OpenStack instance with a single port with a
889         static IP on a network with one subnet.
890         """
891         ip = '10.55.0.101'
892         sub_settings = self.net_config.network_settings.subnet_settings
893         port_settings = PortSettings(
894             name=self.port_1_name,
895             network_name=self.net_config.network_settings.name,
896             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
897
898         instance_settings = VmInstanceSettings(
899             name=self.vm_inst_name,
900             flavor=self.flavor_creator.flavor_settings.name,
901             port_settings=[port_settings])
902
903         self.inst_creator = OpenStackVmInstance(
904             self.os_creds, instance_settings,
905             self.image_creator.image_settings)
906         self.inst_creator.create(block=True)
907
908         self.assertEqual(ip, self.inst_creator.get_port_ip(
909             self.port_1_name,
910             subnet_name=self.net_config.network_settings.subnet_settings[
911                 0].name))
912
913     def test_set_custom_invalid_ip_one_subnet(self):
914         """
915         Tests the creation of an OpenStack instance with a single port with a
916         static IP on a network with one subnet.
917         """
918         ip = '10.66.0.101'
919         sub_settings = self.net_config.network_settings.subnet_settings
920         port_settings = PortSettings(
921             name=self.port_1_name,
922             network_name=self.net_config.network_settings.name,
923             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
924
925         instance_settings = VmInstanceSettings(
926             name=self.vm_inst_name,
927             flavor=self.flavor_creator.flavor_settings.name,
928             port_settings=[port_settings])
929
930         self.inst_creator = OpenStackVmInstance(
931             self.os_creds, instance_settings,
932             self.image_creator.image_settings)
933
934         with self.assertRaises(InvalidIpForSubnetClient):
935             self.inst_creator.create()
936
937     def test_set_custom_valid_mac(self):
938         """
939         Tests the creation of an OpenStack instance with a single port where
940         the MAC address is assigned.
941         """
942         mac_addr = '0a:1b:2c:3d:4e:5f'
943         port_settings = PortSettings(
944             name=self.port_1_name,
945             network_name=self.net_config.network_settings.name,
946             mac_address=mac_addr)
947
948         instance_settings = VmInstanceSettings(
949             name=self.vm_inst_name,
950             flavor=self.flavor_creator.flavor_settings.name,
951             port_settings=[port_settings])
952
953         self.inst_creator = OpenStackVmInstance(
954             self.os_creds, instance_settings,
955             self.image_creator.image_settings)
956         self.inst_creator.create(block=True)
957
958         self.assertEqual(mac_addr,
959                          self.inst_creator.get_port_mac(self.port_1_name))
960
961     def test_set_custom_invalid_mac(self):
962         """
963         Tests the creation of an OpenStack instance with a single port where an
964         invalid MAC address value is being
965         assigned. This should raise an Exception
966         """
967         port_settings = PortSettings(
968             name=self.port_1_name,
969             network_name=self.net_config.network_settings.name,
970             mac_address='foo')
971
972         instance_settings = VmInstanceSettings(
973             name=self.vm_inst_name,
974             flavor=self.flavor_creator.flavor_settings.name,
975             port_settings=[port_settings])
976
977         self.inst_creator = OpenStackVmInstance(
978             self.os_creds, instance_settings,
979             self.image_creator.image_settings)
980
981         with self.assertRaises(Exception):
982             self.inst_creator.create()
983
984     def test_set_custom_mac_and_ip(self):
985         """
986         Tests the creation of an OpenStack instance with a single port where
987         the IP and MAC address is assigned.
988         """
989         ip = '10.55.0.101'
990         mac_addr = '0a:1b:2c:3d:4e:5f'
991         sub_settings = self.net_config.network_settings.subnet_settings
992         port_settings = PortSettings(
993             name=self.port_1_name,
994             network_name=self.net_config.network_settings.name,
995             mac_address=mac_addr,
996             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
997
998         instance_settings = VmInstanceSettings(
999             name=self.vm_inst_name,
1000             flavor=self.flavor_creator.flavor_settings.name,
1001             port_settings=[port_settings])
1002
1003         self.inst_creator = OpenStackVmInstance(
1004             self.os_creds, instance_settings,
1005             self.image_creator.image_settings)
1006         self.inst_creator.create(block=True)
1007
1008         self.assertEqual(ip, self.inst_creator.get_port_ip(
1009             self.port_1_name,
1010             subnet_name=self.net_config.network_settings.subnet_settings[
1011                 0].name))
1012         self.assertEqual(mac_addr,
1013                          self.inst_creator.get_port_mac(self.port_1_name))
1014
1015     def test_set_allowed_address_pairs(self):
1016         """
1017         Tests the creation of an OpenStack instance with a single port where
1018         max_allowed_address_pair is set.
1019         """
1020         ip = '10.55.0.101'
1021         mac_addr = '0a:1b:2c:3d:4e:5f'
1022         pair = {'ip_address': ip, 'mac_address': mac_addr}
1023         port_settings = PortSettings(
1024             name=self.port_1_name,
1025             network_name=self.net_config.network_settings.name,
1026             allowed_address_pairs=[pair])
1027
1028         instance_settings = VmInstanceSettings(
1029             name=self.vm_inst_name,
1030             flavor=self.flavor_creator.flavor_settings.name,
1031             port_settings=[port_settings])
1032
1033         self.inst_creator = OpenStackVmInstance(
1034             self.os_creds, instance_settings,
1035             self.image_creator.image_settings)
1036         self.inst_creator.create(block=True)
1037
1038         port = self.inst_creator.get_port_by_name(port_settings.name)
1039         self.assertIsNotNone(port)
1040         self.assertIsNotNone(port.allowed_address_pairs)
1041         self.assertEqual(1, len(port.allowed_address_pairs))
1042         validation_utils.objects_equivalent(pair,
1043                                             port.allowed_address_pairs[0])
1044
1045     def test_set_allowed_address_pairs_bad_mac(self):
1046         """
1047         Tests the creation of an OpenStack instance with a single port where
1048         max_allowed_address_pair is set with an invalid MAC address.
1049         """
1050         ip = '10.55.0.101'
1051         mac_addr = 'foo'
1052         pair = {'ip_address': ip, 'mac_address': mac_addr}
1053         pairs = set()
1054         pairs.add((ip, mac_addr))
1055         port_settings = PortSettings(
1056             name=self.port_1_name,
1057             network_name=self.net_config.network_settings.name,
1058             allowed_address_pairs=[pair])
1059
1060         instance_settings = VmInstanceSettings(
1061             name=self.vm_inst_name,
1062             flavor=self.flavor_creator.flavor_settings.name,
1063             port_settings=[port_settings])
1064
1065         self.inst_creator = OpenStackVmInstance(
1066             self.os_creds, instance_settings,
1067             self.image_creator.image_settings)
1068         with self.assertRaises(Exception):
1069             self.inst_creator.create()
1070
1071     def test_set_allowed_address_pairs_bad_ip(self):
1072         """
1073         Tests the creation of an OpenStack instance with a single port where
1074         max_allowed_address_pair is set with an invalid MAC address.
1075         """
1076         ip = 'foo'
1077         mac_addr = '0a:1b:2c:3d:4e:5f'
1078         pair = {'ip_address': ip, 'mac_address': mac_addr}
1079         pairs = set()
1080         pairs.add((ip, mac_addr))
1081         port_settings = PortSettings(
1082             name=self.port_1_name,
1083             network_name=self.net_config.network_settings.name,
1084             allowed_address_pairs=[pair])
1085
1086         instance_settings = VmInstanceSettings(
1087             name=self.vm_inst_name,
1088             flavor=self.flavor_creator.flavor_settings.name,
1089             port_settings=[port_settings])
1090
1091         self.inst_creator = OpenStackVmInstance(
1092             self.os_creds, instance_settings,
1093             self.image_creator.image_settings)
1094         with self.assertRaises(Exception):
1095             self.inst_creator.create()
1096
1097
1098 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1099     """
1100     Test for the CreateInstance where one VM is deployed to each compute node
1101     """
1102
1103     def setUp(self):
1104         """
1105         Instantiates the CreateImage object that is responsible for downloading
1106         and creating an OS image file within OpenStack
1107         """
1108         super(self.__class__, self).__start__()
1109
1110         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1111         self.vm_inst_name = guid + '-inst'
1112         self.port_base_name = guid + 'port'
1113
1114         # Initialize for tearDown()
1115         self.image_creator = None
1116         self.flavor_creator = None
1117         self.network_creator = None
1118         self.inst_creators = list()
1119
1120         self.priv_net_config = openstack_tests.get_priv_net_config(
1121             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
1122
1123         os_image_settings = openstack_tests.cirros_image_settings(
1124             name=guid + '-image', image_metadata=self.image_metadata)
1125
1126         try:
1127             # Create Network
1128             self.network_creator = OpenStackNetwork(
1129                 self.admin_os_creds, self.priv_net_config.network_settings)
1130             self.network_creator.create()
1131
1132             # Create Flavor
1133             self.flavor_creator = OpenStackFlavor(
1134                 self.admin_os_creds,
1135                 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1,
1136                                vcpus=1, metadata=self.flavor_metadata))
1137             self.flavor_creator.create()
1138
1139             # Create Image
1140             self.image_creator = OpenStackImage(self.os_creds,
1141                                                 os_image_settings)
1142             self.image_creator.create()
1143
1144         except Exception as e:
1145             self.tearDown()
1146             raise e
1147
1148     def tearDown(self):
1149         """
1150         Cleans the created object
1151         """
1152         for inst_creator in self.inst_creators:
1153             try:
1154                 inst_creator.clean()
1155             except Exception as e:
1156                 logger.error(
1157                     'Unexpected exception cleaning VM instance with message '
1158                     '- %s', e)
1159
1160         if self.flavor_creator:
1161             try:
1162                 self.flavor_creator.clean()
1163             except Exception as e:
1164                 logger.error(
1165                     'Unexpected exception cleaning flavor with message - %s',
1166                     e)
1167
1168         if self.network_creator:
1169             try:
1170                 self.network_creator.clean()
1171             except Exception as e:
1172                 logger.error(
1173                     'Unexpected exception cleaning network with message - %s',
1174                     e)
1175
1176         if self.image_creator and not self.image_creator.image_settings.exists:
1177             try:
1178                 self.image_creator.clean()
1179             except Exception as e:
1180                 logger.error(
1181                     'Unexpected exception cleaning image with message - %s', e)
1182
1183         super(self.__class__, self).__clean__()
1184
1185     def test_deploy_vm_to_each_compute_node(self):
1186         """
1187         Tests the creation of OpenStack VM instances to each compute node.
1188         """
1189         from snaps.openstack.utils import nova_utils
1190         nova = nova_utils.nova_client(self.admin_os_creds)
1191         zone_hosts = nova_utils.get_availability_zone_hosts(nova)
1192
1193         # Create Instance on each server/zone
1194         ctr = 0
1195         for zone in zone_hosts:
1196             inst_name = self.vm_inst_name + '-' + zone
1197             ctr += 1
1198             port_settings = PortSettings(
1199                 name=self.port_base_name + '-' + str(ctr),
1200                 network_name=self.priv_net_config.network_settings.name)
1201
1202             instance_settings = VmInstanceSettings(
1203                 name=inst_name,
1204                 flavor=self.flavor_creator.flavor_settings.name,
1205                 availability_zone=zone,
1206                 port_settings=[port_settings])
1207             inst_creator = OpenStackVmInstance(
1208                 self.admin_os_creds, instance_settings,
1209                 self.image_creator.image_settings)
1210             self.inst_creators.append(inst_creator)
1211             inst_creator.create()
1212
1213         # Validate instances to ensure they've been deployed to the correct
1214         # server
1215         index = 0
1216         for zone in zone_hosts:
1217             creator = self.inst_creators[index]
1218             self.assertTrue(creator.vm_active(block=True))
1219             info = creator.get_vm_info()
1220             deployed_zone = info['OS-EXT-AZ:availability_zone']
1221             deployed_host = info['OS-EXT-SRV-ATTR:host']
1222             self.assertEqual(zone, deployed_zone + ':' + deployed_host)
1223             index += 1
1224
1225
1226 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1227     """
1228     Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP
1229     and eth1 w/o.
1230     These tests require a Centos image
1231     """
1232
1233     def setUp(self):
1234         """
1235         Instantiates the CreateImage object that is responsible for downloading
1236         and creating an OS image file within OpenStack
1237         """
1238         super(self.__class__, self).__start__()
1239
1240         self.nova = nova_utils.nova_client(self.os_creds)
1241
1242         # Initialize for tearDown()
1243         self.image_creator = None
1244         self.network_creators = list()
1245         self.router_creators = list()
1246         self.flavor_creator = None
1247         self.keypair_creator = None
1248         self.sec_grp_creator = None
1249         self.inst_creator = None
1250
1251         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1252         self.keypair_priv_filepath = 'tmp/' + self.guid
1253         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1254         self.keypair_name = self.guid + '-kp'
1255         self.vm_inst_name = self.guid + '-inst'
1256         self.port_1_name = self.guid + '-port-1'
1257         self.port_2_name = self.guid + '-port-2'
1258         self.floating_ip_name = self.guid + 'fip1'
1259         self.priv_net_config = openstack_tests.get_priv_net_config(
1260             net_name=self.guid + '-priv-net',
1261             subnet_name=self.guid + '-priv-subnet',
1262             router_name=self.guid + '-priv-router',
1263             external_net=self.ext_net_name)
1264         self.pub_net_config = openstack_tests.get_pub_net_config(
1265             net_name=self.guid + '-pub-net',
1266             subnet_name=self.guid + '-pub-subnet',
1267             router_name=self.guid + '-pub-router',
1268             external_net=self.ext_net_name)
1269
1270         image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1271         os_image_settings = openstack_tests.centos_image_settings(
1272             name=image_name, image_metadata=self.image_metadata)
1273
1274         try:
1275             # Create Image
1276             self.image_creator = OpenStackImage(self.os_creds,
1277                                                 os_image_settings)
1278             self.image_creator.create()
1279
1280             # First network is public
1281             self.network_creators.append(OpenStackNetwork(
1282                 self.os_creds, self.pub_net_config.network_settings))
1283             # Second network is private
1284             self.network_creators.append(OpenStackNetwork(
1285                 self.os_creds, self.priv_net_config.network_settings))
1286             for network_creator in self.network_creators:
1287                 network_creator.create()
1288
1289             self.router_creators.append(OpenStackRouter(
1290                 self.os_creds, self.pub_net_config.router_settings))
1291             self.router_creators.append(OpenStackRouter(
1292                 self.os_creds, self.priv_net_config.router_settings))
1293
1294             # Create Routers
1295             for router_creator in self.router_creators:
1296                 router_creator.create()
1297
1298             # Create Flavor
1299             self.flavor_creator = OpenStackFlavor(
1300                 self.admin_os_creds,
1301                 FlavorSettings(name=self.guid + '-flavor-name', ram=512,
1302                                disk=10, vcpus=2,
1303                                metadata=self.flavor_metadata))
1304             self.flavor_creator.create()
1305
1306             # Create Keypair
1307             self.keypair_creator = OpenStackKeypair(
1308                 self.os_creds, KeypairSettings(
1309                     name=self.keypair_name,
1310                     public_filepath=self.keypair_pub_filepath,
1311                     private_filepath=self.keypair_priv_filepath))
1312             self.keypair_creator.create()
1313
1314             sec_grp_name = self.guid + '-sec-grp'
1315             rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
1316                                               direction=Direction.ingress,
1317                                               protocol=Protocol.icmp)
1318             rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
1319                                               direction=Direction.ingress,
1320                                               protocol=Protocol.tcp,
1321                                               port_range_min=22,
1322                                               port_range_max=22)
1323             self.sec_grp_creator = OpenStackSecurityGroup(
1324                 self.os_creds,
1325                 SecurityGroupSettings(name=sec_grp_name,
1326                                       rule_settings=[rule1, rule2]))
1327             self.sec_grp_creator.create()
1328         except:
1329             self.tearDown()
1330             raise
1331
1332     def tearDown(self):
1333         """
1334         Cleans the created objects
1335         """
1336         if self.inst_creator:
1337             try:
1338                 self.inst_creator.clean()
1339             except Exception as e:
1340                 logger.error(
1341                     'Unexpected exception cleaning VM instance with message '
1342                     '- %s', e)
1343
1344         if self.keypair_creator:
1345             try:
1346                 self.keypair_creator.clean()
1347             except Exception as e:
1348                 logger.error(
1349                     'Unexpected exception cleaning keypair with message - %s',
1350                     e)
1351
1352         if os.path.isfile(self.keypair_pub_filepath):
1353             os.remove(self.keypair_pub_filepath)
1354
1355         if os.path.isfile(self.keypair_priv_filepath):
1356             os.remove(self.keypair_priv_filepath)
1357
1358         if self.flavor_creator:
1359             try:
1360                 self.flavor_creator.clean()
1361             except Exception as e:
1362                 logger.error(
1363                     'Unexpected exception cleaning flavor with message - %s',
1364                     e)
1365
1366         for router_creator in self.router_creators:
1367             try:
1368                 router_creator.clean()
1369             except Exception as e:
1370                 logger.error(
1371                     'Unexpected exception cleaning router with message - %s',
1372                     e)
1373
1374         for network_creator in self.network_creators:
1375             try:
1376                 network_creator.clean()
1377             except Exception as e:
1378                 logger.error(
1379                     'Unexpected exception cleaning network with message - %s',
1380                     e)
1381
1382         if self.sec_grp_creator:
1383             try:
1384                 self.sec_grp_creator.clean()
1385             except Exception as e:
1386                 logger.error(
1387                     'Unexpected exception cleaning security group with message'
1388                     ' - %s', e)
1389
1390         if self.image_creator and not self.image_creator.image_settings.exists:
1391             try:
1392                 self.image_creator.clean()
1393             except Exception as e:
1394                 logger.error(
1395                     'Unexpected exception cleaning image with message - %s', e)
1396
1397         super(self.__class__, self).__clean__()
1398
1399     def test_dual_ports_dhcp(self):
1400         """
1401         Tests the creation of an OpenStack instance with a dual ports/NICs with
1402         a DHCP assigned IP.
1403         NOTE: This test and any others that call ansible will most likely fail
1404         unless you do one of two things:
1405         1. Have a ~/.ansible.cfg (or alternate means) to
1406            set host_key_checking = False
1407         2. Set the following environment variable in your executing shell:
1408            ANSIBLE_HOST_KEY_CHECKING=False
1409         Should this not be performed, the creation of the host ssh key will
1410         cause your ansible calls to fail.
1411         """
1412         # Create ports/NICs for instance
1413         ports_settings = []
1414         ctr = 1
1415         for network_creator in self.network_creators:
1416             ports_settings.append(PortSettings(
1417                 name=self.guid + '-port-' + str(ctr),
1418                 network_name=network_creator.network_settings.name))
1419             ctr += 1
1420
1421         # Create instance
1422         instance_settings = VmInstanceSettings(
1423             name=self.vm_inst_name,
1424             flavor=self.flavor_creator.flavor_settings.name,
1425             port_settings=ports_settings,
1426             floating_ip_settings=[FloatingIpSettings(
1427                 name=self.floating_ip_name, port_name=self.port_1_name,
1428                 router_name=self.pub_net_config.router_settings.name)])
1429
1430         self.inst_creator = OpenStackVmInstance(
1431             self.os_creds, instance_settings,
1432             self.image_creator.image_settings,
1433             keypair_settings=self.keypair_creator.keypair_settings)
1434
1435         vm_inst = self.inst_creator.create(block=True)
1436
1437         self.assertEqual(vm_inst, self.inst_creator.get_vm_inst())
1438
1439         # Effectively blocks until VM has been properly activated
1440         self.assertTrue(self.inst_creator.vm_active(block=True))
1441
1442         ip = self.inst_creator.get_port_ip(ports_settings[0].name)
1443         self.assertTrue(check_dhcp_lease(self.inst_creator, ip))
1444
1445         # Add security group to VM
1446         self.inst_creator.add_security_group(
1447             self.sec_grp_creator.get_security_group())
1448
1449         # Effectively blocks until VM's ssh port has been opened
1450         self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1451
1452         self.assertEqual(0, self.inst_creator.config_nics())
1453
1454
1455 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1456     """
1457     Tests that include, add, and remove security groups from VM instances
1458     """
1459
1460     def setUp(self):
1461         """
1462         Instantiates the CreateImage object that is responsible for downloading
1463         and creating an OS image file within OpenStack
1464         """
1465         super(self.__class__, self).__start__()
1466
1467         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1468         self.vm_inst_name = self.guid + '-inst'
1469         self.nova = nova_utils.nova_client(self.os_creds)
1470         os_image_settings = openstack_tests.cirros_image_settings(
1471             name=self.guid + '-image', image_metadata=self.image_metadata)
1472
1473         self.vm_inst_name = self.guid + '-inst'
1474         self.port_1_name = self.guid + 'port-1'
1475         self.port_2_name = self.guid + 'port-2'
1476         self.floating_ip_name = self.guid + 'fip1'
1477
1478         net_config = openstack_tests.get_priv_net_config(
1479             net_name=self.guid + '-pub-net',
1480             subnet_name=self.guid + '-pub-subnet',
1481             router_name=self.guid + '-pub-router',
1482             external_net=self.ext_net_name)
1483
1484         # Initialize for tearDown()
1485         self.image_creator = None
1486         self.flavor_creator = None
1487         self.network_creator = None
1488         self.router_creator = None
1489         self.inst_creator = None
1490         self.sec_grp_creators = list()
1491
1492         try:
1493             # Create Image
1494             self.image_creator = OpenStackImage(self.os_creds,
1495                                                 os_image_settings)
1496             self.image_creator.create()
1497
1498             # Create Network
1499             self.network_creator = OpenStackNetwork(
1500                 self.os_creds, net_config.network_settings)
1501             self.network_creator.create()
1502
1503             # Create Flavor
1504             self.flavor_creator = OpenStackFlavor(
1505                 self.admin_os_creds,
1506                 FlavorSettings(name=self.guid + '-flavor-name', ram=256,
1507                                disk=10, vcpus=2,
1508                                metadata=self.flavor_metadata))
1509             self.flavor_creator.create()
1510
1511             self.port_settings = PortSettings(
1512                 name=self.guid + '-port',
1513                 network_name=net_config.network_settings.name)
1514         except Exception as e:
1515             self.tearDown()
1516             raise e
1517
1518     def tearDown(self):
1519         """
1520         Cleans the created object
1521         """
1522         if self.inst_creator:
1523             try:
1524                 self.inst_creator.clean()
1525             except Exception as e:
1526                 logger.error(
1527                     'Unexpected exception cleaning VM instance with message -'
1528                     ' %s', e)
1529
1530         for sec_grp_creator in self.sec_grp_creators:
1531             try:
1532                 sec_grp_creator.clean()
1533             except Exception as e:
1534                 logger.error(
1535                     'Unexpected exception cleaning security group with message'
1536                     ' - %s', e)
1537
1538         if self.flavor_creator:
1539             try:
1540                 self.flavor_creator.clean()
1541             except Exception as e:
1542                 logger.error(
1543                     'Unexpected exception cleaning flavor with message - %s',
1544                     e)
1545
1546         if self.network_creator:
1547             try:
1548                 self.network_creator.clean()
1549             except Exception as e:
1550                 logger.error(
1551                     'Unexpected exception cleaning network with message - %s',
1552                     e)
1553
1554         if self.image_creator and not self.image_creator.image_settings.exists:
1555             try:
1556                 self.image_creator.clean()
1557             except Exception as e:
1558                 logger.error(
1559                     'Unexpected exception cleaning image with message - %s', e)
1560
1561         super(self.__class__, self).__clean__()
1562
1563     def test_add_security_group(self):
1564         """
1565         Tests the addition of a security group created after the instance.
1566         """
1567         # Create instance
1568         instance_settings = VmInstanceSettings(
1569             name=self.vm_inst_name,
1570             flavor=self.flavor_creator.flavor_settings.name,
1571             port_settings=[self.port_settings])
1572         self.inst_creator = OpenStackVmInstance(
1573             self.os_creds, instance_settings,
1574             self.image_creator.image_settings)
1575         vm_inst = self.inst_creator.create(block=True)
1576         self.assertIsNotNone(vm_inst)
1577
1578         # Create security group object to add to instance
1579         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
1580                                                  description='hello group')
1581         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1582                                                  sec_grp_settings)
1583         sec_grp = sec_grp_creator.create()
1584         self.sec_grp_creators.append(sec_grp_creator)
1585
1586         # Check that group has not been added
1587         self.assertFalse(inst_has_sec_grp(
1588             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1589
1590         # Add security group to instance after activated
1591         self.inst_creator.add_security_group(sec_grp)
1592
1593         # Validate that security group has been added
1594         self.assertTrue(inst_has_sec_grp(
1595             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1596
1597     def test_add_invalid_security_group(self):
1598         """
1599         Tests the addition of a security group that no longer exists.
1600         """
1601         # Create instance
1602         instance_settings = VmInstanceSettings(
1603             name=self.vm_inst_name,
1604             flavor=self.flavor_creator.flavor_settings.name,
1605             port_settings=[self.port_settings])
1606         self.inst_creator = OpenStackVmInstance(
1607             self.os_creds, instance_settings,
1608             self.image_creator.image_settings)
1609         vm_inst = self.inst_creator.create(block=True)
1610         self.assertIsNotNone(vm_inst)
1611
1612         # Create security group object to add to instance
1613         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
1614                                                  description='hello group')
1615         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1616                                                  sec_grp_settings)
1617         sec_grp = sec_grp_creator.create()
1618         sec_grp_creator.clean()
1619         self.sec_grp_creators.append(sec_grp_creator)
1620
1621         # Check that group has not been added
1622         self.assertFalse(inst_has_sec_grp(
1623             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1624
1625         # Add security group to instance after activated
1626         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1627
1628         # Validate that security group has been added
1629         self.assertFalse(inst_has_sec_grp(
1630             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1631
1632     def test_remove_security_group(self):
1633         """
1634         Tests the removal of a security group created before and added to the
1635         instance.
1636         """
1637         # Create security group object to add to instance
1638         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
1639                                                  description='hello group')
1640         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1641                                                  sec_grp_settings)
1642         sec_grp = sec_grp_creator.create()
1643         self.sec_grp_creators.append(sec_grp_creator)
1644
1645         # Create instance
1646         instance_settings = VmInstanceSettings(
1647             name=self.vm_inst_name,
1648             flavor=self.flavor_creator.flavor_settings.name,
1649             security_group_names=[sec_grp_settings.name],
1650             port_settings=[self.port_settings])
1651         self.inst_creator = OpenStackVmInstance(
1652             self.os_creds, instance_settings,
1653             self.image_creator.image_settings)
1654         vm_inst = self.inst_creator.create(block=True)
1655         self.assertIsNotNone(vm_inst)
1656
1657         # Check that group has been added
1658         self.assertTrue(inst_has_sec_grp(
1659             self.nova, vm_inst, sec_grp_settings.name))
1660
1661         # Add security group to instance after activated
1662         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1663
1664         # Validate that security group has been added
1665         self.assertFalse(inst_has_sec_grp(
1666             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1667
1668     def test_remove_security_group_never_added(self):
1669         """
1670         Tests the removal of a security group that was never added in the first
1671         place.
1672         """
1673         # Create security group object to add to instance
1674         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
1675                                                  description='hello group')
1676         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1677                                                  sec_grp_settings)
1678         sec_grp = sec_grp_creator.create()
1679         self.sec_grp_creators.append(sec_grp_creator)
1680
1681         # Create instance
1682         instance_settings = VmInstanceSettings(
1683             name=self.vm_inst_name,
1684             flavor=self.flavor_creator.flavor_settings.name,
1685             port_settings=[self.port_settings])
1686         self.inst_creator = OpenStackVmInstance(
1687             self.os_creds, instance_settings,
1688             self.image_creator.image_settings)
1689         vm_inst = self.inst_creator.create(block=True)
1690         self.assertIsNotNone(vm_inst)
1691
1692         # Check that group has been added
1693         self.assertFalse(inst_has_sec_grp(
1694             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1695
1696         # Add security group to instance after activated
1697         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1698
1699         # Validate that security group has been added
1700         self.assertFalse(inst_has_sec_grp(
1701             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1702
1703     def test_add_same_security_group(self):
1704         """
1705         Tests the addition of a security group created before add added to the
1706         instance.
1707         """
1708         # Create security group object to add to instance
1709         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name',
1710                                                  description='hello group')
1711         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1712                                                  sec_grp_settings)
1713         sec_grp = sec_grp_creator.create()
1714         self.sec_grp_creators.append(sec_grp_creator)
1715
1716         # Create instance
1717         instance_settings = VmInstanceSettings(
1718             name=self.vm_inst_name,
1719             flavor=self.flavor_creator.flavor_settings.name,
1720             security_group_names=[sec_grp_settings.name],
1721             port_settings=[self.port_settings])
1722         self.inst_creator = OpenStackVmInstance(
1723             self.os_creds, instance_settings,
1724             self.image_creator.image_settings)
1725         vm_inst = self.inst_creator.create(block=True)
1726         self.assertIsNotNone(vm_inst)
1727
1728         # Check that group has been added
1729         self.assertTrue(inst_has_sec_grp(
1730             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1731
1732         # Add security group to instance after activated
1733         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1734
1735         # Validate that security group has been added
1736         self.assertTrue(inst_has_sec_grp(
1737             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1738
1739
1740 def inst_has_sec_grp(nova, vm_inst, sec_grp_name):
1741     """
1742     Returns true if instance has a security group of a given name
1743     :param nova: the nova client
1744     :param vm_inst: the VmInst domain object
1745     :param sec_grp_name: the name of the security group to validate
1746     :return: T/F
1747     """
1748     sec_grp_names = nova_utils.get_server_security_group_names(nova, vm_inst)
1749     for name in sec_grp_names:
1750         if sec_grp_name == name:
1751             return True
1752     return False
1753
1754
1755 def validate_ssh_client(instance_creator):
1756     """
1757     Returns True if instance_creator returns an SSH client that is valid
1758     :param instance_creator: the object responsible for creating the VM
1759                              instance
1760     :return: T/F
1761     """
1762     ssh_active = instance_creator.vm_ssh_active(block=True)
1763
1764     if ssh_active:
1765         ssh_client = instance_creator.ssh_client()
1766         if ssh_client:
1767             try:
1768                 out = ssh_client.exec_command('pwd')[1]
1769                 channel = out.channel
1770                 in_buffer = channel.in_buffer
1771                 pwd_out = in_buffer.read(1024)
1772                 if not pwd_out or len(pwd_out) < 10:
1773                     return False
1774                 return True
1775             finally:
1776                 ssh_client.close()
1777         else:
1778             return False
1779
1780     return False
1781
1782
1783 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1784     """
1785     Test for the CreateInstance class for creating an image from a 3-part image
1786     """
1787
1788     def setUp(self):
1789         """
1790         Instantiates the CreateImage object that is responsible for downloading
1791         and creating an OS image file within OpenStack
1792         """
1793         super(self.__class__, self).__start__()
1794
1795         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1796         self.image_name = guid
1797         self.vm_inst_name = guid + '-inst'
1798         self.nova = nova_utils.nova_client(self.os_creds)
1799
1800         net_config = openstack_tests.get_priv_net_config(
1801             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1802             router_name=guid + '-pub-router', external_net=self.ext_net_name)
1803
1804         # Initialize for tearDown()
1805         self.image_creator = None
1806         self.network_creator = None
1807         self.flavor_creator = None
1808         self.inst_creator = None
1809
1810         try:
1811             if self.image_metadata and 'disk_file' in self.image_metadata:
1812                 metadata = self.image_metadata
1813             elif self.image_metadata and 'cirros' in self.image_metadata \
1814                     and 'disk_file' in self.image_metadata['cirros']:
1815                 metadata = self.image_metadata['cirros']
1816             else:
1817                 metadata = {
1818                     'disk_url': openstack_tests.CIRROS_DEFAULT_IMAGE_URL,
1819                     'kernel_url':
1820                         openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL,
1821                     'ramdisk_url':
1822                         openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL}
1823
1824             image_settings = openstack_tests.cirros_image_settings(
1825                 name=self.image_name,
1826                 image_metadata=metadata)
1827
1828             if not image_settings.ramdisk_image_settings or not \
1829                     image_settings.kernel_image_settings:
1830                 logger.warn(
1831                     '3 Part image will not be tested. Image metadata has '
1832                     'overridden this functionality')
1833
1834             self.image_creator = OpenStackImage(self.os_creds, image_settings)
1835             self.image_creator.create()
1836
1837             # Create Flavor
1838             self.flavor_creator = OpenStackFlavor(
1839                 self.admin_os_creds,
1840                 FlavorSettings(name=guid + '-flavor-name', ram=256, disk=10,
1841                                vcpus=2, metadata=self.flavor_metadata))
1842             self.flavor_creator.create()
1843
1844             # Create Network
1845             self.network_creator = OpenStackNetwork(
1846                 self.os_creds, net_config.network_settings)
1847             self.network_creator.create()
1848
1849             self.port_settings = PortSettings(
1850                 name=guid + '-port',
1851                 network_name=net_config.network_settings.name)
1852         except Exception as e:
1853             self.tearDown()
1854             raise e
1855
1856     def tearDown(self):
1857         """
1858         Cleans the created object
1859         """
1860         if self.inst_creator:
1861             try:
1862                 self.inst_creator.clean()
1863             except Exception as e:
1864                 logger.error(
1865                     'Unexpected exception cleaning VM instance with message -'
1866                     ' %s', e)
1867
1868         if self.flavor_creator:
1869             try:
1870                 self.flavor_creator.clean()
1871             except Exception as e:
1872                 logger.error(
1873                     'Unexpected exception cleaning flavor with message - %s',
1874                     e)
1875
1876         if self.network_creator:
1877             try:
1878                 self.network_creator.clean()
1879             except Exception as e:
1880                 logger.error(
1881                     'Unexpected exception cleaning network with message - %s',
1882                     e)
1883
1884         if self.image_creator and not self.image_creator.image_settings.exists:
1885             try:
1886                 self.image_creator.clean()
1887             except Exception as e:
1888                 logger.error(
1889                     'Unexpected exception cleaning image with message - %s', e)
1890
1891         super(self.__class__, self).__clean__()
1892
1893     def test_create_instance_from_three_part_image(self):
1894         """
1895         Tests the creation of an OpenStack instance from a 3-part image.
1896         """
1897         instance_settings = VmInstanceSettings(
1898             name=self.vm_inst_name,
1899             flavor=self.flavor_creator.flavor_settings.name,
1900             port_settings=[self.port_settings])
1901
1902         # The last created image is the main image from which we create the
1903         # instance
1904         self.inst_creator = OpenStackVmInstance(
1905             self.os_creds, instance_settings,
1906             self.image_creator.image_settings)
1907
1908         vm_inst = self.inst_creator.create()
1909         self.assertIsNotNone(vm_inst)
1910         self.assertTrue(self.inst_creator.vm_active(block=True))
1911
1912
1913 class CreateInstanceMockOfflineTests(OSComponentTestCase):
1914     """
1915     Tests the custom image_metadata that can be set by clients for handling
1916     images differently than the default behavior of the existing tests
1917     primarily for offline testing
1918     """
1919
1920     def setUp(self):
1921         """
1922         Instantiates the CreateImage object that is responsible for downloading
1923         and creating an OS image file within OpenStack
1924         """
1925         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1926
1927         self.tmpDir = 'tmp/' + str(self.guid)
1928         if not os.path.exists(self.tmpDir):
1929             os.makedirs(self.tmpDir)
1930
1931         self.image_name = self.guid + '-image'
1932         self.vm_inst_name = self.guid + '-inst'
1933         self.port_1_name = self.guid + 'port-1'
1934
1935         # Initialize for tearDown()
1936         self.image_creator = None
1937         self.network_creator = None
1938         self.flavor_creator = None
1939         self.inst_creator = None
1940
1941         self.priv_net_config = openstack_tests.get_priv_net_config(
1942             net_name=self.guid + '-priv-net',
1943             subnet_name=self.guid + '-priv-subnet')
1944         self.port_settings = PortSettings(
1945             name=self.port_1_name,
1946             network_name=self.priv_net_config.network_settings.name)
1947
1948         try:
1949             # Download image file
1950             self.image_file = file_utils.download(
1951                 openstack_tests.CIRROS_DEFAULT_IMAGE_URL, self.tmpDir)
1952
1953             # Create Network
1954             self.network_creator = OpenStackNetwork(
1955                 self.os_creds, self.priv_net_config.network_settings)
1956             self.network_creator.create()
1957
1958             # Create Flavor
1959             self.flavor_creator = OpenStackFlavor(
1960                 self.os_creds,
1961                 FlavorSettings(
1962                     name=self.guid + '-flavor-name', ram=256, disk=10,
1963                     vcpus=1))
1964             self.flavor_creator.create()
1965         except Exception as e:
1966             self.tearDown()
1967             raise e
1968
1969     def tearDown(self):
1970         """
1971         Cleans the created object
1972         """
1973         if self.inst_creator:
1974             try:
1975                 self.inst_creator.clean()
1976             except Exception as e:
1977                 logger.error(
1978                     'Unexpected exception cleaning VM instance with message - '
1979                     '%s', e)
1980
1981         if self.network_creator:
1982             try:
1983                 self.network_creator.clean()
1984             except Exception as e:
1985                 logger.error(
1986                     'Unexpected exception cleaning network with message - %s',
1987                     e)
1988
1989         if self.flavor_creator:
1990             try:
1991                 self.flavor_creator.clean()
1992             except Exception as e:
1993                 logger.error(
1994                     'Unexpected exception cleaning flavor with message - %s',
1995                     e)
1996
1997         if self.image_creator:
1998             try:
1999                 self.image_creator.clean()
2000             except Exception as e:
2001                 logger.error(
2002                     'Unexpected exception cleaning image with message - %s', e)
2003
2004         if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir):
2005             shutil.rmtree(self.tmpDir)
2006
2007     def test_inst_from_file_image_simple_flat(self):
2008         """
2009         Creates a VM instance from a locally sourced file image using simply
2010         the 'disk_file' attribute vs. using the 'config' option which
2011         completely overrides all image settings
2012         :return: 
2013         """
2014         metadata = {'disk_file': self.image_file.name}
2015
2016         os_image_settings = openstack_tests.cirros_image_settings(
2017             name=self.image_name, image_metadata=metadata)
2018         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2019         self.assertEqual(openstack_tests.CIRROS_USER,
2020                          os_image_settings.image_user)
2021         self.assertIsNone(os_image_settings.url)
2022         self.assertFalse(os_image_settings.exists)
2023         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2024                          os_image_settings.format)
2025
2026         self.assertIsNone(os_image_settings.kernel_image_settings)
2027         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2028
2029         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2030         self.image_creator.create()
2031
2032         instance_settings = VmInstanceSettings(
2033             name=self.vm_inst_name,
2034             flavor=self.flavor_creator.flavor_settings.name,
2035             port_settings=[self.port_settings])
2036         self.inst_creator = OpenStackVmInstance(
2037             self.os_creds, instance_settings,
2038             self.image_creator.image_settings)
2039         self.inst_creator.create()
2040
2041         self.assertTrue(self.inst_creator.vm_active(block=True))
2042
2043     def test_inst_from_file_image_simple_nested(self):
2044         """
2045         Creates a VM instance from a locally sourced file image using simply
2046         the 'disk_file' attribute under 'cirros' vs. using the 'config' option
2047         which completely overrides all image settings
2048         :return: 
2049         """
2050         metadata = {'cirros': {'disk_file': self.image_file.name}}
2051
2052         os_image_settings = openstack_tests.cirros_image_settings(
2053             name=self.image_name, image_metadata=metadata)
2054         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2055         self.assertEqual(openstack_tests.CIRROS_USER,
2056                          os_image_settings.image_user)
2057         self.assertIsNone(os_image_settings.url)
2058         self.assertFalse(os_image_settings.exists)
2059         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2060                          os_image_settings.format)
2061
2062         self.assertIsNone(os_image_settings.kernel_image_settings)
2063         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2064
2065         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2066         self.image_creator.create()
2067
2068         instance_settings = VmInstanceSettings(
2069             name=self.vm_inst_name,
2070             flavor=self.flavor_creator.flavor_settings.name,
2071             port_settings=[self.port_settings])
2072         self.inst_creator = OpenStackVmInstance(
2073             self.os_creds, instance_settings,
2074             self.image_creator.image_settings)
2075         self.inst_creator.create()
2076
2077         self.assertTrue(self.inst_creator.vm_active(block=True))
2078
2079     def test_inst_from_existing(self):
2080         """
2081         Creates a VM instance from a image creator that has been configured to
2082         use an existing image
2083         :return: 
2084         """
2085         os_image_settings = openstack_tests.cirros_image_settings(
2086             name=self.image_name)
2087         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2088         self.image_creator.create()
2089
2090         image_settings = self.image_creator.image_settings
2091         test_image_creator = OpenStackImage(
2092             self.os_creds,
2093             ImageSettings(name=image_settings.name,
2094                           image_user=image_settings.image_user,
2095                           exists=True))
2096         test_image_creator.create()
2097         self.assertEqual(self.image_creator.get_image().id,
2098                          test_image_creator.get_image().id)
2099
2100         instance_settings = VmInstanceSettings(
2101             name=self.vm_inst_name,
2102             flavor=self.flavor_creator.flavor_settings.name,
2103             port_settings=[self.port_settings])
2104         self.inst_creator = OpenStackVmInstance(
2105             self.os_creds, instance_settings,
2106             test_image_creator.image_settings)
2107         self.inst_creator.create()
2108
2109         self.assertTrue(self.inst_creator.vm_active(block=True))
2110
2111     def test_inst_from_file_image_complex(self):
2112         """
2113         Creates a VM instance from a locally sourced file image by overriding
2114         the default settings by using a dict() that can be read in by
2115         ImageSettings
2116         :return: 
2117         """
2118
2119         os_image_settings = openstack_tests.cirros_image_settings(
2120             name=self.image_name)
2121         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2122         self.image_creator.create()
2123
2124         metadata = {
2125             'cirros': {
2126                 'config': {
2127                     'name': os_image_settings.name,
2128                     'image_user': os_image_settings.image_user,
2129                     'exists': True}}}
2130         test_image_settings = openstack_tests.cirros_image_settings(
2131             image_metadata=metadata)
2132         test_image = OpenStackImage(self.os_creds, test_image_settings)
2133         test_image.create()
2134
2135         instance_settings = VmInstanceSettings(
2136             name=self.vm_inst_name,
2137             flavor=self.flavor_creator.flavor_settings.name,
2138             port_settings=[self.port_settings])
2139         self.inst_creator = OpenStackVmInstance(self.os_creds,
2140                                                 instance_settings,
2141                                                 test_image_settings)
2142         self.inst_creator.create()
2143
2144         self.assertTrue(self.inst_creator.vm_active(block=True))
2145
2146     def test_inst_from_file_3part_image_complex(self):
2147         """
2148         Creates a VM instance from a locally sourced file image by overriding
2149         the default settings by using a dict() that can be read in by
2150         ImageSettings
2151         :return: 
2152         """
2153
2154         kernel_file = file_utils.download(
2155             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2156         ramdisk_file = file_utils.download(
2157             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2158
2159         metadata = {
2160             'cirros': {
2161                 'config': {
2162                     'name': self.image_name,
2163                     'image_user': openstack_tests.CIRROS_USER,
2164                     'image_file': self.image_file.name,
2165                     'format': openstack_tests.DEFAULT_IMAGE_FORMAT,
2166                     'kernel_image_settings': {
2167                         'name': self.image_name + '-kernel',
2168                         'image_user': openstack_tests.CIRROS_USER,
2169                         'image_file': kernel_file.name,
2170                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT},
2171                     'ramdisk_image_settings': {
2172                         'name': self.image_name + '-ramdisk',
2173                         'image_user': openstack_tests.CIRROS_USER,
2174                         'image_file': ramdisk_file.name,
2175                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}}
2176
2177         os_image_settings = openstack_tests.cirros_image_settings(
2178             name=self.image_name, image_metadata=metadata)
2179         self.assertEqual(self.image_name, os_image_settings.name)
2180         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2181         self.assertEqual(openstack_tests.CIRROS_USER,
2182                          os_image_settings.image_user)
2183         self.assertIsNone(os_image_settings.url)
2184         self.assertFalse(os_image_settings.exists)
2185         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2186                          os_image_settings.format)
2187
2188         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2189         self.assertEqual(self.image_name + '-kernel',
2190                          os_image_settings.kernel_image_settings.name)
2191         self.assertEqual(kernel_file.name,
2192                          os_image_settings.kernel_image_settings.image_file)
2193         self.assertEqual(openstack_tests.CIRROS_USER,
2194                          os_image_settings.kernel_image_settings.image_user)
2195         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2196         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2197         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2198                          os_image_settings.kernel_image_settings.format)
2199
2200         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2201         self.assertEqual(self.image_name + '-ramdisk',
2202                          os_image_settings.ramdisk_image_settings.name)
2203         self.assertEqual(ramdisk_file.name,
2204                          os_image_settings.ramdisk_image_settings.image_file)
2205         self.assertEqual(openstack_tests.CIRROS_USER,
2206                          os_image_settings.ramdisk_image_settings.image_user)
2207         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2208         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2209         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2210                          os_image_settings.ramdisk_image_settings.format)
2211
2212         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2213         self.image_creator.create()
2214
2215         instance_settings = VmInstanceSettings(
2216             name=self.vm_inst_name,
2217             flavor=self.flavor_creator.flavor_settings.name,
2218             port_settings=[self.port_settings])
2219         self.inst_creator = OpenStackVmInstance(
2220             self.os_creds, instance_settings,
2221             self.image_creator.image_settings)
2222         self.inst_creator.create()
2223
2224         self.assertTrue(self.inst_creator.vm_active(block=True))
2225
2226     def test_inst_from_file_3part_image_simple_flat(self):
2227         """
2228         Creates a VM instance from a 3-part image locally sourced from file
2229         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2230         attributes vs. using the 'config' option which completely overrides all
2231         image settings
2232         :return: 
2233         """
2234         kernel_file = file_utils.download(
2235             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2236         ramdisk_file = file_utils.download(
2237             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2238
2239         metadata = {'disk_file': self.image_file.name,
2240                     'kernel_file': kernel_file.name,
2241                     'ramdisk_file': ramdisk_file.name}
2242
2243         os_image_settings = openstack_tests.cirros_image_settings(
2244             name=self.image_name, image_metadata=metadata)
2245
2246         self.assertEqual(self.image_name, os_image_settings.name)
2247         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2248         self.assertEqual(openstack_tests.CIRROS_USER,
2249                          os_image_settings.image_user)
2250         self.assertIsNone(os_image_settings.url)
2251         self.assertFalse(os_image_settings.exists)
2252         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2253                          os_image_settings.format)
2254
2255         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2256         self.assertEqual(self.image_name + '-kernel',
2257                          os_image_settings.kernel_image_settings.name)
2258         self.assertEqual(kernel_file.name,
2259                          os_image_settings.kernel_image_settings.image_file)
2260         self.assertEqual(openstack_tests.CIRROS_USER,
2261                          os_image_settings.kernel_image_settings.image_user)
2262         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2263         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2264         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2265                          os_image_settings.kernel_image_settings.format)
2266
2267         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2268         self.assertEqual(self.image_name + '-ramdisk',
2269                          os_image_settings.ramdisk_image_settings.name)
2270         self.assertEqual(ramdisk_file.name,
2271                          os_image_settings.ramdisk_image_settings.image_file)
2272         self.assertEqual(openstack_tests.CIRROS_USER,
2273                          os_image_settings.ramdisk_image_settings.image_user)
2274         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2275         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2276         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2277                          os_image_settings.ramdisk_image_settings.format)
2278
2279         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2280         self.image_creator.create()
2281
2282         self.assertIsNotNone(self.image_creator.get_kernel_image())
2283         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2284
2285         instance_settings = VmInstanceSettings(
2286             name=self.vm_inst_name,
2287             flavor=self.flavor_creator.flavor_settings.name,
2288             port_settings=[self.port_settings])
2289         self.inst_creator = OpenStackVmInstance(
2290             self.os_creds, instance_settings,
2291             self.image_creator.image_settings)
2292         self.inst_creator.create()
2293
2294         self.assertTrue(self.inst_creator.vm_active(block=True))
2295
2296     def test_inst_from_file_3part_image_simple_nested(self):
2297         """
2298         Creates a VM instance from a 3-part image locally sourced from file
2299         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2300         attributes under 'cirros' vs. using the 'config' option which
2301         completely overrides all image settings
2302         :return: 
2303         """
2304         kernel_file = file_utils.download(
2305             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2306         ramdisk_file = file_utils.download(
2307             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2308
2309         metadata = {'cirros': {'disk_file': self.image_file.name,
2310                                'kernel_file': kernel_file.name,
2311                                'ramdisk_file': ramdisk_file.name}}
2312
2313         os_image_settings = openstack_tests.cirros_image_settings(
2314             name=self.image_name, image_metadata=metadata)
2315
2316         self.assertEqual(self.image_name, os_image_settings.name)
2317         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2318         self.assertEqual(openstack_tests.CIRROS_USER,
2319                          os_image_settings.image_user)
2320         self.assertIsNone(os_image_settings.url)
2321         self.assertFalse(os_image_settings.exists)
2322         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2323                          os_image_settings.format)
2324
2325         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2326         self.assertEqual(self.image_name + '-kernel',
2327                          os_image_settings.kernel_image_settings.name)
2328         self.assertEqual(kernel_file.name,
2329                          os_image_settings.kernel_image_settings.image_file)
2330         self.assertEqual(openstack_tests.CIRROS_USER,
2331                          os_image_settings.kernel_image_settings.image_user)
2332         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2333         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2334         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2335                          os_image_settings.kernel_image_settings.format)
2336
2337         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2338         self.assertEqual(self.image_name + '-ramdisk',
2339                          os_image_settings.ramdisk_image_settings.name)
2340         self.assertEqual(ramdisk_file.name,
2341                          os_image_settings.ramdisk_image_settings.image_file)
2342         self.assertEqual(openstack_tests.CIRROS_USER,
2343                          os_image_settings.ramdisk_image_settings.image_user)
2344         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2345         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2346         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2347                          os_image_settings.ramdisk_image_settings.format)
2348
2349         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2350         self.image_creator.create()
2351
2352         self.assertIsNotNone(self.image_creator.get_kernel_image())
2353         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2354
2355         instance_settings = VmInstanceSettings(
2356             name=self.vm_inst_name,
2357             flavor=self.flavor_creator.flavor_settings.name,
2358             port_settings=[self.port_settings])
2359         self.inst_creator = OpenStackVmInstance(
2360             self.os_creds, instance_settings,
2361             self.image_creator.image_settings)
2362         self.inst_creator.create()
2363
2364         self.assertTrue(self.inst_creator.vm_active(block=True))
2365
2366     def test_inst_from_file_3part_image_existing(self):
2367         """
2368         Creates a VM instance from a 3-part image that is existing
2369         :return: 
2370         """
2371         kernel_file = file_utils.download(
2372             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2373         ramdisk_file = file_utils.download(
2374             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2375
2376         metadata = {'cirros': {'disk_file': self.image_file.name,
2377                                'kernel_file': kernel_file.name,
2378                                'ramdisk_file': ramdisk_file.name}}
2379
2380         os_image_settings = openstack_tests.cirros_image_settings(
2381             name=self.image_name, image_metadata=metadata)
2382         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2383         self.image_creator.create()
2384
2385         image_settings = self.image_creator.image_settings
2386         test_image_creator = OpenStackImage(
2387             self.os_creds,
2388             ImageSettings(name=image_settings.name,
2389                           image_user=image_settings.image_user,
2390                           exists=True))
2391         test_image_creator.create()
2392         self.assertEqual(self.image_creator.get_image().id,
2393                          test_image_creator.get_image().id)
2394
2395         instance_settings = VmInstanceSettings(
2396             name=self.vm_inst_name,
2397             flavor=self.flavor_creator.flavor_settings.name,
2398             port_settings=[self.port_settings])
2399         self.inst_creator = OpenStackVmInstance(
2400             self.os_creds, instance_settings,
2401             test_image_creator.image_settings)
2402         self.inst_creator.create()
2403
2404         self.assertTrue(self.inst_creator.vm_active(block=True))
2405
2406
2407 class CreateInstanceTwoNetTests(OSIntegrationTestCase):
2408     """
2409     Tests the ability of two VMs to communicate when attached to separate
2410     private networks that are tied together with a router.
2411     """
2412
2413     def setUp(self):
2414         """
2415         Instantiates the CreateImage object that is responsible for downloading
2416         and creating an OS image file within OpenStack
2417         """
2418         super(self.__class__, self).__start__()
2419
2420         cidr1 = '10.200.201.0/24'
2421         cidr2 = '10.200.202.0/24'
2422         static_gateway_ip1 = '10.200.201.1'
2423         static_gateway_ip2 = '10.200.202.1'
2424         self.ip1 = '10.200.201.5'
2425         self.ip2 = '10.200.202.5'
2426
2427         self.nova = nova_utils.nova_client(self.os_creds)
2428
2429         # Initialize for tearDown()
2430         self.image_creator = None
2431         self.network_creators = list()
2432         self.router_creator = None
2433         self.flavor_creator = None
2434         self.sec_grp_creator = None
2435         self.inst_creators = list()
2436
2437         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2438         self.vm_inst1_name = self.guid + '-inst1'
2439         self.vm_inst2_name = self.guid + '-inst2'
2440         self.port_1_name = self.guid + '-vm1-port'
2441         self.port_2_name = self.guid + '-vm2-port'
2442         self.net_config_1 = NetworkSettings(
2443             name=self.guid + '-net1',
2444             subnet_settings=[
2445                 create_network.SubnetSettings(
2446                     cidr=cidr1, name=self.guid + '-subnet1',
2447                     gateway_ip=static_gateway_ip1)])
2448         self.net_config_2 = NetworkSettings(
2449             name=self.guid + '-net2',
2450             subnet_settings=[
2451                 create_network.SubnetSettings(
2452                     cidr=cidr2, name=self.guid + '-subnet2',
2453                     gateway_ip=static_gateway_ip2)])
2454
2455         image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
2456         os_image_settings = openstack_tests.cirros_image_settings(
2457             name=image_name, image_metadata=self.image_metadata)
2458
2459         try:
2460             # Create Image
2461             self.image_creator = OpenStackImage(self.os_creds,
2462                                                 os_image_settings)
2463             self.image_creator.create()
2464
2465             # First network is public
2466             self.network_creators.append(OpenStackNetwork(
2467                 self.os_creds, self.net_config_1))
2468             # Second network is private
2469             self.network_creators.append(OpenStackNetwork(
2470                 self.os_creds, self.net_config_2))
2471             for network_creator in self.network_creators:
2472                 network_creator.create()
2473
2474             port_settings = [
2475                 create_network.PortSettings(
2476                     name=self.guid + '-router-port1',
2477                     ip_addrs=[{
2478                         'subnet_name':
2479                             self.net_config_1.subnet_settings[0].name,
2480                         'ip': static_gateway_ip1
2481                     }],
2482                     network_name=self.net_config_1.name,
2483                     project_name=self.os_creds.project_name),
2484                 create_network.PortSettings(
2485                     name=self.guid + '-router-port2',
2486                     ip_addrs=[{
2487                         'subnet_name':
2488                             self.net_config_2.subnet_settings[0].name,
2489                         'ip': static_gateway_ip2
2490                     }],
2491                     network_name=self.net_config_2.name,
2492                     project_name=self.os_creds.project_name)]
2493
2494             router_settings = RouterSettings(name=self.guid + '-pub-router',
2495                                              port_settings=port_settings)
2496             self.router_creator = create_router.OpenStackRouter(
2497                 self.os_creds, router_settings)
2498             self.router_creator.create()
2499
2500             # Create Flavor
2501             self.flavor_creator = OpenStackFlavor(
2502                 self.admin_os_creds,
2503                 FlavorSettings(name=self.guid + '-flavor-name', ram=512,
2504                                disk=10, vcpus=2,
2505                                metadata=self.flavor_metadata))
2506             self.flavor_creator.create()
2507
2508             sec_grp_name = self.guid + '-sec-grp'
2509             rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
2510                                               direction=Direction.ingress,
2511                                               protocol=Protocol.icmp)
2512             self.sec_grp_creator = OpenStackSecurityGroup(
2513                 self.os_creds,
2514                 SecurityGroupSettings(name=sec_grp_name,
2515                                       rule_settings=[rule1]))
2516             self.sec_grp_creator.create()
2517         except:
2518             self.tearDown()
2519             raise
2520
2521     def tearDown(self):
2522         """
2523         Cleans the created objects
2524         """
2525         for inst_creator in self.inst_creators:
2526             try:
2527                 inst_creator.clean()
2528             except Exception as e:
2529                 logger.error(
2530                     'Unexpected exception cleaning VM instance with message '
2531                     '- %s', e)
2532
2533         if self.flavor_creator:
2534             try:
2535                 self.flavor_creator.clean()
2536             except Exception as e:
2537                 logger.error(
2538                     'Unexpected exception cleaning flavor with message - %s',
2539                     e)
2540
2541         if self.router_creator:
2542             try:
2543                 self.router_creator.clean()
2544             except Exception as e:
2545                 logger.error(
2546                     'Unexpected exception cleaning router with message - %s',
2547                     e)
2548
2549         for network_creator in self.network_creators:
2550             try:
2551                 network_creator.clean()
2552             except Exception as e:
2553                 logger.error(
2554                     'Unexpected exception cleaning network with message - %s',
2555                     e)
2556
2557         if self.sec_grp_creator:
2558             try:
2559                 self.sec_grp_creator.clean()
2560             except Exception as e:
2561                 logger.error(
2562                     'Unexpected exception cleaning security group with message'
2563                     ' - %s', e)
2564
2565         if self.image_creator and not self.image_creator.image_settings.exists:
2566             try:
2567                 self.image_creator.clean()
2568             except Exception as e:
2569                 logger.error(
2570                     'Unexpected exception cleaning image with message - %s', e)
2571
2572         super(self.__class__, self).__clean__()
2573
2574     def test_ping_via_router(self):
2575         """
2576         Tests the creation of two OpenStack instances with one port on
2577         different private networks wit a router in between to ensure that they
2578         can ping
2579         through
2580         """
2581         # Create ports/NICs for instance
2582         ports_settings = []
2583         ctr = 1
2584         for network_creator in self.network_creators:
2585             ports_settings.append(PortSettings(
2586                 name=self.guid + '-port-' + str(ctr),
2587                 network_name=network_creator.network_settings.name))
2588             ctr += 1
2589
2590         # Configure instances
2591         instance1_settings = VmInstanceSettings(
2592             name=self.vm_inst1_name,
2593             flavor=self.flavor_creator.flavor_settings.name,
2594             userdata=_get_ping_userdata(self.ip2),
2595             port_settings=[PortSettings(
2596                 name=self.port_1_name,
2597                 ip_addrs=[{
2598                     'subnet_name':
2599                         self.net_config_1.subnet_settings[0].name,
2600                     'ip': self.ip1
2601                 }],
2602                 network_name=self.network_creators[0].network_settings.name)])
2603         instance2_settings = VmInstanceSettings(
2604             name=self.vm_inst2_name,
2605             flavor=self.flavor_creator.flavor_settings.name,
2606             userdata=_get_ping_userdata(self.ip1),
2607             port_settings=[PortSettings(
2608                 name=self.port_2_name,
2609                 ip_addrs=[{
2610                     'subnet_name':
2611                         self.net_config_2.subnet_settings[0].name,
2612                     'ip': self.ip2
2613                 }],
2614                 network_name=self.network_creators[1].network_settings.name)])
2615
2616         # Create instances
2617         self.inst_creators.append(OpenStackVmInstance(
2618             self.os_creds, instance1_settings,
2619             self.image_creator.image_settings))
2620         self.inst_creators.append(OpenStackVmInstance(
2621             self.os_creds, instance2_settings,
2622             self.image_creator.image_settings))
2623
2624         for inst_creator in self.inst_creators:
2625             inst_creator.create(block=True)
2626
2627         # Check for DHCP lease
2628         self.assertTrue(check_dhcp_lease(self.inst_creators[0], self.ip1))
2629         self.assertTrue(check_dhcp_lease(self.inst_creators[1], self.ip2))
2630
2631         # Effectively blocks until VM has been properly activated
2632         self.assertTrue(check_ping(self.inst_creators[0]))
2633         self.assertTrue(check_ping(self.inst_creators[1]))
2634
2635
2636 def check_dhcp_lease(inst_creator, ip, timeout=160):
2637     """
2638     Returns true if the expected DHCP lease has been acquired
2639     :param inst_creator: the SNAPS OpenStackVmInstance object
2640     :param ip: the IP address to look for
2641     :param timeout: how long to query for IP address
2642     :return:
2643     """
2644     found = False
2645     start_time = time.time()
2646
2647     logger.info("Looking for IP %s in the console log" % ip)
2648     full_log = ''
2649     while timeout > time.time() - start_time:
2650         output = inst_creator.get_console_output()
2651         full_log = full_log + output
2652         if re.search(ip, output):
2653             logger.info('DHCP lease obtained logged in console')
2654             found = True
2655             break
2656
2657     if not found:
2658         logger.error('Full console output -\n' + full_log)
2659     else:
2660         logger.debug('Full console output -\n' + full_log)
2661
2662     return found
2663
2664
2665 def _get_ping_userdata(test_ip):
2666     """
2667     Returns the post VM creation script to be added into the VM's userdata
2668     :param test_ip: the IP value to substitute into the script
2669     :return: the bash script contents
2670     """
2671     if test_ip:
2672         return ("#!/bin/sh\n\n"
2673                 "while true; do\n"
2674                 " ping -c 1 %s 2>&1 >/dev/null\n"
2675                 " RES=$?\n"
2676                 " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
2677                 "  echo 'vPing OK'\n"
2678                 "  break\n"
2679                 " else\n"
2680                 "  echo 'vPing KO'\n"
2681                 " fi\n"
2682                 " sleep 1\n"
2683                 "done\n" % test_ip)
2684     return None
2685
2686
2687 def check_ping(vm_creator, timeout=160):
2688     """
2689     Check for VM for ping result
2690     """
2691     tries = 0
2692
2693     while tries < timeout:
2694         time.sleep(1)
2695         p_console = vm_creator.get_console_output()
2696         if "vPing OK" in p_console:
2697             return True
2698         elif "failed to read iid from metadata" in p_console or tries > 5:
2699             return False
2700         tries += 1
2701
2702     return False