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