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