reduce instance's memory size
[snaps.git] / snaps / openstack / tests / create_instance_tests.py
1 # Copyright (c) 2016 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 os
17 import re
18 import time
19 import unittest
20 import uuid
21
22 from snaps.openstack.create_instance import VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings
23 from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
24 from snaps.openstack.create_keypairs import OpenStackKeypair, KeypairSettings
25 from snaps.openstack.create_network import OpenStackNetwork, PortSettings
26 from snaps.openstack.create_router import OpenStackRouter
27 from snaps.openstack.create_image import OpenStackImage
28 from snaps.openstack.create_security_group import SecurityGroupSettings, OpenStackSecurityGroup
29 from snaps.openstack.tests import openstack_tests, validation_utils
30 from snaps.openstack.utils import nova_utils
31 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
32
33 __author__ = 'spisarski'
34
35 VM_BOOT_TIMEOUT = 600
36
37 logger = logging.getLogger('create_instance_tests')
38
39
40 class VmInstanceSettingsUnitTests(unittest.TestCase):
41     """
42     Tests the construction of the VmInstanceSettings class
43     """
44
45     def test_no_params(self):
46         with self.assertRaises(Exception):
47             VmInstanceSettings()
48
49     def test_empty_config(self):
50         with self.assertRaises(Exception):
51             VmInstanceSettings(config=dict())
52
53     def test_name_only(self):
54         with self.assertRaises(Exception):
55             VmInstanceSettings(name='foo')
56
57     def test_config_with_name_only(self):
58         with self.assertRaises(Exception):
59             VmInstanceSettings(config={'name': 'foo'})
60
61     def test_name_flavor_only(self):
62         with self.assertRaises(Exception):
63             VmInstanceSettings(name='foo', flavor='bar')
64
65     def test_config_with_name_flavor_only(self):
66         with self.assertRaises(Exception):
67             VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
68
69     def test_name_flavor_port_only(self):
70         port_settings = PortSettings(name='foo-port', network_name='bar-net')
71         settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings])
72         self.assertEquals('foo', settings.name)
73         self.assertEquals('bar', settings.flavor)
74         self.assertEquals(1, len(settings.port_settings))
75         self.assertEquals('foo-port', settings.port_settings[0].name)
76         self.assertEquals('bar-net', settings.port_settings[0].network_name)
77         self.assertEquals(0, len(settings.security_group_names))
78         self.assertEquals(0, len(settings.floating_ip_settings))
79         self.assertIsNone(settings.sudo_user)
80         self.assertEquals(900, settings.vm_boot_timeout)
81         self.assertEquals(300, settings.vm_delete_timeout)
82         self.assertEquals(180, settings.ssh_connect_timeout)
83         self.assertIsNone(settings.availability_zone)
84
85     def test_config_with_name_flavor_port_only(self):
86         port_settings = PortSettings(name='foo-port', network_name='bar-net')
87         settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
88         self.assertEquals('foo', settings.name)
89         self.assertEquals('bar', settings.flavor)
90         self.assertEquals(1, len(settings.port_settings))
91         self.assertEquals('foo-port', settings.port_settings[0].name)
92         self.assertEquals('bar-net', settings.port_settings[0].network_name)
93         self.assertEquals(0, len(settings.security_group_names))
94         self.assertEquals(0, len(settings.floating_ip_settings))
95         self.assertIsNone(settings.sudo_user)
96         self.assertEquals(900, settings.vm_boot_timeout)
97         self.assertEquals(300, settings.vm_delete_timeout)
98         self.assertEquals(180, settings.ssh_connect_timeout)
99         self.assertIsNone(settings.availability_zone)
100
101     def test_all(self):
102         port_settings = PortSettings(name='foo-port', network_name='bar-net')
103         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router')
104
105         settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings],
106                                       security_group_names=['sec_grp_1'], floating_ip_settings=[fip_settings],
107                                       sudo_user='joe', vm_boot_timeout=999, vm_delete_timeout=333,
108                                       ssh_connect_timeout=111, availability_zone='server name')
109         self.assertEquals('foo', settings.name)
110         self.assertEquals('bar', settings.flavor)
111         self.assertEquals(1, len(settings.port_settings))
112         self.assertEquals('foo-port', settings.port_settings[0].name)
113         self.assertEquals('bar-net', settings.port_settings[0].network_name)
114         self.assertEquals(1, len(settings.security_group_names))
115         self.assertEquals('sec_grp_1', settings.security_group_names[0])
116         self.assertEquals(1, len(settings.floating_ip_settings))
117         self.assertEquals('foo-fip', settings.floating_ip_settings[0].name)
118         self.assertEquals('bar-port', settings.floating_ip_settings[0].port_name)
119         self.assertEquals('foo-bar-router', settings.floating_ip_settings[0].router_name)
120         self.assertEquals('joe', settings.sudo_user)
121         self.assertEquals(999, settings.vm_boot_timeout)
122         self.assertEquals(333, settings.vm_delete_timeout)
123         self.assertEquals(111, settings.ssh_connect_timeout)
124         self.assertEquals('server name', settings.availability_zone)
125
126     def test_config_all(self):
127         port_settings = PortSettings(name='foo-port', network_name='bar-net')
128         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router')
129
130         settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings],
131                                               'security_group_names': ['sec_grp_1'],
132                                               'floating_ips': [fip_settings], 'sudo_user': 'joe',
133                                               'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
134                                               'ssh_connect_timeout': 111, 'availability_zone': 'server name'})
135         self.assertEquals('foo', settings.name)
136         self.assertEquals('bar', settings.flavor)
137         self.assertEquals(1, len(settings.port_settings))
138         self.assertEquals('foo-port', settings.port_settings[0].name)
139         self.assertEquals('bar-net', settings.port_settings[0].network_name)
140         self.assertEquals(1, len(settings.security_group_names))
141         self.assertEquals(1, len(settings.floating_ip_settings))
142         self.assertEquals('foo-fip', settings.floating_ip_settings[0].name)
143         self.assertEquals('bar-port', settings.floating_ip_settings[0].port_name)
144         self.assertEquals('foo-bar-router', settings.floating_ip_settings[0].router_name)
145         self.assertEquals('joe', settings.sudo_user)
146         self.assertEquals(999, settings.vm_boot_timeout)
147         self.assertEquals(333, settings.vm_delete_timeout)
148         self.assertEquals(111, settings.ssh_connect_timeout)
149         self.assertEquals('server name', settings.availability_zone)
150
151
152 class FloatingIpSettingsUnitTests(unittest.TestCase):
153     """
154     Tests the construction of the FloatingIpSettings class
155     """
156
157     def test_no_params(self):
158         with self.assertRaises(Exception):
159             FloatingIpSettings()
160
161     def test_empty_config(self):
162         with self.assertRaises(Exception):
163             FloatingIpSettings(config=dict())
164
165     def test_name_only(self):
166         with self.assertRaises(Exception):
167             FloatingIpSettings(name='foo')
168
169     def test_config_with_name_only(self):
170         with self.assertRaises(Exception):
171             FloatingIpSettings(config={'name': 'foo'})
172
173     def test_name_port_only(self):
174         with self.assertRaises(Exception):
175             FloatingIpSettings(name='foo', port_name='bar')
176
177     def test_config_with_name_port_only(self):
178         with self.assertRaises(Exception):
179             FloatingIpSettings(config={'name': 'foo', 'port_name': 'bar'})
180
181     def test_name_router_only(self):
182         with self.assertRaises(Exception):
183             FloatingIpSettings(name='foo', router_name='bar')
184
185     def test_config_with_name_router_only(self):
186         with self.assertRaises(Exception):
187             FloatingIpSettings(config={'name': 'foo', 'router_name': 'bar'})
188
189     def test_name_port_router_only(self):
190         settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router')
191         self.assertEquals('foo', settings.name)
192         self.assertEquals('foo-port', settings.port_name)
193         self.assertEquals('bar-router', settings.router_name)
194         self.assertIsNone(settings.subnet_name)
195         self.assertTrue(settings.provisioning)
196
197     def test_config_with_name_port_router_only(self):
198         settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router'})
199         self.assertEquals('foo', settings.name)
200         self.assertEquals('foo-port', settings.port_name)
201         self.assertEquals('bar-router', settings.router_name)
202         self.assertIsNone(settings.subnet_name)
203         self.assertTrue(settings.provisioning)
204
205     def test_all(self):
206         settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router',
207                                       subnet_name='bar-subnet', provisioning=False)
208         self.assertEquals('foo', settings.name)
209         self.assertEquals('foo-port', settings.port_name)
210         self.assertEquals('bar-router', settings.router_name)
211         self.assertEquals('bar-subnet', settings.subnet_name)
212         self.assertFalse(settings.provisioning)
213
214     def test_config_all(self):
215         settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router',
216                                               'subnet_name': 'bar-subnet', 'provisioning': False})
217         self.assertEquals('foo', settings.name)
218         self.assertEquals('foo-port', settings.port_name)
219         self.assertEquals('bar-router', settings.router_name)
220         self.assertEquals('bar-subnet', settings.subnet_name)
221         self.assertFalse(settings.provisioning)
222
223
224 class SimpleHealthCheck(OSIntegrationTestCase):
225     """
226     Test for the CreateInstance class with a single NIC/Port with Floating IPs
227     """
228
229     def setUp(self):
230         """
231         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
232         within OpenStack
233         """
234         super(self.__class__, self).__start__()
235
236         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
237         self.keypair_priv_filepath = 'tmp/' + guid
238         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
239         self.keypair_name = guid + '-kp'
240         self.vm_inst_name = guid + '-inst'
241         self.port_1_name = guid + 'port-1'
242         self.port_2_name = guid + 'port-2'
243         self.floating_ip_name = guid + 'fip1'
244
245         # Initialize for tearDown()
246         self.image_creators = list()
247         self.network_creator = None
248         self.flavor_creator = None
249         self.inst_creator = None
250
251         self.priv_net_config = openstack_tests.get_priv_net_config(
252             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
253         self.port_settings = PortSettings(
254             name=self.port_1_name, network_name=self.priv_net_config.network_settings.name)
255
256         # Create Image
257         # Set the default image settings, then set any custom parameters sent from the app
258         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
259
260         if self.image_metadata:
261             if self.image_metadata['disk_url']:
262                 self.os_image_settings.url = self.image_metadata['disk_url']
263             if self.image_metadata['extra_properties']:
264                 self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
265
266         try:
267             # If this is a 3-part image create the kernel and ramdisk images first
268             if self.image_metadata:
269                 if self.image_metadata['kernel_url']:
270                     kernel_image_settings = openstack_tests.cirros_url_image(
271                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
272                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
273                     kernel_image = self.image_creators[-1].create()
274                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
275
276                 if self.image_metadata['ramdisk_url']:
277                     ramdisk_image_settings = openstack_tests.cirros_url_image(
278                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
279                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
280                     ramdisk_image = self.image_creators[-1].create()
281                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
282
283             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
284             self.image_creators[-1].create()
285
286             # Create Network
287             self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)
288             self.network_creator.create()
289
290             # Create Flavor
291             self.flavor_creator = OpenStackFlavor(
292                 self.admin_os_creds,
293                 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=1, metadata=self.flavor_metadata))
294             self.flavor_creator.create()
295         except Exception as e:
296             self.tearDown()
297             raise e
298
299     def tearDown(self):
300         """
301         Cleans the created object
302         """
303         if self.inst_creator:
304             try:
305                 self.inst_creator.clean()
306             except Exception as e:
307                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
308
309         if os.path.isfile(self.keypair_pub_filepath):
310             os.remove(self.keypair_pub_filepath)
311
312         if os.path.isfile(self.keypair_priv_filepath):
313             os.remove(self.keypair_priv_filepath)
314
315         if self.flavor_creator:
316             try:
317                 self.flavor_creator.clean()
318             except Exception as e:
319                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
320
321         if self.image_creators:
322             try:
323                 while self.image_creators:
324                     self.image_creators[-1].clean()
325                     self.image_creators.pop()
326             except Exception as e:
327                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
328
329         super(self.__class__, self).__clean__()
330
331     def test_check_vm_ip_dhcp(self):
332         """
333         Tests the creation of an OpenStack instance with a single port and ensures that it's assigned IP address is
334         the actual.
335         """
336         instance_settings = VmInstanceSettings(
337             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
338
339         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
340         vm = self.inst_creator.create()
341
342         ip = self.inst_creator.get_port_ip(self.port_settings.name)
343         self.assertIsNotNone(ip)
344
345         self.assertTrue(self.inst_creator.vm_active(block=True))
346
347         found = False
348         timeout = 160
349         start_time = time.time()
350         match_value = 'Lease of.*obtained'
351
352         logger.info("Looking for expression %s in the console log" % match_value)
353         while timeout > time.time() - start_time:
354             output = vm.get_console_output()
355             if re.search(match_value, output):
356                 logger.info('DHCP lease obtained logged in console')
357                 if ip in output:
358                     logger.info('With correct IP address')
359                     found = True
360                 else:
361                     logger.error('With incorrect IP address')
362                 break
363
364         self.assertTrue(found)
365
366
367 class CreateInstanceSimpleTests(OSIntegrationTestCase):
368     """
369     Simple instance creation tests without any other objects
370     """
371     def setUp(self):
372         """
373         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
374         within OpenStack
375         """
376         super(self.__class__, self).__start__()
377
378         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
379         self.vm_inst_name = guid + '-inst'
380         self.nova = nova_utils.nova_client(self.os_creds)
381         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
382
383         net_config = openstack_tests.get_priv_net_config(
384             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
385             router_name=guid + '-pub-router', external_net=self.ext_net_name)
386
387         # Initialize for tearDown()
388         self.image_creators = list()
389         self.flavor_creator = None
390
391         self.net_creator = None
392         self.inst_creator = None
393
394         try:
395             # Create Image
396             # Set any custom parameters sent from the app
397             if self.image_metadata:
398                 if self.image_metadata['disk_url']:
399                     self.os_image_settings.url = self.image_metadata['disk_url']
400                 if self.image_metadata['extra_properties']:
401                     self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
402
403             # If this is a 3-part image create the kernel and ramdisk images first
404             if self.image_metadata:
405                 if self.image_metadata['kernel_url']:
406                     kernel_image_settings = openstack_tests.cirros_url_image(
407                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
408                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
409                     kernel_image = self.image_creators[-1].create()
410                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
411
412                 if self.image_metadata['ramdisk_url']:
413                     ramdisk_image_settings = openstack_tests.cirros_url_image(
414                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
415                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
416                     ramdisk_image = self.image_creators[-1].create()
417                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
418
419             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
420             self.image_creators[-1].create()
421
422             # Create Flavor
423             self.flavor_creator = OpenStackFlavor(
424                 self.admin_os_creds,
425                 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
426             self.flavor_creator.create()
427
428             # Create Network
429             self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
430             self.network_creator.create()
431
432             self.port_settings = PortSettings(name=guid + '-port',
433                                               network_name=net_config.network_settings.name)
434
435         except Exception as e:
436             self.tearDown()
437             raise e
438
439     def tearDown(self):
440         """
441         Cleans the created object
442         """
443         if self.inst_creator:
444             try:
445                 self.inst_creator.clean()
446             except Exception as e:
447                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
448
449         if self.flavor_creator:
450             try:
451                 self.flavor_creator.clean()
452             except Exception as e:
453                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
454
455         if self.net_creator:
456             try:
457                 self.net_creator.clean()
458             except Exception as e:
459                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
460
461         if self.image_creators:
462             try:
463                 while self.image_creators:
464                     self.image_creators[-1].clean()
465                     self.image_creators.pop()
466             except Exception as e:
467                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
468
469         super(self.__class__, self).__clean__()
470
471     def test_create_delete_instance(self):
472         """
473         Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
474         """
475         instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
476                                                port_settings=[self.port_settings])
477
478         self.inst_creator = OpenStackVmInstance(
479             self.os_creds, instance_settings, self.image_creators[-1].image_settings)
480
481         vm_inst = self.inst_creator.create()
482         self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
483
484         # Delete instance
485         nova_utils.delete_vm_instance(self.nova, vm_inst)
486
487         self.assertTrue(self.inst_creator.vm_deleted(block=True))
488         self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
489
490         # Exception should not be thrown
491         self.inst_creator.clean()
492
493
494 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
495     """
496     Test for the CreateInstance class with a single NIC/Port with Floating IPs
497     """
498
499     def setUp(self):
500         """
501         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
502         within OpenStack
503         """
504         super(self.__class__, self).__start__()
505
506         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
507         self.keypair_priv_filepath = 'tmp/' + guid
508         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
509         self.keypair_name = guid + '-kp'
510         self.vm_inst_name = guid + '-inst'
511         self.port_1_name = guid + 'port-1'
512         self.port_2_name = guid + 'port-2'
513         self.floating_ip_name = guid + 'fip1'
514
515         # Initialize for tearDown()
516         self.image_creators = list()
517         self.network_creator = None
518         self.router_creator = None
519         self.flavor_creator = None
520         self.keypair_creator = None
521         self.inst_creators = list()
522
523         self.pub_net_config = openstack_tests.get_pub_net_config(
524             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
525             router_name=guid + '-pub-router', external_net=self.ext_net_name)
526         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
527
528         try:
529             # Create Image
530             # Set any custom parameters sent from the app
531             if self.image_metadata:
532                 if self.image_metadata['disk_url']:
533                     self.os_image_settings.url = self.image_metadata['disk_url']
534                 if self.image_metadata['extra_properties']:
535                     self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
536
537             # If this is a 3-part image create the kernel and ramdisk images first
538             if self.image_metadata:
539                 if self.image_metadata['kernel_url']:
540                     kernel_image_settings = openstack_tests.cirros_url_image(
541                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
542                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
543                     kernel_image = self.image_creators[-1].create()
544                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
545
546                 if self.image_metadata['ramdisk_url']:
547                     ramdisk_image_settings = openstack_tests.cirros_url_image(
548                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
549                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
550                     ramdisk_image = self.image_creators[-1].create()
551                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
552
553             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
554             self.image_creators[-1].create()
555
556             # Create Network
557             self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)
558             self.network_creator.create()
559
560             # Create Router
561             self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)
562             self.router_creator.create()
563
564             # Create Flavor
565             self.flavor_creator = OpenStackFlavor(
566                 self.admin_os_creds,
567                 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
568             self.flavor_creator.create()
569
570             self.keypair_creator = OpenStackKeypair(
571                 self.os_creds, KeypairSettings(
572                     name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
573                     private_filepath=self.keypair_priv_filepath))
574             self.keypair_creator.create()
575         except Exception as e:
576             self.tearDown()
577             raise e
578
579     def tearDown(self):
580         """
581         Cleans the created object
582         """
583         for inst_creator in self.inst_creators:
584             try:
585                 inst_creator.clean()
586             except Exception as e:
587                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
588
589         if self.keypair_creator:
590             try:
591                 self.keypair_creator.clean()
592             except Exception as e:
593                 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
594
595         if os.path.isfile(self.keypair_pub_filepath):
596             os.remove(self.keypair_pub_filepath)
597
598         if os.path.isfile(self.keypair_priv_filepath):
599             os.remove(self.keypair_priv_filepath)
600
601         if self.flavor_creator:
602             try:
603                 self.flavor_creator.clean()
604             except Exception as e:
605                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
606
607         if self.router_creator:
608             try:
609                 self.router_creator.clean()
610             except Exception as e:
611                 logger.error('Unexpected exception cleaning router with message - ' + e.message)
612
613         if self.network_creator:
614             try:
615                 self.network_creator.clean()
616             except Exception as e:
617                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
618
619         if self.image_creators:
620             try:
621                 while self.image_creators:
622                     self.image_creators[-1].clean()
623                     self.image_creators.pop()
624             except Exception as e:
625                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
626
627         super(self.__class__, self).__clean__()
628
629     def test_single_port_static(self):
630         """
631         Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP.
632         """
633         ip_1 = '10.55.1.100'
634
635         port_settings = PortSettings(
636             name=self.port_1_name, network_name=self.pub_net_config.network_settings.name,
637             ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}])
638
639         instance_settings = VmInstanceSettings(
640             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
641             floating_ip_settings=[FloatingIpSettings(
642                 name=self.floating_ip_name, port_name=self.port_1_name,
643                 router_name=self.pub_net_config.router_settings.name)])
644
645         inst_creator = OpenStackVmInstance(
646             self.os_creds, instance_settings, self.image_creators[-1].image_settings,
647             keypair_settings=self.keypair_creator.keypair_settings)
648         self.inst_creators.append(inst_creator)
649         vm_inst = inst_creator.create()
650
651         self.assertEquals(ip_1, inst_creator.get_port_ip(self.port_1_name))
652         self.assertTrue(inst_creator.vm_active(block=True))
653         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
654
655     def test_ssh_client_fip_before_active(self):
656         """
657         Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
658         """
659         port_settings = PortSettings(
660             name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
661
662         instance_settings = VmInstanceSettings(
663             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
664             floating_ip_settings=[FloatingIpSettings(
665                 name=self.floating_ip_name, port_name=self.port_1_name,
666                 router_name=self.pub_net_config.router_settings.name)])
667
668         inst_creator = OpenStackVmInstance(
669             self.os_creds, instance_settings, self.image_creators[-1].image_settings,
670             keypair_settings=self.keypair_creator.keypair_settings)
671         self.inst_creators.append(inst_creator)
672         vm_inst = inst_creator.create()
673         self.assertIsNotNone(vm_inst)
674
675         self.assertTrue(inst_creator.vm_active(block=True))
676         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
677
678         self.assertTrue(validate_ssh_client(inst_creator))
679
680     def test_ssh_client_fip_after_active(self):
681         """
682         Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active.
683         """
684         port_settings = PortSettings(
685             name=self.port_1_name, network_name=self.pub_net_config.network_settings.name)
686
687         instance_settings = VmInstanceSettings(
688             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings],
689             floating_ip_settings=[FloatingIpSettings(
690                 name=self.floating_ip_name, port_name=self.port_1_name,
691                 router_name=self.pub_net_config.router_settings.name)])
692
693         inst_creator = OpenStackVmInstance(
694             self.os_creds, instance_settings, self.image_creators[-1].image_settings,
695             keypair_settings=self.keypair_creator.keypair_settings)
696         self.inst_creators.append(inst_creator)
697
698         # block=True will force the create() method to block until the
699         vm_inst = inst_creator.create(block=True)
700         self.assertIsNotNone(vm_inst)
701
702         self.assertTrue(inst_creator.vm_active(block=True))
703         self.assertEquals(vm_inst, inst_creator.get_vm_inst())
704
705         self.assertTrue(validate_ssh_client(inst_creator))
706
707     # TODO - Determine how allowed_address_pairs is supposed to operate before continuing this test
708     # see http://docs.openstack.org/developer/dragonflow/specs/allowed_address_pairs.html for a functional description
709     # def test_allowed_address_port_access(self):
710     #     """
711     #     Tests to ensure that setting allowed_address_pairs on a port functions as designed
712     #     """
713     #     port_settings_1 = PortSettings(
714     #         name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
715     #
716     #     instance_settings_1 = VmInstanceSettings(
717     #         name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
718     #         floating_ip_settings=[FloatingIpSettings(
719     #             name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
720     #             router_name=self.pub_net_config.router_settings.name)])
721     #
722     #     inst_creator_1 = OpenStackVmInstance(
723     #         self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
724     #         keypair_settings=self.keypair_creator.keypair_settings)
725     #     self.inst_creators.append(inst_creator_1)
726     #
727     #     # block=True will force the create() method to block until the
728     #     vm_inst_1 = inst_creator_1.create(block=True)
729     #     self.assertIsNotNone(vm_inst_1)
730     #
731     #     port_settings_1 = PortSettings(
732     #         name=self.port_1_name + '-1', network_name=self.pub_net_config.network_settings.name)
733     #
734     #     instance_settings_1 = VmInstanceSettings(
735     #         name=self.vm_inst_name + '-1', flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings_1],
736     #         floating_ip_settings=[FloatingIpSettings(
737     #             name=self.floating_ip_name + '-1', port_name=port_settings_1.name,
738     #             router_name=self.pub_net_config.router_settings.name)])
739     #
740     #     inst_creator_1 = OpenStackVmInstance(
741     #         self.os_creds, instance_settings_1, self.image_creators[-1].image_settings,
742     #         keypair_settings=self.keypair_creator.keypair_settings)
743     #     self.inst_creators.append(inst_creator_1)
744     #     inst_creator_1.create(block=True)
745     #
746     #     ip = inst_creator_1.get_port_ip(port_settings_1.name,
747     #                                     subnet_name=self.pub_net_config.network_settings.subnet_settings[0].name)
748     #     self.assertIsNotNone(ip)
749     #     mac_addr = inst_creator_1.get_port_mac(port_settings_1.name)
750     #     self.assertIsNotNone(mac_addr)
751     #
752     #     allowed_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
753     #
754     #     # Create VM that can be accessed by vm_inst_1
755     #     port_settings_2 = PortSettings(
756     #         name=self.port_1_name + '-2', network_name=self.pub_net_config.network_settings.name,
757     #         allowed_address_pairs=allowed_address_pairs)
758     #
759     #     instance_settings_2 = VmInstanceSettings(
760     #         name=self.vm_inst_name + '-2', flavor=self.flavor_creator.flavor_settings.name,
761     #         port_settings=[port_settings_2])
762     #
763     #     inst_creator_2 = OpenStackVmInstance(
764     #         self.os_creds, instance_settings_2, self.image_creators[-1].image_settings)
765     #     self.inst_creators.append(inst_creator_2)
766     #     inst_creator_2.create(block=True)
767     #
768     #     # Create VM that cannot be accessed by vm_inst_1
769     #     ip = '10.55.0.101'
770     #     mac_addr = '0a:1b:2c:3d:4e:5f'
771     #     invalid_address_pairs = [{'ip_address': ip, 'mac_address': mac_addr}]
772     #
773     #     port_settings_3 = PortSettings(
774     #         name=self.port_1_name + '-3', network_name=self.pub_net_config.network_settings.name,
775     #         allowed_address_pairs=invalid_address_pairs)
776     #
777     #     instance_settings_3 = VmInstanceSettings(
778     #         name=self.vm_inst_name + '-3', flavor=self.flavor_creator.flavor_settings.name,
779     #         port_settings=[port_settings_3])
780     #
781     #     inst_creator_3 = OpenStackVmInstance(
782     #         self.os_creds, instance_settings_3, self.image_creators[-1].image_settings)
783     #     self.inst_creators.append(inst_creator_3)
784     #     inst_creator_3.create(block=True)
785     #
786     #     print 'foo'
787     # I expected that this feature would block/allow traffic from specific endpoints (VMs). In this case, I would expect
788     # inst_1 to be able to access inst_2 but not inst_3; however, they all can access each other.
789     # TODO - Add validation
790
791
792 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
793     """
794     Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set
795     """
796
797     def setUp(self):
798         """
799         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
800         within OpenStack
801         """
802         super(self.__class__, self).__start__()
803
804         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
805         self.vm_inst_name = guid + '-inst'
806         self.port_1_name = guid + 'port-1'
807         self.port_2_name = guid + 'port-2'
808         self.floating_ip_name = guid + 'fip1'
809
810         # Initialize for tearDown()
811         self.image_creators = list()
812         self.network_creator = None
813         self.flavor_creator = None
814         self.inst_creator = None
815
816         self.net_config = openstack_tests.get_priv_net_config(
817             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
818             router_name=guid + '-pub-router', external_net=self.ext_net_name)
819         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
820
821         try:
822             # Create Image
823             # Set any custom parameters sent from the app
824             if self.image_metadata:
825                 if self.image_metadata['disk_url']:
826                     self.os_image_settings.url = self.image_metadata['disk_url']
827                 if self.image_metadata['extra_properties']:
828                     self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
829
830             # If this is a 3-part image create the kernel and ramdisk images first
831             if self.image_metadata:
832                 if self.image_metadata['kernel_url']:
833                     kernel_image_settings = openstack_tests.cirros_url_image(
834                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
835                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
836                     kernel_image = self.image_creators[-1].create()
837                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
838
839                 if self.image_metadata['ramdisk_url']:
840                     ramdisk_image_settings = openstack_tests.cirros_url_image(
841                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
842                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
843                     ramdisk_image = self.image_creators[-1].create()
844                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
845
846             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
847             self.image_creators[-1].create()
848
849             # Create Network
850             self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings)
851             self.network_creator.create()
852
853             # Create Flavor
854             self.flavor_creator = OpenStackFlavor(
855                 self.admin_os_creds,
856                 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
857             self.flavor_creator.create()
858         except Exception as e:
859             self.tearDown()
860             raise e
861
862     def tearDown(self):
863         """
864         Cleans the created object
865         """
866         if self.inst_creator:
867             try:
868                 self.inst_creator.clean()
869             except Exception as e:
870                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
871
872         if self.flavor_creator:
873             try:
874                 self.flavor_creator.clean()
875             except Exception as e:
876                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
877
878         if self.network_creator:
879             try:
880                 self.network_creator.clean()
881             except Exception as e:
882                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
883
884         if self.image_creators:
885             try:
886                 while self.image_creators:
887                     self.image_creators[-1].clean()
888                     self.image_creators.pop()
889             except Exception as e:
890                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
891
892         super(self.__class__, self).__clean__()
893
894     def test_set_custom_valid_ip_one_subnet(self):
895         """
896         Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
897         """
898         ip = '10.55.0.101'
899         port_settings = PortSettings(
900             name=self.port_1_name, network_name=self.net_config.network_settings.name,
901             ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
902
903         instance_settings = VmInstanceSettings(
904             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
905
906         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
907         self.inst_creator.create()
908
909         self.assertEquals(ip, self.inst_creator.get_port_ip(
910             self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
911
912     def test_set_custom_invalid_ip_one_subnet(self):
913         """
914         Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet.
915         """
916         ip = '10.66.0.101'
917         port_settings = PortSettings(
918             name=self.port_1_name, network_name=self.net_config.network_settings.name,
919             ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
920
921         instance_settings = VmInstanceSettings(
922             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
923
924         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
925
926         with self.assertRaises(Exception):
927             self.inst_creator.create()
928
929     def test_set_custom_valid_mac(self):
930         """
931         Tests the creation of an OpenStack instance with a single port where the MAC address is assigned.
932         """
933         mac_addr = '0a:1b:2c:3d:4e:5f'
934         port_settings = PortSettings(
935             name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr)
936
937         instance_settings = VmInstanceSettings(
938             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
939
940         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
941         self.inst_creator.create()
942
943         self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
944
945     def test_set_custom_invalid_mac(self):
946         """
947         Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being
948         assigned. This should raise an Exception
949         """
950         port_settings = PortSettings(
951             name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo')
952
953         instance_settings = VmInstanceSettings(
954             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
955
956         self.inst_creator = OpenStackVmInstance(
957             self.os_creds, instance_settings, self.image_creators[-1].image_settings)
958
959         with self.assertRaises(Exception):
960             self.inst_creator.create()
961
962     def test_set_custom_mac_and_ip(self):
963         """
964         Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned.
965         """
966         ip = '10.55.0.101'
967         mac_addr = '0a:1b:2c:3d:4e:5f'
968         port_settings = PortSettings(
969             name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr,
970             ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}])
971
972         instance_settings = VmInstanceSettings(
973             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
974
975         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
976         self.inst_creator.create()
977
978         self.assertEquals(ip, self.inst_creator.get_port_ip(
979             self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name))
980         self.assertEquals(mac_addr, self.inst_creator.get_port_mac(self.port_1_name))
981
982     def test_set_allowed_address_pairs(self):
983         """
984         Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set.
985         """
986         ip = '10.55.0.101'
987         mac_addr = '0a:1b:2c:3d:4e:5f'
988         pair = {'ip_address': ip, 'mac_address': mac_addr}
989         port_settings = PortSettings(
990             name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
991
992         instance_settings = VmInstanceSettings(
993             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
994
995         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
996         self.inst_creator.create()
997
998         port = self.inst_creator.get_port_by_name(port_settings.name)
999         self.assertIsNotNone(port)
1000         self.assertIsNotNone(port['port'].get('allowed_address_pairs'))
1001         self.assertEquals(1, len(port['port']['allowed_address_pairs']))
1002         validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0])
1003
1004     def test_set_allowed_address_pairs_bad_mac(self):
1005         """
1006         Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1007         invalid MAC address.
1008         """
1009         ip = '10.55.0.101'
1010         mac_addr = 'foo'
1011         pair = {'ip_address': ip, 'mac_address': mac_addr}
1012         pairs = set()
1013         pairs.add((ip, mac_addr))
1014         port_settings = PortSettings(
1015             name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1016
1017         instance_settings = VmInstanceSettings(
1018             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1019
1020         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1021         with self.assertRaises(Exception):
1022             self.inst_creator.create()
1023
1024     def test_set_allowed_address_pairs_bad_ip(self):
1025         """
1026         Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an
1027         invalid MAC address.
1028         """
1029         ip = 'foo'
1030         mac_addr = '0a:1b:2c:3d:4e:5f'
1031         pair = {'ip_address': ip, 'mac_address': mac_addr}
1032         pairs = set()
1033         pairs.add((ip, mac_addr))
1034         port_settings = PortSettings(
1035             name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair])
1036
1037         instance_settings = VmInstanceSettings(
1038             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings])
1039
1040         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1041         with self.assertRaises(Exception):
1042             self.inst_creator.create()
1043
1044
1045 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1046     """
1047     Test for the CreateInstance where one VM is deployed to each compute node
1048     """
1049
1050     def setUp(self):
1051         """
1052         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1053         within OpenStack
1054         """
1055         super(self.__class__, self).__start__()
1056
1057         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1058         self.vm_inst_name = guid + '-inst'
1059         self.port_base_name = guid + 'port'
1060
1061         # Initialize for tearDown()
1062         self.image_creators = list()
1063         self.flavor_creator = None
1064         self.network_creator = None
1065         self.inst_creators = list()
1066
1067         self.priv_net_config = openstack_tests.get_priv_net_config(
1068             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet')
1069
1070         self.os_image_settings = openstack_tests.cirros_url_image(name=guid + '-image')
1071
1072         try:
1073             # Create Network
1074             self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings)
1075             self.network_creator.create()
1076
1077             # Create Flavor
1078             self.flavor_creator = OpenStackFlavor(
1079                 self.admin_os_creds,
1080                 FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata))
1081             self.flavor_creator.create()
1082
1083             # Create Image
1084             # Set any custom parameters sent from the app
1085             if self.image_metadata:
1086                 if self.image_metadata['disk_url']:
1087                     self.os_image_settings.url = self.image_metadata['disk_url']
1088                 if self.image_metadata['extra_properties']:
1089                     self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1090
1091             # If this is a 3-part image create the kernel and ramdisk images first
1092             if self.image_metadata:
1093                 if self.image_metadata['kernel_url']:
1094                     kernel_image_settings = openstack_tests.cirros_url_image(
1095                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1096                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1097                     kernel_image = self.image_creators[-1].create()
1098                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1099
1100                 if self.image_metadata['ramdisk_url']:
1101                     ramdisk_image_settings = openstack_tests.cirros_url_image(
1102                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1103                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1104                     ramdisk_image = self.image_creators[-1].create()
1105                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1106
1107             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1108             self.image_creators[-1].create()
1109
1110         except Exception as e:
1111             self.tearDown()
1112             raise e
1113
1114     def tearDown(self):
1115         """
1116         Cleans the created object
1117         """
1118         for inst_creator in self.inst_creators:
1119             try:
1120                 inst_creator.clean()
1121             except Exception as e:
1122                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1123
1124         if self.flavor_creator:
1125             try:
1126                 self.flavor_creator.clean()
1127             except Exception as e:
1128                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1129
1130         if self.network_creator:
1131             try:
1132                 self.network_creator.clean()
1133             except Exception as e:
1134                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1135
1136         if self.image_creators:
1137             try:
1138                 while self.image_creators:
1139                     self.image_creators[-1].clean()
1140                     self.image_creators.pop()
1141             except Exception as e:
1142                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1143
1144         super(self.__class__, self).__clean__()
1145
1146     def test_deploy_vm_to_each_compute_node(self):
1147         """
1148         Tests the creation of OpenStack VM instances to each compute node.
1149         """
1150         from snaps.openstack.utils import nova_utils
1151         nova = nova_utils.nova_client(self.admin_os_creds)
1152         zones = nova_utils.get_nova_availability_zones(nova)
1153
1154         # Create Instance on each server/zone
1155         ctr = 0
1156         for zone in zones:
1157             inst_name = self.vm_inst_name + '-' + zone
1158             ctr += 1
1159             port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr),
1160                                          network_name=self.priv_net_config.network_settings.name)
1161
1162             instance_settings = VmInstanceSettings(
1163                 name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone,
1164                 port_settings=[port_settings])
1165             inst_creator = OpenStackVmInstance(
1166                 self.admin_os_creds, instance_settings, self.image_creators[-1].image_settings)
1167             self.inst_creators.append(inst_creator)
1168             inst_creator.create()
1169
1170         # Validate instances to ensure they've been deployed to the correct server
1171         index = 0
1172         for zone in zones:
1173             creator = self.inst_creators[index]
1174             self.assertTrue(creator.vm_active(block=True))
1175             vm = creator.get_vm_inst()
1176             deployed_zone = vm._info['OS-EXT-AZ:availability_zone']
1177             deployed_host = vm._info['OS-EXT-SRV-ATTR:host']
1178             self.assertEquals(zone, deployed_zone + ':' + deployed_host)
1179             index += 1
1180
1181
1182 class CreateInstancePubPrivNetTests(OSIntegrationTestCase):
1183     """
1184     Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o
1185     These tests require a Centos image
1186     """
1187
1188     def setUp(self):
1189         """
1190         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1191         within OpenStack
1192         """
1193         super(self.__class__, self).__start__()
1194
1195         # Initialize for tearDown()
1196         self.image_creators = list()
1197         self.network_creators = list()
1198         self.router_creators = list()
1199         self.flavor_creator = None
1200         self.keypair_creator = None
1201         self.inst_creator = None
1202
1203         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1204         self.keypair_priv_filepath = 'tmp/' + self.guid
1205         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1206         self.keypair_name = self.guid + '-kp'
1207         self.vm_inst_name = self.guid + '-inst'
1208         self.port_1_name = self.guid + '-port-1'
1209         self.port_2_name = self.guid + '-port-2'
1210         self.floating_ip_name = self.guid + 'fip1'
1211         self.priv_net_config = openstack_tests.get_priv_net_config(
1212             net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet',
1213             router_name=self.guid + '-priv-router', external_net=self.ext_net_name)
1214         self.pub_net_config = openstack_tests.get_pub_net_config(
1215             net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1216             router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1217         image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
1218         self.os_image_settings = openstack_tests.centos_url_image(name=image_name)
1219
1220         try:
1221             # Create Image
1222             # Set any custom parameters sent from the app
1223             if self.image_metadata:
1224                 if self.image_metadata['disk_url']:
1225                     self.os_image_settings.url = self.image_metadata['disk_url']
1226                 if self.image_metadata['extra_properties']:
1227                     self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1228
1229             # If this is a 3-part image create the kernel and ramdisk images first
1230             if self.image_metadata:
1231                 if self.image_metadata['kernel_url']:
1232                     kernel_image_settings = openstack_tests.cirros_url_image(
1233                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1234                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1235                     kernel_image = self.image_creators[-1].create()
1236                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1237
1238                 if self.image_metadata['ramdisk_url']:
1239                     ramdisk_image_settings = openstack_tests.cirros_url_image(
1240                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1241                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1242                     ramdisk_image = self.image_creators[-1].create()
1243                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1244
1245             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1246             self.image_creators[-1].create()
1247
1248             # First network is public
1249             self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings))
1250             # Second network is private
1251             self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings))
1252             for network_creator in self.network_creators:
1253                 network_creator.create()
1254
1255             self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings))
1256             self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings))
1257
1258             # Create Routers
1259             for router_creator in self.router_creators:
1260                 router_creator.create()
1261
1262             # Create Flavor
1263             self.flavor_creator = OpenStackFlavor(
1264                 self.admin_os_creds,
1265                 FlavorSettings(name=self.guid + '-flavor-name', ram=512, disk=10, vcpus=2,
1266                                metadata=self.flavor_metadata))
1267             self.flavor_creator.create()
1268
1269             # Create Keypair
1270             self.keypair_creator = OpenStackKeypair(
1271                 self.os_creds, KeypairSettings(
1272                     name=self.keypair_name, public_filepath=self.keypair_pub_filepath,
1273                     private_filepath=self.keypair_priv_filepath))
1274             self.keypair_creator.create()
1275         except Exception as e:
1276             self.tearDown()
1277             raise Exception(e.message)
1278
1279     def tearDown(self):
1280         """
1281         Cleans the created objects
1282         """
1283         if self.inst_creator:
1284             try:
1285                 self.inst_creator.clean()
1286             except Exception as e:
1287                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1288
1289         if self.keypair_creator:
1290             try:
1291                 self.keypair_creator.clean()
1292             except Exception as e:
1293                 logger.error('Unexpected exception cleaning keypair with message - ' + e.message)
1294
1295         if os.path.isfile(self.keypair_pub_filepath):
1296             os.remove(self.keypair_pub_filepath)
1297
1298         if os.path.isfile(self.keypair_priv_filepath):
1299             os.remove(self.keypair_priv_filepath)
1300
1301         if self.flavor_creator:
1302             try:
1303                 self.flavor_creator.clean()
1304             except Exception as e:
1305                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1306
1307         for router_creator in self.router_creators:
1308             try:
1309                 router_creator.clean()
1310             except Exception as e:
1311                 logger.error('Unexpected exception cleaning router with message - ' + e.message)
1312
1313         for network_creator in self.network_creators:
1314             try:
1315                 network_creator.clean()
1316             except Exception as e:
1317                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1318
1319         if self.image_creators:
1320             try:
1321                 while self.image_creators:
1322                     self.image_creators[-1].clean()
1323                     self.image_creators.pop()
1324             except Exception as e:
1325                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1326
1327         super(self.__class__, self).__clean__()
1328
1329     def test_dual_ports_dhcp(self):
1330         """
1331         Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP.
1332         NOTE: This test and any others that call ansible will most likely fail unless you do one of
1333         two things:
1334         1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False
1335         2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False
1336         Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail.
1337         """
1338         # Create ports/NICs for instance
1339         ports_settings = []
1340         ctr = 1
1341         for network_creator in self.network_creators:
1342             ports_settings.append(PortSettings(
1343                 name=self.guid + '-port-' + str(ctr),
1344                 network_name=network_creator.network_settings.name))
1345             ctr += 1
1346
1347         # Create instance
1348         instance_settings = VmInstanceSettings(
1349             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings,
1350             floating_ip_settings=[FloatingIpSettings(
1351                 name=self.floating_ip_name, port_name=self.port_1_name,
1352                 router_name=self.pub_net_config.router_settings.name)])
1353
1354         self.inst_creator = OpenStackVmInstance(
1355             self.os_creds, instance_settings, self.image_creators[-1].image_settings,
1356             keypair_settings=self.keypair_creator.keypair_settings)
1357
1358         vm_inst = self.inst_creator.create(block=True)
1359
1360         self.assertEquals(vm_inst, self.inst_creator.get_vm_inst())
1361
1362         # Effectively blocks until VM has been properly activated
1363         self.assertTrue(self.inst_creator.vm_active(block=True))
1364
1365         # Effectively blocks until VM's ssh port has been opened
1366         self.assertTrue(self.inst_creator.vm_ssh_active(block=True))
1367
1368         self.inst_creator.config_nics()
1369
1370         # TODO - *** ADD VALIDATION HERE ***
1371         # TODO - Add validation that both floating IPs work
1372         # TODO - Add tests where only one NIC has a floating IP
1373         # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway
1374
1375
1376 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1377     """
1378     Tests that include, add, and remove security groups from VM instances
1379     """
1380     def setUp(self):
1381         """
1382         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1383         within OpenStack
1384         """
1385         super(self.__class__, self).__start__()
1386
1387         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1388         self.vm_inst_name = self.guid + '-inst'
1389         self.nova = nova_utils.nova_client(self.os_creds)
1390         self.os_image_settings = openstack_tests.cirros_url_image(name=self.guid + '-image')
1391
1392         self.vm_inst_name = self.guid + '-inst'
1393         self.port_1_name = self.guid + 'port-1'
1394         self.port_2_name = self.guid + 'port-2'
1395         self.floating_ip_name = self.guid + 'fip1'
1396
1397         net_config = openstack_tests.get_priv_net_config(
1398             net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet',
1399             router_name=self.guid + '-pub-router', external_net=self.ext_net_name)
1400
1401         # Initialize for tearDown()
1402         self.image_creators = list()
1403         self.flavor_creator = None
1404         self.network_creator = None
1405         self.router_creator = None
1406         self.inst_creator = None
1407         self.sec_grp_creators = list()
1408
1409         try:
1410             # Create Image
1411             # Set any custom parameters sent from the app
1412             if self.image_metadata:
1413                 if self.image_metadata['disk_url']:
1414                     self.os_image_settings.url = self.image_metadata['disk_url']
1415                 if self.image_metadata['extra_properties']:
1416                     self.os_image_settings.extra_properties = self.image_metadata['extra_properties']
1417
1418             # If this is a 3-part image create the kernel and ramdisk images first
1419             if self.image_metadata:
1420                 if self.image_metadata['kernel_url']:
1421                     kernel_image_settings = openstack_tests.cirros_url_image(
1422                         name=self.os_image_settings.name+'_kernel', url=self.image_metadata['kernel_url'])
1423                     self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1424                     kernel_image = self.image_creators[-1].create()
1425                     self.os_image_settings.extra_properties['kernel_id'] = kernel_image.id
1426
1427                 if self.image_metadata['ramdisk_url']:
1428                     ramdisk_image_settings = openstack_tests.cirros_url_image(
1429                         name=self.os_image_settings.name+'_ramdisk', url=self.image_metadata['ramdisk_url'])
1430                     self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1431                     ramdisk_image = self.image_creators[-1].create()
1432                     self.os_image_settings.extra_properties['ramdisk_id'] = ramdisk_image.id
1433
1434             self.image_creators.append(OpenStackImage(self.os_creds, self.os_image_settings))
1435             self.image_creators[-1].create()
1436
1437             # Create Network
1438             self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1439             self.network_creator.create()
1440
1441             # Create Flavor
1442             self.flavor_creator = OpenStackFlavor(
1443                 self.admin_os_creds,
1444                 FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=2,
1445                                metadata=self.flavor_metadata))
1446             self.flavor_creator.create()
1447
1448             self.port_settings = PortSettings(name=self.guid + '-port',
1449                                               network_name=net_config.network_settings.name)
1450         except Exception as e:
1451             self.tearDown()
1452             raise e
1453
1454     def tearDown(self):
1455         """
1456         Cleans the created object
1457         """
1458         if self.inst_creator:
1459             try:
1460                 self.inst_creator.clean()
1461             except Exception as e:
1462                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1463
1464         for sec_grp_creator in self.sec_grp_creators:
1465             try:
1466                 sec_grp_creator.clean()
1467             except Exception as e:
1468                 logger.error('Unexpected exception cleaning security group with message - ' + e.message)
1469
1470         if self.flavor_creator:
1471             try:
1472                 self.flavor_creator.clean()
1473             except Exception as e:
1474                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1475
1476         if self.network_creator:
1477             try:
1478                 self.network_creator.clean()
1479             except Exception as e:
1480                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1481
1482         if self.image_creators:
1483             try:
1484                 while self.image_creators:
1485                     self.image_creators[-1].clean()
1486                     self.image_creators.pop()
1487             except Exception as e:
1488                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1489
1490         super(self.__class__, self).__clean__()
1491
1492     def test_add_security_group(self):
1493         """
1494         Tests the addition of a security group created after the instance.
1495         """
1496         # Create instance
1497         instance_settings = VmInstanceSettings(
1498             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1499         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1500         vm_inst = self.inst_creator.create(block=True)
1501         self.assertIsNotNone(vm_inst)
1502
1503         # Create security group object to add to instance
1504         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1505         sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1506         sec_grp = sec_grp_creator.create()
1507         self.sec_grp_creators.append(sec_grp_creator)
1508
1509         # Check that group has not been added
1510         self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1511
1512         # Add security group to instance after activated
1513         self.inst_creator.add_security_group(sec_grp)
1514
1515         # Validate that security group has been added
1516         self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1517
1518     def test_add_invalid_security_group(self):
1519         """
1520         Tests the addition of a security group that no longer exists.
1521         """
1522         # Create instance
1523         instance_settings = VmInstanceSettings(
1524             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1525         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1526         vm_inst = self.inst_creator.create(block=True)
1527         self.assertIsNotNone(vm_inst)
1528
1529         # Create security group object to add to instance
1530         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1531         sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1532         sec_grp = sec_grp_creator.create()
1533         sec_grp_creator.clean()
1534         self.sec_grp_creators.append(sec_grp_creator)
1535
1536         # Check that group has not been added
1537         self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1538
1539         # Add security group to instance after activated
1540         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1541
1542         # Validate that security group has been added
1543         self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1544
1545     def test_remove_security_group(self):
1546         """
1547         Tests the removal of a security group created before and added to the instance.
1548         """
1549         # Create security group object to add to instance
1550         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1551         sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1552         sec_grp = sec_grp_creator.create()
1553         self.sec_grp_creators.append(sec_grp_creator)
1554
1555         # Create instance
1556         instance_settings = VmInstanceSettings(
1557             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1558             security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1559         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1560         vm_inst = self.inst_creator.create(block=True)
1561         self.assertIsNotNone(vm_inst)
1562
1563         # Check that group has been added
1564         self.assertTrue(inst_has_sec_grp(vm_inst, sec_grp_settings.name))
1565
1566         # Add security group to instance after activated
1567         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1568
1569         # Validate that security group has been added
1570         self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1571
1572     def test_remove_security_group_never_added(self):
1573         """
1574         Tests the removal of a security group that was never added in the first place.
1575         """
1576         # Create security group object to add to instance
1577         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1578         sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1579         sec_grp = sec_grp_creator.create()
1580         self.sec_grp_creators.append(sec_grp_creator)
1581
1582         # Create instance
1583         instance_settings = VmInstanceSettings(
1584             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings])
1585         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1586         vm_inst = self.inst_creator.create(block=True)
1587         self.assertIsNotNone(vm_inst)
1588
1589         # Check that group has been added
1590         self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1591
1592         # Add security group to instance after activated
1593         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
1594
1595         # Validate that security group has been added
1596         self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1597
1598     def test_add_same_security_group(self):
1599         """
1600         Tests the addition of a security group created before add added to the instance.
1601         """
1602         # Create security group object to add to instance
1603         sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group')
1604         sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings)
1605         sec_grp = sec_grp_creator.create()
1606         self.sec_grp_creators.append(sec_grp_creator)
1607
1608         # Create instance
1609         instance_settings = VmInstanceSettings(
1610             name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1611             security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings])
1612         self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creators[-1].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(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1618
1619         # Add security group to instance after activated
1620         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
1621
1622         # Validate that security group has been added
1623         self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1624
1625
1626 def inst_has_sec_grp(vm_inst, sec_grp_name):
1627     """
1628     Returns true if instance has a security group of a given name
1629     :return:
1630     """
1631     if not hasattr(vm_inst, 'security_groups'):
1632         return False
1633
1634     found = False
1635     for sec_grp_dict in vm_inst.security_groups:
1636         if sec_grp_name in sec_grp_dict['name']:
1637             found = True
1638             break
1639     return found
1640
1641
1642 def validate_ssh_client(instance_creator):
1643     """
1644     Returns True if instance_creator returns an SSH client that is valid
1645     :param instance_creator: the object responsible for creating the VM instance
1646     :return: T/F
1647     """
1648     ssh_active = instance_creator.vm_ssh_active(block=True)
1649
1650     if ssh_active:
1651         ssh_client = instance_creator.ssh_client()
1652         if ssh_client:
1653             out = ssh_client.exec_command('pwd')[1]
1654         else:
1655             return False
1656
1657         channel = out.channel
1658         in_buffer = channel.in_buffer
1659         pwd_out = in_buffer.read(1024)
1660         if not pwd_out or len(pwd_out) < 10:
1661             return False
1662         return True
1663
1664     return False
1665
1666
1667 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
1668     """
1669     Test for the CreateInstance class for creating an image from a 3-part image
1670     """
1671
1672     def setUp(self):
1673         """
1674         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
1675         within OpenStack
1676         """
1677         super(self.__class__, self).__start__()
1678
1679         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1680         self.image_name = guid
1681         self.vm_inst_name = guid + '-inst'
1682         self.nova = nova_utils.nova_client(self.os_creds)
1683
1684         net_config = openstack_tests.get_priv_net_config(
1685             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1686             router_name=guid + '-pub-router', external_net=self.ext_net_name)
1687
1688         # Initialize for tearDown()
1689         self.image_creators = list()
1690         self.network_creator = None
1691         self.flavor_creator = None
1692         self.inst_creator = None
1693
1694         try:
1695             # Create Images
1696             # Set properties
1697             properties = {}
1698             if self.image_metadata and  self.image_metadata['extra_properties']:
1699                 properties = self.image_metadata['extra_properties']
1700
1701             # Create the kernel image
1702             kernel_image_settings = openstack_tests.cirros_url_image(
1703                 name=self.image_name+'_kernel',
1704                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel')
1705             if self.image_metadata and self.image_metadata['kernel_url']:
1706                 kernel_url = self.image_metadata['kernel_url']
1707             self.image_creators.append(OpenStackImage(self.os_creds, kernel_image_settings))
1708             kernel_image = self.image_creators[-1].create()
1709
1710             # Create the ramdisk image
1711             ramdisk_image_settings = openstack_tests.cirros_url_image(
1712                 name=self.image_name+'_ramdisk',
1713                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs')
1714             if self.image_metadata and self.image_metadata['ramdisk_url']:
1715                 ramdisk_url = self.image_metadata['ramdisk_url']
1716             self.image_creators.append(OpenStackImage(self.os_creds, ramdisk_image_settings))
1717             ramdisk_image = self.image_creators[-1].create()
1718             self.assertIsNotNone(ramdisk_image)
1719
1720             # Create the main image
1721             os_image_settings = openstack_tests.cirros_url_image(
1722                 name=self.image_name,
1723                 url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img')
1724             if self.image_metadata and self.image_metadata['disk_url']:
1725                 umage_url = self.image_metadata['disk_url']
1726             properties['kernel_id'] = kernel_image.id
1727             properties['ramdisk_id'] = ramdisk_image.id
1728             os_image_settings.extra_properties = properties
1729             self.image_creators.append(OpenStackImage(self.os_creds, os_image_settings))
1730             created_image = self.image_creators[-1].create()
1731             self.assertIsNotNone(created_image)
1732
1733             # Create Flavor
1734             self.flavor_creator = OpenStackFlavor(
1735                 self.admin_os_creds,
1736                 FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata))
1737             self.flavor_creator.create()
1738
1739             # Create Network
1740             self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings)
1741             self.network_creator.create()
1742
1743             self.port_settings = PortSettings(name=guid + '-port',
1744                                               network_name=net_config.network_settings.name)
1745         except Exception as e:
1746             self.tearDown()
1747             raise e
1748
1749     def tearDown(self):
1750         """
1751         Cleans the created object
1752         """
1753         if self.inst_creator:
1754             try:
1755                 self.inst_creator.clean()
1756             except Exception as e:
1757                 logger.error('Unexpected exception cleaning VM instance with message - ' + e.message)
1758
1759         if self.flavor_creator:
1760             try:
1761                 self.flavor_creator.clean()
1762             except Exception as e:
1763                 logger.error('Unexpected exception cleaning flavor with message - ' + e.message)
1764
1765         if self.network_creator:
1766             try:
1767                 self.network_creator.clean()
1768             except Exception as e:
1769                 logger.error('Unexpected exception cleaning network with message - ' + e.message)
1770
1771         if self.image_creators:
1772             try:
1773                 while self.image_creators:
1774                     self.image_creators[0].clean()
1775                     self.image_creators.pop(0)
1776             except Exception as e:
1777                 logger.error('Unexpected exception cleaning image with message - ' + e.message)
1778
1779         super(self.__class__, self).__clean__()
1780
1781     def test_create_delete_instance_from_three_part_image(self):
1782         """
1783         Tests the creation of an OpenStack instance from a 3-part image.
1784         """
1785         instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name,
1786                                                port_settings=[self.port_settings])
1787
1788         # The last created image is the main image from which we create the instance
1789         self.inst_creator = OpenStackVmInstance(
1790             self.os_creds, instance_settings, self.image_creators[-1].image_settings)
1791
1792         vm_inst = self.inst_creator.create()
1793         self.assertEquals(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1794
1795         # Delete instance
1796         nova_utils.delete_vm_instance(self.nova, vm_inst)
1797
1798         self.assertTrue(self.inst_creator.vm_deleted(block=True))
1799         self.assertEquals(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name)))
1800
1801         # Exception should not be thrown
1802         self.inst_creator.clean()