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