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