8ff98fc9524f658692c4d78f1990dc359439a1a7
[snaps.git] / snaps / openstack / tests / create_instance_tests.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 import logging
16 import re
17 import shutil
18 import time
19 import unittest
20 import uuid
21
22 import os
23 from neutronclient.common.exceptions import (
24     InvalidIpForSubnetClient, BadRequest)
25
26 from snaps import file_utils
27 from snaps.config.flavor import FlavorConfig
28 from snaps.config.image import ImageConfig
29 from snaps.config.keypair import KeypairConfig
30 from snaps.config.network import PortConfig, NetworkConfig, SubnetConfig
31 from snaps.config.router import RouterConfig
32 from snaps.config.security_group import (
33     Protocol, SecurityGroupRuleConfig, Direction, SecurityGroupConfig)
34 from snaps.config.vm_inst import (
35     VmInstanceConfig, FloatingIpConfig,  VmInstanceConfigError,
36     FloatingIpConfigError)
37 from snaps.config.volume import VolumeConfig
38 from snaps.openstack import create_network, create_router, create_instance
39 from snaps.openstack.create_flavor import OpenStackFlavor
40 from snaps.openstack.create_image import OpenStackImage
41 from snaps.openstack.create_instance import (
42     VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings)
43 from snaps.openstack.create_keypairs import OpenStackKeypair
44 from snaps.openstack.create_network import OpenStackNetwork
45 from snaps.openstack.create_router import OpenStackRouter
46 from snaps.openstack.create_security_group import OpenStackSecurityGroup
47 from snaps.openstack.create_volume import OpenStackVolume
48 from snaps.openstack.tests import openstack_tests, validation_utils
49 from snaps.openstack.tests.os_source_file_test import (
50     OSIntegrationTestCase, OSComponentTestCase)
51 from snaps.openstack.utils import nova_utils, keystone_utils, neutron_utils
52 from snaps.openstack.utils.nova_utils import RebootType
53 from snaps.openstack.utils import nova_utils, settings_utils, neutron_utils
54
55 __author__ = 'spisarski'
56
57 VM_BOOT_TIMEOUT = 600
58
59 logger = logging.getLogger('create_instance_tests')
60
61
62 class VmInstanceSettingsUnitTests(unittest.TestCase):
63     """
64     Tests the construction of the VmInstanceSettings class
65     """
66
67     def test_no_params(self):
68         with self.assertRaises(VmInstanceConfigError):
69             VmInstanceSettings()
70
71     def test_empty_config(self):
72         with self.assertRaises(VmInstanceConfigError):
73             VmInstanceSettings(config=dict())
74
75     def test_name_only(self):
76         with self.assertRaises(VmInstanceConfigError):
77             VmInstanceSettings(name='foo')
78
79     def test_config_with_name_only(self):
80         with self.assertRaises(VmInstanceConfigError):
81             VmInstanceSettings(config={'name': 'foo'})
82
83     def test_name_flavor_only(self):
84         with self.assertRaises(VmInstanceConfigError):
85             VmInstanceSettings(name='foo', flavor='bar')
86
87     def test_config_with_name_flavor_only(self):
88         with self.assertRaises(VmInstanceConfigError):
89             VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar'})
90
91     def test_name_flavor_port_only(self):
92         port_settings = PortConfig(name='foo-port', network_name='bar-net')
93         settings = VmInstanceSettings(name='foo', flavor='bar',
94                                       port_settings=[port_settings])
95         self.assertEqual('foo', settings.name)
96         self.assertEqual('bar', settings.flavor)
97         self.assertEqual(1, len(settings.port_settings))
98         self.assertEqual('foo-port', settings.port_settings[0].name)
99         self.assertEqual('bar-net', settings.port_settings[0].network_name)
100         self.assertEqual(0, len(settings.security_group_names))
101         self.assertEqual(0, len(settings.floating_ip_settings))
102         self.assertIsNone(settings.sudo_user)
103         self.assertEqual(900, settings.vm_boot_timeout)
104         self.assertEqual(300, settings.vm_delete_timeout)
105         self.assertEqual(180, settings.ssh_connect_timeout)
106         self.assertIsNone(settings.availability_zone)
107         self.assertIsNone(settings.volume_names)
108
109     def test_config_with_name_flavor_port_only(self):
110         port_settings = PortConfig(name='foo-port', network_name='bar-net')
111         settings = VmInstanceSettings(
112             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]})
113         self.assertEqual('foo', settings.name)
114         self.assertEqual('bar', settings.flavor)
115         self.assertEqual(1, len(settings.port_settings))
116         self.assertEqual('foo-port', settings.port_settings[0].name)
117         self.assertEqual('bar-net', settings.port_settings[0].network_name)
118         self.assertEqual(0, len(settings.security_group_names))
119         self.assertEqual(0, len(settings.floating_ip_settings))
120         self.assertIsNone(settings.sudo_user)
121         self.assertEqual(900, settings.vm_boot_timeout)
122         self.assertEqual(300, settings.vm_delete_timeout)
123         self.assertEqual(180, settings.ssh_connect_timeout)
124         self.assertIsNone(settings.availability_zone)
125         self.assertIsNone(settings.volume_names)
126
127     def test_all(self):
128         port_settings = PortConfig(name='foo-port', network_name='bar-net')
129         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
130                                           router_name='foo-bar-router')
131
132         settings = VmInstanceSettings(
133             name='foo', flavor='bar', port_settings=[port_settings],
134             security_group_names=['sec_grp_1'],
135             floating_ip_settings=[fip_settings], sudo_user='joe',
136             vm_boot_timeout=999, vm_delete_timeout=333,
137             ssh_connect_timeout=111, availability_zone='server name',
138             volume_names=['vol1'])
139         self.assertEqual('foo', settings.name)
140         self.assertEqual('bar', settings.flavor)
141         self.assertEqual(1, len(settings.port_settings))
142         self.assertEqual('foo-port', settings.port_settings[0].name)
143         self.assertEqual('bar-net', settings.port_settings[0].network_name)
144         self.assertEqual(1, len(settings.security_group_names))
145         self.assertEqual('sec_grp_1', settings.security_group_names[0])
146         self.assertEqual(1, len(settings.floating_ip_settings))
147         self.assertEqual('foo-fip', settings.floating_ip_settings[0].name)
148         self.assertEqual('bar-port',
149                          settings.floating_ip_settings[0].port_name)
150         self.assertEqual('foo-bar-router',
151                          settings.floating_ip_settings[0].router_name)
152         self.assertEqual('joe', settings.sudo_user)
153         self.assertEqual(999, settings.vm_boot_timeout)
154         self.assertEqual(333, settings.vm_delete_timeout)
155         self.assertEqual(111, settings.ssh_connect_timeout)
156         self.assertEqual('server name', settings.availability_zone)
157         self.assertEqual('vol1', settings.volume_names[0])
158
159     def test_config_all(self):
160         port_settings = PortConfig(name='foo-port', network_name='bar-net')
161         fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port',
162                                           router_name='foo-bar-router')
163
164         settings = VmInstanceSettings(
165             **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings],
166                'security_group_names': ['sec_grp_1'],
167                'floating_ips': [fip_settings], 'sudo_user': 'joe',
168                'vm_boot_timeout': 999, 'vm_delete_timeout': 333,
169                'ssh_connect_timeout': 111, 'availability_zone': 'server name',
170                'volume_names': ['vol2']})
171         self.assertEqual('foo', settings.name)
172         self.assertEqual('bar', settings.flavor)
173         self.assertEqual(1, len(settings.port_settings))
174         self.assertEqual('foo-port', settings.port_settings[0].name)
175         self.assertEqual('bar-net', settings.port_settings[0].network_name)
176         self.assertEqual(1, len(settings.security_group_names))
177         self.assertEqual(1, len(settings.floating_ip_settings))
178         self.assertEqual('foo-fip', settings.floating_ip_settings[0].name)
179         self.assertEqual('bar-port',
180                          settings.floating_ip_settings[0].port_name)
181         self.assertEqual('foo-bar-router',
182                          settings.floating_ip_settings[0].router_name)
183         self.assertEqual('joe', settings.sudo_user)
184         self.assertEqual(999, settings.vm_boot_timeout)
185         self.assertEqual(333, settings.vm_delete_timeout)
186         self.assertEqual(111, settings.ssh_connect_timeout)
187         self.assertEqual('server name', settings.availability_zone)
188         self.assertEqual('vol2', settings.volume_names[0])
189
190
191 class FloatingIpSettingsUnitTests(unittest.TestCase):
192     """
193     Tests the construction of the FloatingIpSettings class
194     """
195
196     def test_no_params(self):
197         with self.assertRaises(FloatingIpConfigError):
198             FloatingIpSettings()
199
200     def test_empty_config(self):
201         with self.assertRaises(FloatingIpConfigError):
202             FloatingIpSettings(**dict())
203
204     def test_name_only(self):
205         with self.assertRaises(FloatingIpConfigError):
206             FloatingIpSettings(name='foo')
207
208     def test_config_with_name_only(self):
209         with self.assertRaises(FloatingIpConfigError):
210             FloatingIpSettings(**{'name': 'foo'})
211
212     def test_name_port_only(self):
213         with self.assertRaises(FloatingIpConfigError):
214             FloatingIpSettings(name='foo', port_name='bar')
215
216     def test_config_with_name_port_only(self):
217         with self.assertRaises(FloatingIpConfigError):
218             FloatingIpSettings(**{'name': 'foo', 'port_name': 'bar'})
219
220     def test_name_router_only(self):
221         with self.assertRaises(FloatingIpConfigError):
222             FloatingIpSettings(name='foo', router_name='bar')
223
224     def test_config_with_name_router_only(self):
225         with self.assertRaises(FloatingIpConfigError):
226             FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'})
227
228     def test_name_port_router_name_only(self):
229         settings = FloatingIpSettings(name='foo', port_name='foo-port',
230                                       router_name='bar-router')
231         self.assertEqual('foo', settings.name)
232         self.assertEqual('foo-port', settings.port_name)
233         self.assertIsNone(settings.port_id)
234         self.assertEqual('bar-router', settings.router_name)
235         self.assertIsNone(settings.subnet_name)
236         self.assertTrue(settings.provisioning)
237
238     def test_name_port_router_id_only(self):
239         settings = FloatingIpSettings(name='foo', port_id='foo-port',
240                                       router_name='bar-router')
241         self.assertEqual('foo', settings.name)
242         self.assertEqual('foo-port', settings.port_id)
243         self.assertIsNone(settings.port_name)
244         self.assertEqual('bar-router', settings.router_name)
245         self.assertIsNone(settings.subnet_name)
246         self.assertTrue(settings.provisioning)
247
248     def test_config_with_name_port_router_only(self):
249         settings = FloatingIpSettings(
250             **{'name': 'foo', 'port_name': 'foo-port',
251                'router_name': 'bar-router'})
252         self.assertEqual('foo', settings.name)
253         self.assertEqual('foo-port', settings.port_name)
254         self.assertIsNone(settings.port_id)
255         self.assertEqual('bar-router', settings.router_name)
256         self.assertIsNone(settings.subnet_name)
257         self.assertTrue(settings.provisioning)
258
259     def test_all(self):
260         settings = FloatingIpSettings(name='foo', port_name='foo-port',
261                                       router_name='bar-router',
262                                       subnet_name='bar-subnet',
263                                       provisioning=False)
264         self.assertEqual('foo', settings.name)
265         self.assertEqual('foo-port', settings.port_name)
266         self.assertIsNone(settings.port_id)
267         self.assertEqual('bar-router', settings.router_name)
268         self.assertEqual('bar-subnet', settings.subnet_name)
269         self.assertFalse(settings.provisioning)
270
271     def test_config_all(self):
272         settings = FloatingIpSettings(
273             **{'name': 'foo', 'port_name': 'foo-port',
274                'router_name': 'bar-router', 'subnet_name': 'bar-subnet',
275                'provisioning': False})
276         self.assertEqual('foo', settings.name)
277         self.assertEqual('foo-port', settings.port_name)
278         self.assertIsNone(settings.port_id)
279         self.assertEqual('bar-router', settings.router_name)
280         self.assertEqual('bar-subnet', settings.subnet_name)
281         self.assertFalse(settings.provisioning)
282
283
284 class SimpleHealthCheck(OSIntegrationTestCase):
285     """
286     Test for the CreateInstance class with a single NIC/Port with Floating IPs
287     """
288
289     def setUp(self):
290         """
291         Instantiates the CreateImage object that is responsible for downloading
292         and creating an OS image file
293         within OpenStack
294         """
295         super(self.__class__, self).__start__()
296
297         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
298         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
299         self.vm_inst_name = guid + '-inst'
300         self.port_1_name = guid + 'port-1'
301
302         # Initialize for tearDown()
303         self.image_creator = None
304         self.network_creator = None
305         self.flavor_creator = None
306         self.inst_creator = None
307
308         self.priv_net_config = openstack_tests.get_priv_net_config(
309             net_name=guid + '-priv-net',
310             subnet_name=guid + '-priv-subnet',
311             netconf_override=self.netconf_override)
312         self.port_settings = PortConfig(
313             name=self.port_1_name,
314             network_name=self.priv_net_config.network_settings.name)
315
316         # Create Image
317         # Set the default image settings, then set any custom parameters sent
318         # from the app
319         os_image_settings = openstack_tests.cirros_image_settings(
320             name=guid + '-image', image_metadata=self.image_metadata)
321
322         try:
323             self.image_creator = OpenStackImage(self.os_creds,
324                                                 os_image_settings)
325             self.image_creator.create()
326
327             # Create Network
328             self.network_creator = OpenStackNetwork(
329                 self.os_creds, self.priv_net_config.network_settings)
330             self.network_creator.create()
331
332             # Create Flavor
333             self.flavor_ram = 256
334             if (self.flavor_metadata and
335                self.flavor_metadata.get('hw:mem_page_size') == 'large'):
336                 self.flavor_ram = 1024
337             self.flavor_creator = OpenStackFlavor(
338                 self.admin_os_creds,
339                 FlavorConfig(name=guid + '-flavor-name', ram=self.flavor_ram,
340                              disk=10, vcpus=1, metadata=self.flavor_metadata))
341             self.flavor_creator.create()
342         except Exception as e:
343             self.tearDown()
344             raise e
345
346     def tearDown(self):
347         """
348         Cleans the created object
349         """
350         if self.inst_creator:
351             try:
352                 self.inst_creator.clean()
353             except Exception as e:
354                 logger.error(
355                     'Unexpected exception cleaning VM instance with message'
356                     ' - %s', e)
357
358         if self.network_creator:
359             try:
360                 self.network_creator.clean()
361             except Exception as e:
362                 logger.error(
363                     'Unexpected exception cleaning network with message - %s',
364                     e)
365
366         if self.flavor_creator:
367             try:
368                 self.flavor_creator.clean()
369             except Exception as e:
370                 logger.error(
371                     'Unexpected exception cleaning flavor with message - %s',
372                     e)
373
374         if self.image_creator and not self.image_creator.image_settings.exists:
375             try:
376                 self.image_creator.clean()
377             except Exception as e:
378                 logger.error(
379                     'Unexpected exception cleaning image with message - %s',
380                     e)
381
382         super(self.__class__, self).__clean__()
383
384     def test_check_vm_ip_dhcp(self):
385         """
386         Tests the creation of an OpenStack instance with a single port and
387         ensures that it's assigned IP address is the actual.
388         """
389         instance_settings = VmInstanceConfig(
390             name=self.vm_inst_name,
391             flavor=self.flavor_creator.flavor_settings.name,
392             port_settings=[self.port_settings])
393
394         self.inst_creator = OpenStackVmInstance(
395             self.os_creds, instance_settings,
396             self.image_creator.image_settings)
397         self.inst_creator.create()
398
399         ip = self.inst_creator.get_port_ip(self.port_settings.name)
400         self.assertIsNotNone(ip)
401
402         self.assertTrue(self.inst_creator.vm_active(block=True))
403
404         self.assertTrue(check_dhcp_lease(self.inst_creator, ip))
405
406
407 class CreateInstanceSimpleTests(OSIntegrationTestCase):
408     """
409     Simple instance creation tests without any other objects
410     """
411
412     def setUp(self):
413         """
414         Setup the objects required for the test
415         """
416         super(self.__class__, self).__start__()
417
418         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
419         self.vm_inst_name = self.guid + '-inst'
420         self.nova = nova_utils.nova_client(self.os_creds)
421         self.neutron = neutron_utils.neutron_client(self.os_creds)
422         os_image_settings = openstack_tests.cirros_image_settings(
423             name=self.guid + '-image', image_metadata=self.image_metadata)
424
425         # Initialize for tearDown()
426         self.image_creator = None
427         self.flavor_creator = None
428
429         self.network_creator = None
430         self.inst_creator = None
431
432         try:
433             # Create Image
434             self.image_creator = OpenStackImage(self.os_creds,
435                                                 os_image_settings)
436             self.image_creator.create()
437
438             # Create Flavor
439             self.flavor_creator = OpenStackFlavor(
440                 self.admin_os_creds,
441                 FlavorConfig(name=self.guid + '-flavor-name', ram=256, disk=10,
442                              vcpus=2, metadata=self.flavor_metadata))
443             self.flavor_creator.create()
444             self.network_creator = None
445         except Exception as e:
446             self.tearDown()
447             raise e
448
449     def tearDown(self):
450         """
451         Cleans the created object
452         """
453         if self.inst_creator:
454             try:
455                 self.inst_creator.clean()
456             except Exception as e:
457                 logger.error(
458                     'Unexpected exception cleaning VM instance with message '
459                     '- %s', e)
460
461         if self.flavor_creator:
462             try:
463                 self.flavor_creator.clean()
464             except Exception as e:
465                 logger.error(
466                     'Unexpected exception cleaning flavor with message - %s',
467                     e)
468
469         if self.network_creator:
470             try:
471                 self.network_creator.clean()
472             except Exception as e:
473                 logger.error(
474                     'Unexpected exception cleaning network with message - %s',
475                     e)
476
477         if self.image_creator and not self.image_creator.image_settings.exists:
478             try:
479                 self.image_creator.clean()
480             except Exception as e:
481                 logger.error(
482                     'Unexpected exception cleaning image with message - %s', e)
483
484         super(self.__class__, self).__clean__()
485
486     def test_create_delete_instance(self):
487         """
488         Tests the creation of an OpenStack instance with a single port with a
489         static IP without a Floating IP.
490         """
491         # Create Network
492         net_config = openstack_tests.get_priv_net_config(
493             net_name=self.guid + '-pub-net',
494             subnet_name=self.guid + '-pub-subnet',
495             router_name=self.guid + '-pub-router',
496             external_net=self.ext_net_name,
497             netconf_override=self.netconf_override)
498         self.network_creator = OpenStackNetwork(
499             self.os_creds, net_config.network_settings)
500         self.network_creator.create()
501
502         self.port_settings = PortConfig(
503             name=self.guid + '-port',
504             network_name=net_config.network_settings.name)
505
506         instance_settings = VmInstanceConfig(
507             name=self.vm_inst_name,
508             flavor=self.flavor_creator.flavor_settings.name,
509             port_settings=[self.port_settings])
510
511         self.inst_creator = OpenStackVmInstance(
512             self.os_creds, instance_settings,
513             self.image_creator.image_settings)
514
515         vm_inst = self.inst_creator.create(block=True)
516         vm_inst_get = nova_utils.get_server(
517             self.nova, self.neutron, self.keystone,
518             vm_inst_settings=instance_settings)
519         self.assertEqual(vm_inst, vm_inst_get)
520
521         self.assertIsNotNone(self.inst_creator.get_vm_inst().availability_zone)
522         self.assertIsNone(self.inst_creator.get_vm_inst().compute_host)
523
524         # Delete instance
525         nova_utils.delete_vm_instance(self.nova, vm_inst)
526
527         self.assertTrue(self.inst_creator.vm_deleted(block=True))
528         self.assertIsNone(nova_utils.get_server(
529             self.nova, self.neutron, self.keystone,
530             vm_inst_settings=instance_settings))
531
532         # Exception should not be thrown
533         self.inst_creator.clean()
534
535     def test_create_admin_instance(self):
536         """
537         Tests the creation of an OpenStack instance with a single port with a
538         static IP without a Floating IP.
539         """
540         # Create Network
541         net_config = openstack_tests.get_priv_net_config(
542             net_name=self.guid + '-pub-net',
543             subnet_name=self.guid + '-pub-subnet',
544             router_name=self.guid + '-pub-router',
545             external_net=self.ext_net_name,
546             netconf_override=self.netconf_override)
547         self.network_creator = OpenStackNetwork(
548             self.admin_os_creds, net_config.network_settings)
549         self.network_creator.create()
550
551         self.port_settings = PortConfig(
552             name=self.guid + '-port',
553             network_name=net_config.network_settings.name)
554
555         instance_settings = VmInstanceConfig(
556             name=self.vm_inst_name,
557             flavor=self.flavor_creator.flavor_settings.name,
558             port_settings=[self.port_settings])
559
560         self.inst_creator = OpenStackVmInstance(
561             self.admin_os_creds, instance_settings,
562             self.image_creator.image_settings)
563
564         admin_nova = nova_utils.nova_client(self.admin_os_creds)
565         admin_neutron = neutron_utils.neutron_client(self.admin_os_creds)
566         admin_key = keystone_utils.keystone_client(self.admin_os_creds)
567         vm_inst = self.inst_creator.create(block=True)
568
569         self.assertIsNotNone(vm_inst)
570         vm_inst_get = nova_utils.get_server(
571             admin_nova, admin_neutron, admin_key,
572             vm_inst_settings=instance_settings)
573         self.assertEqual(vm_inst, vm_inst_get)
574
575         self.assertIsNone(nova_utils.get_server(
576             self.nova, self.neutron, self.keystone,
577             vm_inst_settings=instance_settings))
578
579         self.assertIsNotNone(self.inst_creator.get_vm_inst().availability_zone)
580         self.assertIsNotNone(self.inst_creator.get_vm_inst().compute_host)
581
582
583 class CreateInstanceExternalNetTests(OSIntegrationTestCase):
584     """
585     Simple instance creation tests where the network is external
586     """
587
588     def setUp(self):
589         """
590         Instantiates the CreateImage object that is responsible for downloading
591         and creating an OS image file
592         within OpenStack
593         """
594         super(self.__class__, self).__start__()
595
596         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
597         self.vm_inst_name = guid + '-inst'
598         self.nova = nova_utils.nova_client(self.admin_os_creds)
599         self.neutron = neutron_utils.neutron_client(self.admin_os_creds)
600         os_image_settings = openstack_tests.cirros_image_settings(
601             name=guid + '-image', image_metadata=self.image_metadata)
602
603         # Initialize for tearDown()
604         self.image_creator = None
605         self.flavor_creator = None
606         self.inst_creator = None
607
608         try:
609             # Create Image
610             self.image_creator = OpenStackImage(self.os_creds,
611                                                 os_image_settings)
612             self.image_creator.create()
613
614             # Create Flavor
615             self.flavor_creator = OpenStackFlavor(
616                 self.admin_os_creds,
617                 FlavorConfig(name=guid + '-flavor-name', ram=256, disk=10,
618                              vcpus=2, metadata=self.flavor_metadata))
619             self.flavor_creator.create()
620
621             self.port_settings = PortConfig(
622                 name=guid + '-port',
623                 network_name=self.ext_net_name)
624
625         except Exception as e:
626             self.tearDown()
627             raise e
628
629     def tearDown(self):
630         """
631         Cleans the created object
632         """
633         if self.inst_creator:
634             try:
635                 self.inst_creator.clean()
636             except Exception as e:
637                 logger.error(
638                     'Unexpected exception cleaning VM instance with message '
639                     '- %s', e)
640
641         if self.flavor_creator:
642             try:
643                 self.flavor_creator.clean()
644             except Exception as e:
645                 logger.error(
646                     'Unexpected exception cleaning flavor with message - %s',
647                     e)
648
649         if self.image_creator and not self.image_creator.image_settings.exists:
650             try:
651                 self.image_creator.clean()
652             except Exception as e:
653                 logger.error(
654                     'Unexpected exception cleaning image with message - %s', e)
655
656         super(self.__class__, self).__clean__()
657
658     def test_create_instance_public_net(self):
659         """
660         Tests the creation of an OpenStack instance with a single port to
661         the external network.
662         """
663         instance_settings = VmInstanceConfig(
664             name=self.vm_inst_name,
665             flavor=self.flavor_creator.flavor_settings.name,
666             port_settings=[self.port_settings])
667
668         self.inst_creator = OpenStackVmInstance(
669             self.admin_os_creds, instance_settings,
670             self.image_creator.image_settings)
671
672         vm_inst = self.inst_creator.create(block=True)
673         vm_inst_get = nova_utils.get_server(
674             self.nova, self.neutron, self.keystone,
675             vm_inst_settings=instance_settings)
676         self.assertEqual(vm_inst, vm_inst_get)
677         ip = self.inst_creator.get_port_ip(self.port_settings.name)
678
679         check_dhcp_lease(self.inst_creator, ip)
680
681
682 class CreateInstanceSingleNetworkTests(OSIntegrationTestCase):
683     """
684     Test for the CreateInstance class with a single NIC/Port with Floating IPs
685     """
686
687     def setUp(self):
688         """
689         Instantiates the CreateImage object that is responsible for downloading
690         and creating an OS image file within OpenStack
691         """
692         super(self.__class__, self).__start__()
693
694         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
695         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
696         self.keypair_priv_filepath = 'tmp/' + guid
697         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
698         self.keypair_name = guid + '-kp'
699         self.vm_inst_name = guid + '-inst'
700         self.port_1_name = guid + 'port-1'
701         self.port_2_name = guid + 'port-2'
702         self.floating_ip_name = guid + 'fip1'
703
704         # Initialize for tearDown()
705         self.image_creator = None
706         self.network_creator = None
707         self.router_creator = None
708         self.flavor_creator = None
709         self.keypair_creator = None
710         self.sec_grp_creator = None
711         self.inst_creators = list()
712
713         self.pub_net_config = openstack_tests.get_pub_net_config(
714             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
715             router_name=guid + '-pub-router', external_net=self.ext_net_name,
716             netconf_override=self.netconf_override)
717         os_image_settings = openstack_tests.cirros_image_settings(
718             name=guid + '-image', image_metadata=self.image_metadata)
719         try:
720             # Create Image
721             self.image_creator = OpenStackImage(self.os_creds,
722                                                 os_image_settings)
723             self.image_creator.create()
724
725             # Create Network
726             self.network_creator = OpenStackNetwork(
727                 self.os_creds, self.pub_net_config.network_settings)
728             self.network_creator.create()
729
730             # Create Router
731             self.router_creator = OpenStackRouter(
732                 self.os_creds, self.pub_net_config.router_settings)
733             self.router_creator.create()
734
735             # Create Flavor
736             self.flavor_creator = OpenStackFlavor(
737                 self.admin_os_creds,
738                 FlavorConfig(name=guid + '-flavor-name', ram=256, disk=10,
739                              vcpus=2, metadata=self.flavor_metadata))
740             self.flavor_creator.create()
741
742             self.keypair_creator = OpenStackKeypair(
743                 self.os_creds, KeypairConfig(
744                     name=self.keypair_name,
745                     public_filepath=self.keypair_pub_filepath,
746                     private_filepath=self.keypair_priv_filepath))
747             self.keypair_creator.create()
748
749             sec_grp_name = guid + '-sec-grp'
750             rule1 = SecurityGroupRuleConfig(
751                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
752                 protocol=Protocol.icmp)
753             rule2 = SecurityGroupRuleConfig(
754                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
755                 protocol=Protocol.tcp, port_range_min=22, port_range_max=22)
756             self.sec_grp_creator = OpenStackSecurityGroup(
757                 self.os_creds,
758                 SecurityGroupConfig(
759                     name=sec_grp_name, rule_settings=[rule1, rule2]))
760             self.sec_grp_creator.create()
761         except Exception as e:
762             self.tearDown()
763             raise e
764
765     def tearDown(self):
766         """
767         Cleans the created object
768         """
769         for inst_creator in self.inst_creators:
770             try:
771                 inst_creator.clean()
772             except Exception as e:
773                 logger.error(
774                     'Unexpected exception cleaning VM instance with message '
775                     '- %s', e)
776
777         if self.keypair_creator:
778             try:
779                 self.keypair_creator.clean()
780             except Exception as e:
781                 logger.error(
782                     'Unexpected exception cleaning keypair with message - %s',
783                     e)
784
785         if self.flavor_creator:
786             try:
787                 self.flavor_creator.clean()
788             except Exception as e:
789                 logger.error(
790                     'Unexpected exception cleaning flavor with message - %s',
791                     e)
792
793         if self.sec_grp_creator:
794             try:
795                 self.sec_grp_creator.clean()
796             except Exception as e:
797                 logger.error(
798                     'Unexpected exception cleaning security group with message'
799                     ' - %s', e)
800
801         if self.router_creator:
802             try:
803                 self.router_creator.clean()
804             except Exception as e:
805                 logger.error(
806                     'Unexpected exception cleaning router with message - %s',
807                     e)
808
809         if self.network_creator:
810             try:
811                 self.network_creator.clean()
812             except Exception as e:
813                 logger.error(
814                     'Unexpected exception cleaning network with message - %s',
815                     e)
816
817         if self.image_creator and not self.image_creator.image_settings.exists:
818             try:
819                 self.image_creator.clean()
820             except Exception as e:
821                 logger.error(
822                     'Unexpected exception cleaning image with message - %s', e)
823
824         super(self.__class__, self).__clean__()
825
826     def test_single_port_static(self):
827         """
828         Tests the creation of an OpenStack instance with a single port with a
829         static IP without a Floating IP.
830         """
831         ip_1 = '10.55.1.100'
832         sub_settings = self.pub_net_config.network_settings.subnet_settings
833         port_settings = PortConfig(
834             name=self.port_1_name,
835             network_name=self.pub_net_config.network_settings.name,
836             ip_addrs=[
837                 {'subnet_name': sub_settings[0].name, 'ip': ip_1}])
838
839         instance_settings = VmInstanceConfig(
840             name=self.vm_inst_name,
841             flavor=self.flavor_creator.flavor_settings.name,
842             port_settings=[port_settings],
843             floating_ip_settings=[FloatingIpConfig(
844                 name=self.floating_ip_name, port_name=self.port_1_name,
845                 router_name=self.pub_net_config.router_settings.name)])
846
847         inst_creator = OpenStackVmInstance(
848             self.os_creds, instance_settings,
849             self.image_creator.image_settings,
850             keypair_settings=self.keypair_creator.keypair_settings)
851         self.inst_creators.append(inst_creator)
852         vm_inst = inst_creator.create(block=True)
853
854         self.assertEqual(ip_1, inst_creator.get_port_ip(self.port_1_name))
855         self.assertTrue(inst_creator.vm_active(block=True))
856         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
857
858     def test_ssh_client_fip_before_active(self):
859         """
860         Tests the ability to access a VM via SSH and a floating IP when it has
861         been assigned prior to being active.
862         """
863         port_settings = PortConfig(
864             name=self.port_1_name,
865             network_name=self.pub_net_config.network_settings.name)
866
867         instance_settings = VmInstanceConfig(
868             name=self.vm_inst_name,
869             flavor=self.flavor_creator.flavor_settings.name,
870             port_settings=[port_settings],
871             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
872             floating_ip_settings=[FloatingIpConfig(
873                 name=self.floating_ip_name, port_name=self.port_1_name,
874                 router_name=self.pub_net_config.router_settings.name)])
875
876         inst_creator = OpenStackVmInstance(
877             self.os_creds, instance_settings,
878             self.image_creator.image_settings,
879             keypair_settings=self.keypair_creator.keypair_settings)
880         self.inst_creators.append(inst_creator)
881         vm_inst = inst_creator.create()
882         self.assertIsNotNone(vm_inst)
883
884         self.assertTrue(inst_creator.vm_active(block=True))
885
886         ip = inst_creator.get_port_ip(port_settings.name)
887         self.assertTrue(check_dhcp_lease(inst_creator, ip))
888
889         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
890
891         self.assertTrue(validate_ssh_client(inst_creator))
892
893     def test_ssh_client_fip_after_active(self):
894         """
895         Tests the ability to access a VM via SSH and a floating IP when it has
896         been assigned prior to being active.
897         """
898         port_settings = PortConfig(
899             name=self.port_1_name,
900             network_name=self.pub_net_config.network_settings.name)
901
902         instance_settings = VmInstanceConfig(
903             name=self.vm_inst_name,
904             flavor=self.flavor_creator.flavor_settings.name,
905             port_settings=[port_settings],
906             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
907             floating_ip_settings=[FloatingIpConfig(
908                 name=self.floating_ip_name, port_name=self.port_1_name,
909                 router_name=self.pub_net_config.router_settings.name)])
910
911         inst_creator = OpenStackVmInstance(
912             self.os_creds, instance_settings,
913             self.image_creator.image_settings,
914             keypair_settings=self.keypair_creator.keypair_settings)
915         self.inst_creators.append(inst_creator)
916
917         # block=True will force the create() method to block until the
918         vm_inst = inst_creator.create(block=True)
919         self.assertIsNotNone(vm_inst)
920
921         self.assertTrue(inst_creator.vm_active(block=True))
922
923         ip = inst_creator.get_port_ip(port_settings.name)
924         self.assertTrue(check_dhcp_lease(inst_creator, ip))
925
926         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
927
928         self.assertTrue(validate_ssh_client(inst_creator))
929
930     def test_ssh_client_fip_after_reboot(self):
931         """
932         Tests the ability to access a VM via SSH and a floating IP after it has
933         been rebooted.
934         """
935         port_settings = PortConfig(
936             name=self.port_1_name,
937             network_name=self.pub_net_config.network_settings.name)
938
939         instance_settings = VmInstanceConfig(
940             name=self.vm_inst_name,
941             flavor=self.flavor_creator.flavor_settings.name,
942             port_settings=[port_settings],
943             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
944             floating_ip_settings=[FloatingIpConfig(
945                 name=self.floating_ip_name, port_name=self.port_1_name,
946                 router_name=self.pub_net_config.router_settings.name)])
947
948         inst_creator = OpenStackVmInstance(
949             self.os_creds, instance_settings,
950             self.image_creator.image_settings,
951             keypair_settings=self.keypair_creator.keypair_settings)
952         self.inst_creators.append(inst_creator)
953
954         # block=True will force the create() method to block until the
955         vm_inst = inst_creator.create(block=True)
956         self.assertIsNotNone(vm_inst)
957
958         self.assertTrue(inst_creator.vm_active(block=True))
959
960         ip = inst_creator.get_port_ip(port_settings.name)
961         self.assertTrue(check_dhcp_lease(inst_creator, ip))
962
963         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
964
965         self.assertTrue(validate_ssh_client(inst_creator))
966
967         # Test default reboot which should be 'SOFT'
968         inst_creator.reboot()
969         # Lag time to allow for shutdown routine to take effect
970         time.sleep(15)
971         self.assertTrue(check_dhcp_lease(inst_creator, ip))
972         self.assertTrue(validate_ssh_client(inst_creator))
973
974         # Test 'SOFT' reboot
975         inst_creator.reboot(reboot_type=RebootType.soft)
976         time.sleep(15)
977         self.assertTrue(check_dhcp_lease(inst_creator, ip))
978         self.assertTrue(validate_ssh_client(inst_creator))
979
980         # Test 'HARD' reboot
981         inst_creator.reboot(reboot_type=RebootType.hard)
982         time.sleep(15)
983         self.assertTrue(check_dhcp_lease(inst_creator, ip))
984         self.assertTrue(validate_ssh_client(inst_creator))
985
986     def test_ssh_client_fip_after_init(self):
987         """
988         Tests the ability to assign a floating IP to an already initialized
989         OpenStackVmInstance object. After the floating IP has been allocated
990         and assigned, this test will ensure that it can be accessed via SSH.
991         """
992         port_settings = PortConfig(
993             name=self.port_1_name,
994             network_name=self.pub_net_config.network_settings.name)
995
996         instance_settings = VmInstanceConfig(
997             name=self.vm_inst_name,
998             flavor=self.flavor_creator.flavor_settings.name,
999             port_settings=[port_settings],
1000             security_group_names=[self.sec_grp_creator.sec_grp_settings.name])
1001
1002         inst_creator = OpenStackVmInstance(
1003             self.os_creds, instance_settings,
1004             self.image_creator.image_settings,
1005             keypair_settings=self.keypair_creator.keypair_settings)
1006         self.inst_creators.append(inst_creator)
1007
1008         # block=True will force the create() method to block until the
1009         vm_inst = inst_creator.create(block=True)
1010         self.assertIsNotNone(vm_inst)
1011
1012         self.assertTrue(inst_creator.vm_active(block=True))
1013         ip = inst_creator.get_port_ip(port_settings.name)
1014         self.assertTrue(check_dhcp_lease(inst_creator, ip))
1015         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
1016
1017         inst_creator.add_floating_ip(FloatingIpConfig(
1018             name=self.floating_ip_name, port_name=self.port_1_name,
1019             router_name=self.pub_net_config.router_settings.name))
1020
1021         self.assertTrue(validate_ssh_client(inst_creator))
1022
1023     def test_ssh_client_fip_reverse_engineer(self):
1024         """
1025         Tests the ability to assign a floating IP to a reverse engineered
1026         OpenStackVmInstance object. After the floating IP has been allocated
1027         and assigned, this test will ensure that it can be accessed via SSH.
1028         """
1029         port_settings = PortConfig(
1030             name=self.port_1_name,
1031             network_name=self.pub_net_config.network_settings.name)
1032
1033         instance_settings = VmInstanceConfig(
1034             name=self.vm_inst_name,
1035             flavor=self.flavor_creator.flavor_settings.name,
1036             port_settings=[port_settings],
1037             security_group_names=[self.sec_grp_creator.sec_grp_settings.name])
1038
1039         inst_creator = OpenStackVmInstance(
1040             self.os_creds, instance_settings,
1041             self.image_creator.image_settings,
1042             keypair_settings=self.keypair_creator.keypair_settings)
1043         self.inst_creators.append(inst_creator)
1044
1045         # block=True will force the create() method to block until the
1046         vm_inst = inst_creator.create(block=True)
1047         self.assertIsNotNone(vm_inst)
1048
1049         self.assertTrue(inst_creator.vm_active(block=True))
1050
1051         derived_inst_creator = create_instance.generate_creator(
1052             self.os_creds, vm_inst, self.image_creator.image_settings,
1053             self.os_creds.project_name, self.keypair_creator.keypair_settings)
1054
1055         derived_inst_creator.add_floating_ip(FloatingIpConfig(
1056             name=self.floating_ip_name, port_name=self.port_1_name,
1057             router_name=self.pub_net_config.router_settings.name))
1058         self.inst_creators.append(derived_inst_creator)
1059
1060         self.assertTrue(validate_ssh_client(
1061             derived_inst_creator, fip_name=self.floating_ip_name))
1062
1063     def test_ssh_client_fip_second_creator(self):
1064         """
1065         Tests the ability to access a VM via SSH and a floating IP via a
1066         creator that is identical to the original creator.
1067         """
1068         port_settings = PortConfig(
1069             name=self.port_1_name,
1070             network_name=self.pub_net_config.network_settings.name)
1071
1072         instance_settings = VmInstanceConfig(
1073             name=self.vm_inst_name,
1074             flavor=self.flavor_creator.flavor_settings.name,
1075             port_settings=[port_settings],
1076             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
1077             floating_ip_settings=[FloatingIpConfig(
1078                 name=self.floating_ip_name, port_name=self.port_1_name,
1079                 router_name=self.pub_net_config.router_settings.name)])
1080
1081         inst_creator = OpenStackVmInstance(
1082             self.os_creds, instance_settings,
1083             self.image_creator.image_settings,
1084             keypair_settings=self.keypair_creator.keypair_settings)
1085         self.inst_creators.append(inst_creator)
1086
1087         # block=True will force the create() method to block until the
1088         vm_inst = inst_creator.create(block=True)
1089         self.assertIsNotNone(vm_inst)
1090
1091         self.assertTrue(inst_creator.vm_active(block=True))
1092
1093         ip = inst_creator.get_port_ip(port_settings.name)
1094         self.assertTrue(check_dhcp_lease(inst_creator, ip))
1095
1096         self.assertEqual(vm_inst.id, inst_creator.get_vm_inst().id)
1097
1098         self.assertTrue(validate_ssh_client(inst_creator))
1099
1100         inst_creator2 = OpenStackVmInstance(
1101             self.os_creds, instance_settings,
1102             self.image_creator.image_settings,
1103             keypair_settings=self.keypair_creator.keypair_settings)
1104         inst_creator2.create()
1105         self.assertTrue(validate_ssh_client(inst_creator2))
1106
1107
1108 class CreateInstanceIPv6NetworkTests(OSIntegrationTestCase):
1109     """
1110     Test for the CreateInstance class with a single NIC/Port with Floating IPs
1111     """
1112
1113     def setUp(self):
1114         """
1115         Instantiates the CreateImage object that is responsible for downloading
1116         and creating an OS image file within OpenStack
1117         """
1118         super(self.__class__, self).__start__()
1119
1120         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
1121         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1122         self.keypair_priv_filepath = 'tmp/' + self.guid
1123         self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
1124         self.keypair_name = self.guid + '-kp'
1125         self.vm_inst_name = self.guid + '-inst'
1126         self.port1_name = self.guid + 'port1'
1127         self.port2_name = self.guid + 'port2'
1128
1129         # Initialize for tearDown()
1130         self.image_creator = None
1131         self.network_creator = None
1132         self.router_creator = None
1133         self.flavor_creator = None
1134         self.keypair_creator = None
1135         self.sec_grp_creator = None
1136         self.inst_creator = None
1137
1138         os_image_settings = openstack_tests.cirros_image_settings(
1139             name=self.guid + '-image', image_metadata=self.image_metadata)
1140         try:
1141             self.image_creator = OpenStackImage(
1142                 self.os_creds, os_image_settings)
1143             self.image_creator.create()
1144
1145             self.flavor_creator = OpenStackFlavor(
1146                 self.admin_os_creds,
1147                 FlavorConfig(
1148                     name=self.guid + '-flavor-name', ram=256, disk=10, vcpus=2,
1149                     metadata=self.flavor_metadata))
1150             self.flavor_creator.create()
1151
1152             self.keypair_creator = OpenStackKeypair(
1153                 self.os_creds, KeypairConfig(
1154                     name=self.keypair_name,
1155                     public_filepath=self.keypair_pub_filepath,
1156                     private_filepath=self.keypair_priv_filepath))
1157             self.keypair_creator.create()
1158
1159             sec_grp_name = self.guid + '-sec-grp'
1160             rule1 = SecurityGroupRuleConfig(
1161                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
1162                 protocol=Protocol.icmp)
1163             rule2 = SecurityGroupRuleConfig(
1164                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
1165                 protocol=Protocol.tcp, port_range_min=22, port_range_max=22)
1166             self.sec_grp_creator = OpenStackSecurityGroup(
1167                 self.os_creds,
1168                 SecurityGroupConfig(
1169                     name=sec_grp_name, rule_settings=[rule1, rule2]))
1170             self.sec_grp_creator.create()
1171         except Exception as e:
1172             self.tearDown()
1173             raise e
1174
1175     def tearDown(self):
1176         """
1177         Cleans the created object
1178         """
1179         if self.inst_creator:
1180             try:
1181                 self.inst_creator.clean()
1182             except Exception as e:
1183                 logger.error(
1184                     'Unexpected exception cleaning VM instance with message '
1185                     '- %s', e)
1186
1187         if self.keypair_creator:
1188             try:
1189                 self.keypair_creator.clean()
1190             except Exception as e:
1191                 logger.error(
1192                     'Unexpected exception cleaning keypair with message - %s',
1193                     e)
1194
1195         if self.flavor_creator:
1196             try:
1197                 self.flavor_creator.clean()
1198             except Exception as e:
1199                 logger.error(
1200                     'Unexpected exception cleaning flavor with message - %s',
1201                     e)
1202
1203         if self.sec_grp_creator:
1204             try:
1205                 self.sec_grp_creator.clean()
1206             except Exception as e:
1207                 logger.error(
1208                     'Unexpected exception cleaning security group with message'
1209                     ' - %s', e)
1210
1211         if self.router_creator:
1212             try:
1213                 self.router_creator.clean()
1214             except Exception as e:
1215                 logger.error(
1216                     'Unexpected exception cleaning router with message - %s',
1217                     e)
1218
1219         if self.network_creator:
1220             try:
1221                 self.network_creator.clean()
1222             except Exception as e:
1223                 logger.error(
1224                     'Unexpected exception cleaning network with message - %s',
1225                     e)
1226
1227         if self.image_creator and not self.image_creator.image_settings.exists:
1228             try:
1229                 self.image_creator.clean()
1230             except Exception as e:
1231                 logger.error(
1232                     'Unexpected exception cleaning image with message - %s', e)
1233
1234         super(self.__class__, self).__clean__()
1235
1236     def test_v4fip_v6overlay(self):
1237         """
1238         Tests the ability to assign an IPv4 floating IP to an IPv6 overlay
1239         network when the external network does not have an IPv6 subnet.
1240         """
1241         subnet_settings = SubnetConfig(
1242             name=self.guid + '-subnet', cidr='1:1:0:0:0:0:0:0/64',
1243             ip_version=6)
1244         network_settings = NetworkConfig(
1245             name=self.guid + '-net', subnet_settings=[subnet_settings])
1246         router_settings = RouterConfig(
1247             name=self.guid + '-router', external_gateway=self.ext_net_name,
1248             internal_subnets=[subnet_settings.name])
1249
1250         # Create Network
1251         self.network_creator = OpenStackNetwork(
1252             self.os_creds, network_settings)
1253         self.network_creator.create()
1254
1255         # Create Router
1256         self.router_creator = OpenStackRouter(
1257             self.os_creds, router_settings)
1258         self.router_creator.create()
1259
1260         port_settings = PortConfig(
1261             name=self.port1_name, network_name=network_settings.name)
1262
1263         instance_settings = VmInstanceConfig(
1264             name=self.vm_inst_name,
1265             flavor=self.flavor_creator.flavor_settings.name,
1266             port_settings=[port_settings],
1267             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
1268             floating_ip_settings=[FloatingIpConfig(
1269                 name='fip1', port_name=self.port1_name,
1270                 router_name=router_settings.name)])
1271
1272         self.inst_creator = OpenStackVmInstance(
1273             self.os_creds, instance_settings,
1274             self.image_creator.image_settings,
1275             keypair_settings=self.keypair_creator.keypair_settings)
1276
1277         with self.assertRaises(BadRequest):
1278             self.inst_creator.create(block=True)
1279
1280     def test_fip_v4and6_overlay(self):
1281         """
1282         Tests the ability to assign an IPv4 floating IP to an IPv6 overlay
1283         network when the external network does not have an IPv6 subnet.
1284         """
1285         subnet4_settings = SubnetConfig(
1286             name=self.guid + '-subnet4', cidr='10.0.1.0/24',
1287             ip_version=4)
1288         subnet6_settings = SubnetConfig(
1289             name=self.guid + '-subnet6', cidr='1:1:0:0:0:0:0:0/64',
1290             ip_version=6)
1291         network_settings = NetworkConfig(
1292             name=self.guid + '-net',
1293             subnet_settings=[subnet4_settings, subnet6_settings])
1294         router_settings = RouterConfig(
1295             name=self.guid + '-router', external_gateway=self.ext_net_name,
1296             internal_subnets=[subnet4_settings.name])
1297
1298         # Create Network
1299         self.network_creator = OpenStackNetwork(
1300             self.os_creds, network_settings)
1301         self.network_creator.create()
1302
1303         # Create Router
1304         self.router_creator = OpenStackRouter(
1305             self.os_creds, router_settings)
1306         self.router_creator.create()
1307
1308         port_settings = PortConfig(
1309             name=self.port1_name, network_name=network_settings.name)
1310
1311         instance_settings = VmInstanceConfig(
1312             name=self.vm_inst_name,
1313             flavor=self.flavor_creator.flavor_settings.name,
1314             port_settings=[port_settings],
1315             security_group_names=[self.sec_grp_creator.sec_grp_settings.name],
1316             floating_ip_settings=[FloatingIpConfig(
1317                 name='fip1', port_name=self.port1_name,
1318                 router_name=router_settings.name)])
1319
1320         self.inst_creator = OpenStackVmInstance(
1321             self.os_creds, instance_settings,
1322             self.image_creator.image_settings,
1323             keypair_settings=self.keypair_creator.keypair_settings)
1324
1325         self.inst_creator.create(block=True)
1326         ssh_client = self.inst_creator.ssh_client()
1327         self.assertIsNotNone(ssh_client)
1328
1329
1330 class CreateInstancePortManipulationTests(OSIntegrationTestCase):
1331     """
1332     Test for the CreateInstance class with a single NIC/Port where mac and IP
1333     values are manually set
1334     """
1335
1336     def setUp(self):
1337         """
1338         Instantiates the CreateImage object that is responsible for downloading
1339         and creating an OS image file within OpenStack
1340         """
1341         super(self.__class__, self).__start__()
1342
1343         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1344         self.vm_inst_name = guid + '-inst'
1345         self.port_1_name = guid + 'port-1'
1346         self.port_2_name = guid + 'port-2'
1347         self.floating_ip_name = guid + 'fip1'
1348
1349         # Initialize for tearDown()
1350         self.image_creator = None
1351         self.network_creator = None
1352         self.flavor_creator = None
1353         self.inst_creator = None
1354
1355         self.net_config = openstack_tests.get_priv_net_config(
1356             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
1357             router_name=guid + '-pub-router', external_net=self.ext_net_name,
1358             netconf_override=self.netconf_override)
1359         os_image_settings = openstack_tests.cirros_image_settings(
1360             name=guid + '-image', image_metadata=self.image_metadata)
1361
1362         try:
1363             # Create Image
1364             self.image_creator = OpenStackImage(self.os_creds,
1365                                                 os_image_settings)
1366             self.image_creator.create()
1367
1368             # Create Network
1369             self.network_creator = OpenStackNetwork(
1370                 self.os_creds, self.net_config.network_settings)
1371             self.network_creator.create()
1372
1373             # Create Flavor
1374             self.flavor_creator = OpenStackFlavor(
1375                 self.admin_os_creds,
1376                 FlavorConfig(name=guid + '-flavor-name', ram=256, disk=10,
1377                              vcpus=2, metadata=self.flavor_metadata))
1378             self.flavor_creator.create()
1379         except Exception as e:
1380             self.tearDown()
1381             raise e
1382
1383     def tearDown(self):
1384         """
1385         Cleans the created object
1386         """
1387         if self.inst_creator:
1388             try:
1389                 self.inst_creator.clean()
1390             except Exception as e:
1391                 logger.error(
1392                     'Unexpected exception cleaning VM instance with message '
1393                     '- %s', e)
1394
1395         if self.flavor_creator:
1396             try:
1397                 self.flavor_creator.clean()
1398             except Exception as e:
1399                 logger.error(
1400                     'Unexpected exception cleaning flavor with message - %s',
1401                     e)
1402
1403         if self.network_creator:
1404             try:
1405                 self.network_creator.clean()
1406             except Exception as e:
1407                 logger.error(
1408                     'Unexpected exception cleaning network with message - %s',
1409                     e)
1410
1411         if self.image_creator and not self.image_creator.image_settings.exists:
1412             try:
1413                 self.image_creator.clean()
1414             except Exception as e:
1415                 logger.error(
1416                     'Unexpected exception cleaning image with message - %s', e)
1417
1418         super(self.__class__, self).__clean__()
1419
1420     def test_set_custom_valid_ip_one_subnet(self):
1421         """
1422         Tests the creation of an OpenStack instance with a single port with a
1423         static IP on a network with one subnet.
1424         """
1425         ip = '10.55.0.101'
1426         sub_settings = self.net_config.network_settings.subnet_settings
1427         port_settings = PortConfig(
1428             name=self.port_1_name,
1429             network_name=self.net_config.network_settings.name,
1430             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1431
1432         instance_settings = VmInstanceConfig(
1433             name=self.vm_inst_name,
1434             flavor=self.flavor_creator.flavor_settings.name,
1435             port_settings=[port_settings])
1436
1437         self.inst_creator = OpenStackVmInstance(
1438             self.os_creds, instance_settings,
1439             self.image_creator.image_settings)
1440         self.inst_creator.create(block=True)
1441
1442         self.assertEqual(ip, self.inst_creator.get_port_ip(
1443             self.port_1_name,
1444             subnet_name=self.net_config.network_settings.subnet_settings[
1445                 0].name))
1446
1447     def test_set_custom_invalid_ip_one_subnet(self):
1448         """
1449         Tests the creation of an OpenStack instance with a single port with a
1450         static IP on a network with one subnet.
1451         """
1452         ip = '10.66.0.101'
1453         sub_settings = self.net_config.network_settings.subnet_settings
1454         port_settings = PortConfig(
1455             name=self.port_1_name,
1456             network_name=self.net_config.network_settings.name,
1457             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1458
1459         instance_settings = VmInstanceConfig(
1460             name=self.vm_inst_name,
1461             flavor=self.flavor_creator.flavor_settings.name,
1462             port_settings=[port_settings])
1463
1464         self.inst_creator = OpenStackVmInstance(
1465             self.os_creds, instance_settings,
1466             self.image_creator.image_settings)
1467
1468         with self.assertRaises(InvalidIpForSubnetClient):
1469             self.inst_creator.create()
1470
1471     def test_set_custom_valid_mac(self):
1472         """
1473         Tests the creation of an OpenStack instance with a single port where
1474         the MAC address is assigned.
1475         """
1476         mac_addr = '0a:1b:2c:3d:4e:5f'
1477         port_settings = PortConfig(
1478             name=self.port_1_name,
1479             network_name=self.net_config.network_settings.name,
1480             mac_address=mac_addr)
1481
1482         instance_settings = VmInstanceConfig(
1483             name=self.vm_inst_name,
1484             flavor=self.flavor_creator.flavor_settings.name,
1485             port_settings=[port_settings])
1486
1487         self.inst_creator = OpenStackVmInstance(
1488             self.os_creds, instance_settings,
1489             self.image_creator.image_settings)
1490         self.inst_creator.create(block=True)
1491
1492         self.assertEqual(mac_addr,
1493                          self.inst_creator.get_port_mac(self.port_1_name))
1494
1495     def test_set_custom_invalid_mac(self):
1496         """
1497         Tests the creation of an OpenStack instance with a single port where an
1498         invalid MAC address value is being
1499         assigned. This should raise an Exception
1500         """
1501         port_settings = PortConfig(
1502             name=self.port_1_name,
1503             network_name=self.net_config.network_settings.name,
1504             mac_address='foo')
1505
1506         instance_settings = VmInstanceConfig(
1507             name=self.vm_inst_name,
1508             flavor=self.flavor_creator.flavor_settings.name,
1509             port_settings=[port_settings])
1510
1511         self.inst_creator = OpenStackVmInstance(
1512             self.os_creds, instance_settings,
1513             self.image_creator.image_settings)
1514
1515         with self.assertRaises(Exception):
1516             self.inst_creator.create()
1517
1518     def test_set_custom_mac_and_ip(self):
1519         """
1520         Tests the creation of an OpenStack instance with a single port where
1521         the IP and MAC address is assigned.
1522         """
1523         ip = '10.55.0.101'
1524         mac_addr = '0a:1b:2c:3d:4e:5f'
1525         sub_settings = self.net_config.network_settings.subnet_settings
1526         port_settings = PortConfig(
1527             name=self.port_1_name,
1528             network_name=self.net_config.network_settings.name,
1529             mac_address=mac_addr,
1530             ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}])
1531
1532         instance_settings = VmInstanceConfig(
1533             name=self.vm_inst_name,
1534             flavor=self.flavor_creator.flavor_settings.name,
1535             port_settings=[port_settings])
1536
1537         self.inst_creator = OpenStackVmInstance(
1538             self.os_creds, instance_settings,
1539             self.image_creator.image_settings)
1540         self.inst_creator.create(block=True)
1541
1542         self.assertEqual(ip, self.inst_creator.get_port_ip(
1543             self.port_1_name,
1544             subnet_name=self.net_config.network_settings.subnet_settings[
1545                 0].name))
1546         self.assertEqual(mac_addr,
1547                          self.inst_creator.get_port_mac(self.port_1_name))
1548
1549     def test_set_allowed_address_pairs(self):
1550         """
1551         Tests the creation of an OpenStack instance with a single port where
1552         max_allowed_address_pair is set.
1553         """
1554         ip = '10.55.0.101'
1555         mac_addr = '0a:1b:2c:3d:4e:5f'
1556         pair = {'ip_address': ip, 'mac_address': mac_addr}
1557         port_settings = PortConfig(
1558             name=self.port_1_name,
1559             network_name=self.net_config.network_settings.name,
1560             allowed_address_pairs=[pair])
1561
1562         instance_settings = VmInstanceConfig(
1563             name=self.vm_inst_name,
1564             flavor=self.flavor_creator.flavor_settings.name,
1565             port_settings=[port_settings])
1566
1567         self.inst_creator = OpenStackVmInstance(
1568             self.os_creds, instance_settings,
1569             self.image_creator.image_settings)
1570         self.inst_creator.create(block=True)
1571
1572         port = self.inst_creator.get_port_by_name(port_settings.name)
1573         self.assertIsNotNone(port)
1574         self.assertIsNotNone(port.allowed_address_pairs)
1575         self.assertEqual(1, len(port.allowed_address_pairs))
1576         validation_utils.objects_equivalent(pair,
1577                                             port.allowed_address_pairs[0])
1578
1579     def test_set_allowed_address_pairs_bad_mac(self):
1580         """
1581         Tests the creation of an OpenStack instance with a single port where
1582         max_allowed_address_pair is set with an invalid MAC address.
1583         """
1584         ip = '10.55.0.101'
1585         mac_addr = 'foo'
1586         pair = {'ip_address': ip, 'mac_address': mac_addr}
1587         pairs = set()
1588         pairs.add((ip, mac_addr))
1589         port_settings = PortConfig(
1590             name=self.port_1_name,
1591             network_name=self.net_config.network_settings.name,
1592             allowed_address_pairs=[pair])
1593
1594         instance_settings = VmInstanceConfig(
1595             name=self.vm_inst_name,
1596             flavor=self.flavor_creator.flavor_settings.name,
1597             port_settings=[port_settings])
1598
1599         self.inst_creator = OpenStackVmInstance(
1600             self.os_creds, instance_settings,
1601             self.image_creator.image_settings)
1602         with self.assertRaises(Exception):
1603             self.inst_creator.create()
1604
1605     def test_set_allowed_address_pairs_bad_ip(self):
1606         """
1607         Tests the creation of an OpenStack instance with a single port where
1608         max_allowed_address_pair is set with an invalid MAC address.
1609         """
1610         ip = 'foo'
1611         mac_addr = '0a:1b:2c:3d:4e:5f'
1612         pair = {'ip_address': ip, 'mac_address': mac_addr}
1613         pairs = set()
1614         pairs.add((ip, mac_addr))
1615         port_settings = PortConfig(
1616             name=self.port_1_name,
1617             network_name=self.net_config.network_settings.name,
1618             allowed_address_pairs=[pair])
1619
1620         instance_settings = VmInstanceConfig(
1621             name=self.vm_inst_name,
1622             flavor=self.flavor_creator.flavor_settings.name,
1623             port_settings=[port_settings])
1624
1625         self.inst_creator = OpenStackVmInstance(
1626             self.os_creds, instance_settings,
1627             self.image_creator.image_settings)
1628         with self.assertRaises(Exception):
1629             self.inst_creator.create()
1630
1631
1632 class CreateInstanceOnComputeHost(OSIntegrationTestCase):
1633     """
1634     Test for the CreateInstance where one VM is deployed to each compute node
1635     """
1636
1637     def setUp(self):
1638         """
1639         Instantiates the CreateImage object that is responsible for downloading
1640         and creating an OS image file within OpenStack
1641         """
1642         super(self.__class__, self).__start__()
1643
1644         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1645         self.vm_inst_name = guid + '-inst'
1646         self.port_base_name = guid + 'port'
1647
1648         # Initialize for tearDown()
1649         self.image_creator = None
1650         self.flavor_creator = None
1651         self.network_creator = None
1652         self.inst_creators = list()
1653
1654         self.priv_net_config = openstack_tests.get_priv_net_config(
1655             net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet',
1656             netconf_override=self.netconf_override)
1657
1658         os_image_settings = openstack_tests.cirros_image_settings(
1659             name=guid + '-image', image_metadata=self.image_metadata)
1660
1661         try:
1662             # Create Network
1663             self.network_creator = OpenStackNetwork(
1664                 self.admin_os_creds, self.priv_net_config.network_settings)
1665             self.network_creator.create()
1666
1667             # Create Flavor
1668             self.flavor_creator = OpenStackFlavor(
1669                 self.admin_os_creds,
1670                 FlavorConfig(name=guid + '-flavor-name', ram=512, disk=1,
1671                              vcpus=1, metadata=self.flavor_metadata))
1672             self.flavor_creator.create()
1673
1674             # Create Image
1675             self.image_creator = OpenStackImage(self.os_creds,
1676                                                 os_image_settings)
1677             self.image_creator.create()
1678
1679         except Exception as e:
1680             self.tearDown()
1681             raise e
1682
1683     def tearDown(self):
1684         """
1685         Cleans the created object
1686         """
1687         for inst_creator in self.inst_creators:
1688             try:
1689                 inst_creator.clean()
1690             except Exception as e:
1691                 logger.error(
1692                     'Unexpected exception cleaning VM instance with message '
1693                     '- %s', e)
1694
1695         if self.flavor_creator:
1696             try:
1697                 self.flavor_creator.clean()
1698             except Exception as e:
1699                 logger.error(
1700                     'Unexpected exception cleaning flavor with message - %s',
1701                     e)
1702
1703         if self.network_creator:
1704             try:
1705                 self.network_creator.clean()
1706             except Exception as e:
1707                 logger.error(
1708                     'Unexpected exception cleaning network with message - %s',
1709                     e)
1710
1711         if self.image_creator and not self.image_creator.image_settings.exists:
1712             try:
1713                 self.image_creator.clean()
1714             except Exception as e:
1715                 logger.error(
1716                     'Unexpected exception cleaning image with message - %s', e)
1717
1718         super(self.__class__, self).__clean__()
1719
1720     def test_deploy_vm_to_each_compute_node(self):
1721         """
1722         Tests the creation of OpenStack VM instances to each compute node.
1723         """
1724         from snaps.openstack.utils import nova_utils
1725         nova = nova_utils.nova_client(
1726             self.admin_os_creds, self.admin_os_session)
1727         zone_hosts = nova_utils.get_availability_zone_hosts(nova)
1728
1729         # Create Instance on each server/zone
1730         ctr = 0
1731         for zone in zone_hosts:
1732             inst_name = self.vm_inst_name + '-' + zone
1733             ctr += 1
1734             port_settings = PortConfig(
1735                 name=self.port_base_name + '-' + str(ctr),
1736                 network_name=self.priv_net_config.network_settings.name)
1737
1738             instance_settings = VmInstanceConfig(
1739                 name=inst_name,
1740                 flavor=self.flavor_creator.flavor_settings.name,
1741                 availability_zone=zone,
1742                 port_settings=[port_settings])
1743             inst_creator = OpenStackVmInstance(
1744                 self.admin_os_creds, instance_settings,
1745                 self.image_creator.image_settings)
1746             self.inst_creators.append(inst_creator)
1747             inst_creator.create(block=True)
1748             avail_zone = inst_creator.get_vm_inst().availability_zone
1749             self.assertTrue(avail_zone in zone)
1750             compute_host = inst_creator.get_vm_inst().compute_host
1751             self.assertTrue(compute_host in zone)
1752
1753         # Validate instances to ensure they've been deployed to the correct
1754         # server
1755         index = 0
1756         for zone in zone_hosts:
1757             creator = self.inst_creators[index]
1758             self.assertTrue(creator.vm_active(block=True))
1759             info = creator.get_vm_info()
1760             deployed_zone = info['OS-EXT-AZ:availability_zone']
1761             deployed_host = info['OS-EXT-SRV-ATTR:host']
1762             self.assertEqual(zone, deployed_zone + ':' + deployed_host)
1763             index += 1
1764
1765
1766 class InstanceSecurityGroupTests(OSIntegrationTestCase):
1767     """
1768     Tests that include, add, and remove security groups from VM instances
1769     """
1770
1771     def setUp(self):
1772         """
1773         Instantiates the CreateImage object that is responsible for downloading
1774         and creating an OS image file within OpenStack
1775         """
1776         super(self.__class__, self).__start__()
1777
1778         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
1779         self.vm_inst_name = self.guid + '-inst'
1780         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
1781         os_image_settings = openstack_tests.cirros_image_settings(
1782             name=self.guid + '-image', image_metadata=self.image_metadata)
1783
1784         self.vm_inst_name = self.guid + '-inst'
1785         self.port_1_name = self.guid + 'port-1'
1786         self.port_2_name = self.guid + 'port-2'
1787         self.floating_ip_name = self.guid + 'fip1'
1788
1789         net_config = openstack_tests.get_priv_net_config(
1790             net_name=self.guid + '-pub-net',
1791             subnet_name=self.guid + '-pub-subnet',
1792             router_name=self.guid + '-pub-router',
1793             external_net=self.ext_net_name,
1794             netconf_override=self.netconf_override)
1795
1796         # Initialize for tearDown()
1797         self.image_creator = None
1798         self.flavor_creator = None
1799         self.network_creator = None
1800         self.router_creator = None
1801         self.inst_creator = None
1802         self.sec_grp_creators = list()
1803
1804         try:
1805             # Create Image
1806             self.image_creator = OpenStackImage(self.os_creds,
1807                                                 os_image_settings)
1808             self.image_creator.create()
1809
1810             # Create Network
1811             self.network_creator = OpenStackNetwork(
1812                 self.os_creds, net_config.network_settings)
1813             self.network_creator.create()
1814
1815             # Create Flavor
1816             self.flavor_creator = OpenStackFlavor(
1817                 self.admin_os_creds,
1818                 FlavorConfig(name=self.guid + '-flavor-name', ram=256,
1819                              disk=10, vcpus=2,
1820                              metadata=self.flavor_metadata))
1821             self.flavor_creator.create()
1822
1823             self.port_settings = PortConfig(
1824                 name=self.guid + '-port',
1825                 network_name=net_config.network_settings.name)
1826         except Exception as e:
1827             self.tearDown()
1828             raise e
1829
1830     def tearDown(self):
1831         """
1832         Cleans the created object
1833         """
1834         if self.inst_creator:
1835             try:
1836                 self.inst_creator.clean()
1837             except Exception as e:
1838                 logger.error(
1839                     'Unexpected exception cleaning VM instance with message -'
1840                     ' %s', e)
1841
1842         for sec_grp_creator in self.sec_grp_creators:
1843             try:
1844                 sec_grp_creator.clean()
1845             except Exception as e:
1846                 logger.error(
1847                     'Unexpected exception cleaning security group with message'
1848                     ' - %s', e)
1849
1850         if self.flavor_creator:
1851             try:
1852                 self.flavor_creator.clean()
1853             except Exception as e:
1854                 logger.error(
1855                     'Unexpected exception cleaning flavor with message - %s',
1856                     e)
1857
1858         if self.network_creator:
1859             try:
1860                 self.network_creator.clean()
1861             except Exception as e:
1862                 logger.error(
1863                     'Unexpected exception cleaning network with message - %s',
1864                     e)
1865
1866         if self.image_creator and not self.image_creator.image_settings.exists:
1867             try:
1868                 self.image_creator.clean()
1869             except Exception as e:
1870                 logger.error(
1871                     'Unexpected exception cleaning image with message - %s', e)
1872
1873         super(self.__class__, self).__clean__()
1874
1875     def test_add_security_group(self):
1876         """
1877         Tests the addition of a security group created after the instance.
1878         """
1879         # Create instance
1880         instance_settings = VmInstanceConfig(
1881             name=self.vm_inst_name,
1882             flavor=self.flavor_creator.flavor_settings.name,
1883             port_settings=[self.port_settings])
1884         self.inst_creator = OpenStackVmInstance(
1885             self.os_creds, instance_settings,
1886             self.image_creator.image_settings)
1887         vm_inst = self.inst_creator.create(block=True)
1888         self.assertIsNotNone(vm_inst)
1889
1890         # Create security group object to add to instance
1891         sec_grp_settings = SecurityGroupConfig(
1892             name=self.guid + '-name', description='hello group')
1893         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1894                                                  sec_grp_settings)
1895         sec_grp = sec_grp_creator.create()
1896         self.sec_grp_creators.append(sec_grp_creator)
1897
1898         # Check that group has not been added
1899         self.assertFalse(inst_has_sec_grp(
1900             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1901
1902         # Add security group to instance after activated
1903         self.inst_creator.add_security_group(sec_grp)
1904
1905         # Validate that security group has been added
1906         self.assertTrue(inst_has_sec_grp(
1907             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1908
1909     def test_add_invalid_security_group(self):
1910         """
1911         Tests the addition of a security group that no longer exists.
1912         """
1913         # Create instance
1914         instance_settings = VmInstanceConfig(
1915             name=self.vm_inst_name,
1916             flavor=self.flavor_creator.flavor_settings.name,
1917             port_settings=[self.port_settings])
1918         self.inst_creator = OpenStackVmInstance(
1919             self.os_creds, instance_settings,
1920             self.image_creator.image_settings)
1921         vm_inst = self.inst_creator.create(block=True)
1922         self.assertIsNotNone(vm_inst)
1923
1924         # Create security group object to add to instance
1925         sec_grp_settings = SecurityGroupConfig(
1926             name=self.guid + '-name', description='hello group')
1927         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1928                                                  sec_grp_settings)
1929         sec_grp = sec_grp_creator.create()
1930         sec_grp_creator.clean()
1931         self.sec_grp_creators.append(sec_grp_creator)
1932
1933         # Check that group has not been added
1934         self.assertFalse(inst_has_sec_grp(
1935             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1936
1937         # Add security group to instance after activated
1938         self.assertFalse(self.inst_creator.add_security_group(sec_grp))
1939
1940         # Validate that security group has been added
1941         self.assertFalse(inst_has_sec_grp(
1942             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1943
1944     def test_remove_security_group(self):
1945         """
1946         Tests the removal of a security group created before and added to the
1947         instance.
1948         """
1949         # Create security group object to add to instance
1950         sec_grp_settings = SecurityGroupConfig(
1951             name=self.guid + '-name', description='hello group')
1952         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1953                                                  sec_grp_settings)
1954         sec_grp = sec_grp_creator.create()
1955         self.sec_grp_creators.append(sec_grp_creator)
1956
1957         # Create instance
1958         instance_settings = VmInstanceConfig(
1959             name=self.vm_inst_name,
1960             flavor=self.flavor_creator.flavor_settings.name,
1961             security_group_names=[sec_grp_settings.name],
1962             port_settings=[self.port_settings])
1963         self.inst_creator = OpenStackVmInstance(
1964             self.os_creds, instance_settings,
1965             self.image_creator.image_settings)
1966         vm_inst = self.inst_creator.create(block=True)
1967         self.assertIsNotNone(vm_inst)
1968
1969         # Check that group has been added
1970         self.assertTrue(inst_has_sec_grp(
1971             self.nova, vm_inst, sec_grp_settings.name))
1972
1973         # Add security group to instance after activated
1974         self.assertTrue(self.inst_creator.remove_security_group(sec_grp))
1975
1976         # Validate that security group has been added
1977         self.assertFalse(inst_has_sec_grp(
1978             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
1979
1980     def test_remove_security_group_never_added(self):
1981         """
1982         Tests the removal of a security group that was never added in the first
1983         place.
1984         """
1985         # Create security group object to add to instance
1986         sec_grp_settings = SecurityGroupConfig(
1987             name=self.guid + '-name', description='hello group')
1988         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
1989                                                  sec_grp_settings)
1990         sec_grp = sec_grp_creator.create()
1991         self.sec_grp_creators.append(sec_grp_creator)
1992
1993         # Create instance
1994         instance_settings = VmInstanceConfig(
1995             name=self.vm_inst_name,
1996             flavor=self.flavor_creator.flavor_settings.name,
1997             port_settings=[self.port_settings])
1998         self.inst_creator = OpenStackVmInstance(
1999             self.os_creds, instance_settings,
2000             self.image_creator.image_settings)
2001         vm_inst = self.inst_creator.create(block=True)
2002         self.assertIsNotNone(vm_inst)
2003
2004         # Check that group has been added
2005         self.assertFalse(inst_has_sec_grp(
2006             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2007
2008         # Add security group to instance after activated
2009         self.assertFalse(self.inst_creator.remove_security_group(sec_grp))
2010
2011         # Validate that security group has been added
2012         self.assertFalse(inst_has_sec_grp(
2013             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2014
2015     def test_add_same_security_group(self):
2016         """
2017         Tests the addition of a security group created before add added to the
2018         instance.
2019         """
2020         # Create security group object to add to instance
2021         sec_grp_settings = SecurityGroupConfig(
2022             name=self.guid + '-name', description='hello group')
2023         sec_grp_creator = OpenStackSecurityGroup(self.os_creds,
2024                                                  sec_grp_settings)
2025         sec_grp = sec_grp_creator.create()
2026         self.sec_grp_creators.append(sec_grp_creator)
2027
2028         # Create instance
2029         instance_settings = VmInstanceConfig(
2030             name=self.vm_inst_name,
2031             flavor=self.flavor_creator.flavor_settings.name,
2032             security_group_names=[sec_grp_settings.name],
2033             port_settings=[self.port_settings])
2034         self.inst_creator = OpenStackVmInstance(
2035             self.os_creds, instance_settings,
2036             self.image_creator.image_settings)
2037         vm_inst = self.inst_creator.create(block=True)
2038         self.assertIsNotNone(vm_inst)
2039
2040         # Check that group has been added
2041         self.assertTrue(inst_has_sec_grp(
2042             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2043
2044         # Add security group to instance after activated
2045         self.assertTrue(self.inst_creator.add_security_group(sec_grp))
2046
2047         # Validate that security group has been added
2048         self.assertTrue(inst_has_sec_grp(
2049             self.nova, self.inst_creator.get_vm_inst(), sec_grp_settings.name))
2050
2051
2052 def inst_has_sec_grp(nova, vm_inst, sec_grp_name):
2053     """
2054     Returns true if instance has a security group of a given name
2055     :param nova: the nova client
2056     :param vm_inst: the VmInst domain object
2057     :param sec_grp_name: the name of the security group to validate
2058     :return: T/F
2059     """
2060     sec_grp_names = nova_utils.get_server_security_group_names(nova, vm_inst)
2061     for name in sec_grp_names:
2062         if sec_grp_name == name:
2063             return True
2064     return False
2065
2066
2067 def validate_ssh_client(instance_creator, fip_name=None):
2068     """
2069     Returns True if instance_creator returns an SSH client that is valid
2070     :param instance_creator: the object responsible for creating the VM
2071                              instance
2072     :param fip_name: the name of the floating IP to use
2073     :return: T/F
2074     """
2075     ssh_active = instance_creator.vm_ssh_active(block=True)
2076
2077     if ssh_active:
2078         ssh_client = instance_creator.ssh_client(fip_name=fip_name)
2079         if ssh_client:
2080             try:
2081                 out = ssh_client.exec_command('pwd')[1]
2082                 channel = out.channel
2083                 in_buffer = channel.in_buffer
2084                 pwd_out = in_buffer.read(1024)
2085                 if not pwd_out or len(pwd_out) < 10:
2086                     return False
2087                 return True
2088             finally:
2089                 ssh_client.close()
2090         else:
2091             return False
2092
2093     return False
2094
2095
2096 class CreateInstanceFromThreePartImage(OSIntegrationTestCase):
2097     """
2098     Test for the CreateInstance class for creating an image from a 3-part image
2099     """
2100
2101     def setUp(self):
2102         """
2103         Instantiates the CreateImage object that is responsible for downloading
2104         and creating an OS image file within OpenStack
2105         """
2106         super(self.__class__, self).__start__()
2107
2108         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2109         self.image_name = guid
2110         self.vm_inst_name = guid + '-inst'
2111         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
2112
2113         net_config = openstack_tests.get_priv_net_config(
2114             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
2115             router_name=guid + '-pub-router', external_net=self.ext_net_name,
2116             netconf_override=self.netconf_override)
2117
2118         # Initialize for tearDown()
2119         self.image_creator = None
2120         self.network_creator = None
2121         self.flavor_creator = None
2122         self.inst_creator = None
2123
2124         try:
2125             if self.image_metadata and 'disk_file' in self.image_metadata:
2126                 metadata = self.image_metadata
2127             elif self.image_metadata and 'cirros' in self.image_metadata \
2128                     and 'disk_file' in self.image_metadata['cirros']:
2129                 metadata = self.image_metadata['cirros']
2130             else:
2131                 metadata = {
2132                     'disk_url': openstack_tests.CIRROS_DEFAULT_IMAGE_URL,
2133                     'kernel_url':
2134                         openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL,
2135                     'ramdisk_url':
2136                         openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL}
2137
2138             image_settings = openstack_tests.cirros_image_settings(
2139                 name=self.image_name,
2140                 image_metadata=metadata)
2141
2142             if not image_settings.ramdisk_image_settings or not \
2143                     image_settings.kernel_image_settings:
2144                 logger.warn(
2145                     '3 Part image will not be tested. Image metadata has '
2146                     'overridden this functionality')
2147
2148             self.image_creator = OpenStackImage(self.os_creds, image_settings)
2149             self.image_creator.create()
2150
2151             # Create Flavor
2152             self.flavor_creator = OpenStackFlavor(
2153                 self.admin_os_creds,
2154                 FlavorConfig(name=guid + '-flavor-name', ram=256, disk=10,
2155                              vcpus=2, metadata=self.flavor_metadata))
2156             self.flavor_creator.create()
2157
2158             # Create Network
2159             self.network_creator = OpenStackNetwork(
2160                 self.os_creds, net_config.network_settings)
2161             self.network_creator.create()
2162
2163             self.port_settings = PortConfig(
2164                 name=guid + '-port',
2165                 network_name=net_config.network_settings.name)
2166         except Exception as e:
2167             self.tearDown()
2168             raise e
2169
2170     def tearDown(self):
2171         """
2172         Cleans the created object
2173         """
2174         if self.inst_creator:
2175             try:
2176                 self.inst_creator.clean()
2177             except Exception as e:
2178                 logger.error(
2179                     'Unexpected exception cleaning VM instance with message -'
2180                     ' %s', e)
2181
2182         if self.flavor_creator:
2183             try:
2184                 self.flavor_creator.clean()
2185             except Exception as e:
2186                 logger.error(
2187                     'Unexpected exception cleaning flavor with message - %s',
2188                     e)
2189
2190         if self.network_creator:
2191             try:
2192                 self.network_creator.clean()
2193             except Exception as e:
2194                 logger.error(
2195                     'Unexpected exception cleaning network with message - %s',
2196                     e)
2197
2198         if self.image_creator and not self.image_creator.image_settings.exists:
2199             try:
2200                 self.image_creator.clean()
2201             except Exception as e:
2202                 logger.error(
2203                     'Unexpected exception cleaning image with message - %s', e)
2204
2205         super(self.__class__, self).__clean__()
2206
2207     def test_create_instance_from_three_part_image(self):
2208         """
2209         Tests the creation of an OpenStack instance from a 3-part image.
2210         """
2211         instance_settings = VmInstanceConfig(
2212             name=self.vm_inst_name,
2213             flavor=self.flavor_creator.flavor_settings.name,
2214             port_settings=[self.port_settings])
2215
2216         # The last created image is the main image from which we create the
2217         # instance
2218         self.inst_creator = OpenStackVmInstance(
2219             self.os_creds, instance_settings,
2220             self.image_creator.image_settings)
2221
2222         vm_inst = self.inst_creator.create()
2223         self.assertIsNotNone(vm_inst)
2224         self.assertTrue(self.inst_creator.vm_active(block=True))
2225
2226
2227 class CreateInstanceMockOfflineTests(OSComponentTestCase):
2228     """
2229     Tests the custom image_metadata that can be set by clients for handling
2230     images differently than the default behavior of the existing tests
2231     primarily for offline testing
2232     """
2233
2234     def setUp(self):
2235         """
2236         Instantiates the CreateImage object that is responsible for downloading
2237         and creating an OS image file within OpenStack
2238         """
2239         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2240
2241         self.tmpDir = 'tmp/' + str(self.guid)
2242         if not os.path.exists(self.tmpDir):
2243             os.makedirs(self.tmpDir)
2244
2245         self.image_name = self.guid + '-image'
2246         self.vm_inst_name = self.guid + '-inst'
2247         self.port_1_name = self.guid + 'port-1'
2248
2249         # Initialize for tearDown()
2250         self.image_creator = None
2251         self.network_creator = None
2252         self.flavor_creator = None
2253         self.inst_creator = None
2254
2255         self.priv_net_config = openstack_tests.get_priv_net_config(
2256             net_name=self.guid + '-priv-net',
2257             subnet_name=self.guid + '-priv-subnet')
2258         self.port_settings = PortConfig(
2259             name=self.port_1_name,
2260             network_name=self.priv_net_config.network_settings.name)
2261
2262         try:
2263             # Download image file
2264             self.image_file = file_utils.download(
2265                 openstack_tests.CIRROS_DEFAULT_IMAGE_URL, self.tmpDir)
2266
2267             # Create Network
2268             self.network_creator = OpenStackNetwork(
2269                 self.os_creds, self.priv_net_config.network_settings)
2270             self.network_creator.create()
2271
2272             # Create Flavor
2273             self.flavor_creator = OpenStackFlavor(
2274                 self.os_creds,
2275                 FlavorConfig(
2276                     name=self.guid + '-flavor-name', ram=256, disk=10,
2277                     vcpus=1))
2278             self.flavor_creator.create()
2279         except Exception as e:
2280             self.tearDown()
2281             raise e
2282
2283     def tearDown(self):
2284         """
2285         Cleans the created object
2286         """
2287         if self.inst_creator:
2288             try:
2289                 self.inst_creator.clean()
2290             except Exception as e:
2291                 logger.error(
2292                     'Unexpected exception cleaning VM instance with message - '
2293                     '%s', e)
2294
2295         if self.network_creator:
2296             try:
2297                 self.network_creator.clean()
2298             except Exception as e:
2299                 logger.error(
2300                     'Unexpected exception cleaning network with message - %s',
2301                     e)
2302
2303         if self.flavor_creator:
2304             try:
2305                 self.flavor_creator.clean()
2306             except Exception as e:
2307                 logger.error(
2308                     'Unexpected exception cleaning flavor with message - %s',
2309                     e)
2310
2311         if self.image_creator:
2312             try:
2313                 self.image_creator.clean()
2314             except Exception as e:
2315                 logger.error(
2316                     'Unexpected exception cleaning image with message - %s', e)
2317
2318         if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir):
2319             shutil.rmtree(self.tmpDir)
2320
2321         super(self.__class__, self).__clean__()
2322
2323     def test_inst_from_file_image_simple_flat(self):
2324         """
2325         Creates a VM instance from a locally sourced file image using simply
2326         the 'disk_file' attribute vs. using the 'config' option which
2327         completely overrides all image settings
2328         :return: 
2329         """
2330         metadata = {'disk_file': self.image_file.name}
2331
2332         os_image_settings = openstack_tests.cirros_image_settings(
2333             name=self.image_name, image_metadata=metadata)
2334         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2335         self.assertEqual(openstack_tests.CIRROS_USER,
2336                          os_image_settings.image_user)
2337         self.assertIsNone(os_image_settings.url)
2338         self.assertFalse(os_image_settings.exists)
2339         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2340                          os_image_settings.format)
2341
2342         self.assertIsNone(os_image_settings.kernel_image_settings)
2343         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2344
2345         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2346         self.image_creator.create()
2347
2348         instance_settings = VmInstanceConfig(
2349             name=self.vm_inst_name,
2350             flavor=self.flavor_creator.flavor_settings.name,
2351             port_settings=[self.port_settings])
2352         self.inst_creator = OpenStackVmInstance(
2353             self.os_creds, instance_settings,
2354             self.image_creator.image_settings)
2355         self.inst_creator.create()
2356
2357         self.assertTrue(self.inst_creator.vm_active(block=True))
2358
2359     def test_inst_from_file_image_simple_nested(self):
2360         """
2361         Creates a VM instance from a locally sourced file image using simply
2362         the 'disk_file' attribute under 'cirros' vs. using the 'config' option
2363         which completely overrides all image settings
2364         :return: 
2365         """
2366         metadata = {'cirros': {'disk_file': self.image_file.name}}
2367
2368         os_image_settings = openstack_tests.cirros_image_settings(
2369             name=self.image_name, image_metadata=metadata)
2370         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2371         self.assertEqual(openstack_tests.CIRROS_USER,
2372                          os_image_settings.image_user)
2373         self.assertIsNone(os_image_settings.url)
2374         self.assertFalse(os_image_settings.exists)
2375         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2376                          os_image_settings.format)
2377
2378         self.assertIsNone(os_image_settings.kernel_image_settings)
2379         self.assertIsNone(os_image_settings.ramdisk_image_settings)
2380
2381         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2382         self.image_creator.create()
2383
2384         instance_settings = VmInstanceConfig(
2385             name=self.vm_inst_name,
2386             flavor=self.flavor_creator.flavor_settings.name,
2387             port_settings=[self.port_settings])
2388         self.inst_creator = OpenStackVmInstance(
2389             self.os_creds, instance_settings,
2390             self.image_creator.image_settings)
2391         self.inst_creator.create()
2392
2393         self.assertTrue(self.inst_creator.vm_active(block=True))
2394
2395     def test_inst_from_existing(self):
2396         """
2397         Creates a VM instance from a image creator that has been configured to
2398         use an existing image
2399         :return: 
2400         """
2401         os_image_settings = openstack_tests.cirros_image_settings(
2402             name=self.image_name)
2403         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2404         self.image_creator.create()
2405
2406         image_settings = self.image_creator.image_settings
2407         test_image_creator = OpenStackImage(
2408             self.os_creds,
2409             ImageConfig(
2410                 name=image_settings.name, image_user=image_settings.image_user,
2411                 exists=True))
2412         test_image_creator.create()
2413         self.assertEqual(self.image_creator.get_image().id,
2414                          test_image_creator.get_image().id)
2415
2416         instance_settings = VmInstanceConfig(
2417             name=self.vm_inst_name,
2418             flavor=self.flavor_creator.flavor_settings.name,
2419             port_settings=[self.port_settings])
2420         self.inst_creator = OpenStackVmInstance(
2421             self.os_creds, instance_settings,
2422             test_image_creator.image_settings)
2423         self.inst_creator.create()
2424
2425         self.assertTrue(self.inst_creator.vm_active(block=True))
2426
2427     def test_inst_from_file_image_complex(self):
2428         """
2429         Creates a VM instance from a locally sourced file image by overriding
2430         the default settings by using a dict() that can be read in by
2431         ImageSettings
2432         :return: 
2433         """
2434
2435         os_image_settings = openstack_tests.cirros_image_settings(
2436             name=self.image_name)
2437         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2438         self.image_creator.create()
2439
2440         metadata = {
2441             'cirros': {
2442                 'config': {
2443                     'name': os_image_settings.name,
2444                     'image_user': os_image_settings.image_user,
2445                     'exists': True}}}
2446         test_image_settings = openstack_tests.cirros_image_settings(
2447             image_metadata=metadata)
2448         test_image = OpenStackImage(self.os_creds, test_image_settings)
2449         test_image.create()
2450
2451         instance_settings = VmInstanceConfig(
2452             name=self.vm_inst_name,
2453             flavor=self.flavor_creator.flavor_settings.name,
2454             port_settings=[self.port_settings])
2455         self.inst_creator = OpenStackVmInstance(self.os_creds,
2456                                                 instance_settings,
2457                                                 test_image_settings)
2458         self.inst_creator.create()
2459
2460         self.assertTrue(self.inst_creator.vm_active(block=True))
2461
2462     def test_inst_from_file_3part_image_complex(self):
2463         """
2464         Creates a VM instance from a locally sourced file image by overriding
2465         the default settings by using a dict() that can be read in by
2466         ImageSettings
2467         :return: 
2468         """
2469
2470         kernel_file = file_utils.download(
2471             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2472         ramdisk_file = file_utils.download(
2473             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2474
2475         metadata = {
2476             'cirros': {
2477                 'config': {
2478                     'name': self.image_name,
2479                     'image_user': openstack_tests.CIRROS_USER,
2480                     'image_file': self.image_file.name,
2481                     'format': openstack_tests.DEFAULT_IMAGE_FORMAT,
2482                     'kernel_image_settings': {
2483                         'name': self.image_name + '-kernel',
2484                         'image_user': openstack_tests.CIRROS_USER,
2485                         'image_file': kernel_file.name,
2486                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT},
2487                     'ramdisk_image_settings': {
2488                         'name': self.image_name + '-ramdisk',
2489                         'image_user': openstack_tests.CIRROS_USER,
2490                         'image_file': ramdisk_file.name,
2491                         'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}}
2492
2493         os_image_settings = openstack_tests.cirros_image_settings(
2494             name=self.image_name, image_metadata=metadata)
2495         self.assertEqual(self.image_name, os_image_settings.name)
2496         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2497         self.assertEqual(openstack_tests.CIRROS_USER,
2498                          os_image_settings.image_user)
2499         self.assertIsNone(os_image_settings.url)
2500         self.assertFalse(os_image_settings.exists)
2501         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2502                          os_image_settings.format)
2503
2504         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2505         self.assertEqual(self.image_name + '-kernel',
2506                          os_image_settings.kernel_image_settings.name)
2507         self.assertEqual(kernel_file.name,
2508                          os_image_settings.kernel_image_settings.image_file)
2509         self.assertEqual(openstack_tests.CIRROS_USER,
2510                          os_image_settings.kernel_image_settings.image_user)
2511         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2512         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2513         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2514                          os_image_settings.kernel_image_settings.format)
2515
2516         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2517         self.assertEqual(self.image_name + '-ramdisk',
2518                          os_image_settings.ramdisk_image_settings.name)
2519         self.assertEqual(ramdisk_file.name,
2520                          os_image_settings.ramdisk_image_settings.image_file)
2521         self.assertEqual(openstack_tests.CIRROS_USER,
2522                          os_image_settings.ramdisk_image_settings.image_user)
2523         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2524         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2525         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2526                          os_image_settings.ramdisk_image_settings.format)
2527
2528         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2529         self.image_creator.create()
2530
2531         instance_settings = VmInstanceConfig(
2532             name=self.vm_inst_name,
2533             flavor=self.flavor_creator.flavor_settings.name,
2534             port_settings=[self.port_settings])
2535         self.inst_creator = OpenStackVmInstance(
2536             self.os_creds, instance_settings,
2537             self.image_creator.image_settings)
2538         self.inst_creator.create()
2539
2540         self.assertTrue(self.inst_creator.vm_active(block=True))
2541
2542     def test_inst_from_file_3part_image_simple_flat(self):
2543         """
2544         Creates a VM instance from a 3-part image locally sourced from file
2545         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2546         attributes vs. using the 'config' option which completely overrides all
2547         image settings
2548         :return: 
2549         """
2550         kernel_file = file_utils.download(
2551             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2552         ramdisk_file = file_utils.download(
2553             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2554
2555         metadata = {'disk_file': self.image_file.name,
2556                     'kernel_file': kernel_file.name,
2557                     'ramdisk_file': ramdisk_file.name}
2558
2559         os_image_settings = openstack_tests.cirros_image_settings(
2560             name=self.image_name, image_metadata=metadata)
2561
2562         self.assertEqual(self.image_name, os_image_settings.name)
2563         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2564         self.assertEqual(openstack_tests.CIRROS_USER,
2565                          os_image_settings.image_user)
2566         self.assertIsNone(os_image_settings.url)
2567         self.assertFalse(os_image_settings.exists)
2568         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2569                          os_image_settings.format)
2570
2571         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2572         self.assertEqual(self.image_name + '-kernel',
2573                          os_image_settings.kernel_image_settings.name)
2574         self.assertEqual(kernel_file.name,
2575                          os_image_settings.kernel_image_settings.image_file)
2576         self.assertEqual(openstack_tests.CIRROS_USER,
2577                          os_image_settings.kernel_image_settings.image_user)
2578         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2579         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2580         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2581                          os_image_settings.kernel_image_settings.format)
2582
2583         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2584         self.assertEqual(self.image_name + '-ramdisk',
2585                          os_image_settings.ramdisk_image_settings.name)
2586         self.assertEqual(ramdisk_file.name,
2587                          os_image_settings.ramdisk_image_settings.image_file)
2588         self.assertEqual(openstack_tests.CIRROS_USER,
2589                          os_image_settings.ramdisk_image_settings.image_user)
2590         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2591         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2592         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2593                          os_image_settings.ramdisk_image_settings.format)
2594
2595         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2596         self.image_creator.create()
2597
2598         self.assertIsNotNone(self.image_creator.get_kernel_image())
2599         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2600
2601         instance_settings = VmInstanceConfig(
2602             name=self.vm_inst_name,
2603             flavor=self.flavor_creator.flavor_settings.name,
2604             port_settings=[self.port_settings])
2605         self.inst_creator = OpenStackVmInstance(
2606             self.os_creds, instance_settings,
2607             self.image_creator.image_settings)
2608         self.inst_creator.create()
2609
2610         self.assertTrue(self.inst_creator.vm_active(block=True))
2611
2612     def test_inst_from_file_3part_image_simple_nested(self):
2613         """
2614         Creates a VM instance from a 3-part image locally sourced from file
2615         images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file'
2616         attributes under 'cirros' vs. using the 'config' option which
2617         completely overrides all image settings
2618         :return: 
2619         """
2620         kernel_file = file_utils.download(
2621             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2622         ramdisk_file = file_utils.download(
2623             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2624
2625         metadata = {'cirros': {'disk_file': self.image_file.name,
2626                                'kernel_file': kernel_file.name,
2627                                'ramdisk_file': ramdisk_file.name}}
2628
2629         os_image_settings = openstack_tests.cirros_image_settings(
2630             name=self.image_name, image_metadata=metadata)
2631
2632         self.assertEqual(self.image_name, os_image_settings.name)
2633         self.assertEqual(self.image_file.name, os_image_settings.image_file)
2634         self.assertEqual(openstack_tests.CIRROS_USER,
2635                          os_image_settings.image_user)
2636         self.assertIsNone(os_image_settings.url)
2637         self.assertFalse(os_image_settings.exists)
2638         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2639                          os_image_settings.format)
2640
2641         self.assertIsNotNone(os_image_settings.kernel_image_settings)
2642         self.assertEqual(self.image_name + '-kernel',
2643                          os_image_settings.kernel_image_settings.name)
2644         self.assertEqual(kernel_file.name,
2645                          os_image_settings.kernel_image_settings.image_file)
2646         self.assertEqual(openstack_tests.CIRROS_USER,
2647                          os_image_settings.kernel_image_settings.image_user)
2648         self.assertIsNone(os_image_settings.kernel_image_settings.url)
2649         self.assertFalse(os_image_settings.kernel_image_settings.exists)
2650         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2651                          os_image_settings.kernel_image_settings.format)
2652
2653         self.assertIsNotNone(os_image_settings.ramdisk_image_settings)
2654         self.assertEqual(self.image_name + '-ramdisk',
2655                          os_image_settings.ramdisk_image_settings.name)
2656         self.assertEqual(ramdisk_file.name,
2657                          os_image_settings.ramdisk_image_settings.image_file)
2658         self.assertEqual(openstack_tests.CIRROS_USER,
2659                          os_image_settings.ramdisk_image_settings.image_user)
2660         self.assertIsNone(os_image_settings.ramdisk_image_settings.url)
2661         self.assertFalse(os_image_settings.ramdisk_image_settings.exists)
2662         self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT,
2663                          os_image_settings.ramdisk_image_settings.format)
2664
2665         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2666         self.image_creator.create()
2667
2668         self.assertIsNotNone(self.image_creator.get_kernel_image())
2669         self.assertIsNotNone(self.image_creator.get_ramdisk_image())
2670
2671         instance_settings = VmInstanceConfig(
2672             name=self.vm_inst_name,
2673             flavor=self.flavor_creator.flavor_settings.name,
2674             port_settings=[self.port_settings])
2675         self.inst_creator = OpenStackVmInstance(
2676             self.os_creds, instance_settings,
2677             self.image_creator.image_settings)
2678         self.inst_creator.create()
2679
2680         self.assertTrue(self.inst_creator.vm_active(block=True))
2681
2682     def test_inst_from_file_3part_image_existing(self):
2683         """
2684         Creates a VM instance from a 3-part image that is existing
2685         :return: 
2686         """
2687         kernel_file = file_utils.download(
2688             openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir)
2689         ramdisk_file = file_utils.download(
2690             openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir)
2691
2692         metadata = {'cirros': {'disk_file': self.image_file.name,
2693                                'kernel_file': kernel_file.name,
2694                                'ramdisk_file': ramdisk_file.name}}
2695
2696         os_image_settings = openstack_tests.cirros_image_settings(
2697             name=self.image_name, image_metadata=metadata)
2698         self.image_creator = OpenStackImage(self.os_creds, os_image_settings)
2699         self.image_creator.create()
2700
2701         image_settings = self.image_creator.image_settings
2702         test_image_creator = OpenStackImage(
2703             self.os_creds,
2704             ImageConfig(
2705                 name=image_settings.name, image_user=image_settings.image_user,
2706                 exists=True))
2707         test_image_creator.create()
2708         self.assertEqual(self.image_creator.get_image().id,
2709                          test_image_creator.get_image().id)
2710
2711         instance_settings = VmInstanceConfig(
2712             name=self.vm_inst_name,
2713             flavor=self.flavor_creator.flavor_settings.name,
2714             port_settings=[self.port_settings])
2715         self.inst_creator = OpenStackVmInstance(
2716             self.os_creds, instance_settings,
2717             test_image_creator.image_settings)
2718         self.inst_creator.create()
2719
2720         self.assertTrue(self.inst_creator.vm_active(block=True))
2721
2722
2723 class CreateInstanceTwoNetTests(OSIntegrationTestCase):
2724     """
2725     Tests the ability of two VMs to communicate when attached to separate
2726     private networks that are tied together with a router.
2727     """
2728
2729     def setUp(self):
2730         """
2731         Instantiates the CreateImage object that is responsible for downloading
2732         and creating an OS image file within OpenStack
2733         """
2734         super(self.__class__, self).__start__()
2735
2736         cidr1 = '10.200.201.0/24'
2737         cidr2 = '10.200.202.0/24'
2738         static_gateway_ip1 = '10.200.201.1'
2739         static_gateway_ip2 = '10.200.202.1'
2740         self.ip1 = '10.200.201.5'
2741         self.ip2 = '10.200.202.5'
2742
2743         self.nova = nova_utils.nova_client(self.os_creds, self.os_session)
2744
2745         # Initialize for tearDown()
2746         self.image_creator = None
2747         self.network_creators = list()
2748         self.router_creator = None
2749         self.flavor_creator = None
2750         self.sec_grp_creator = None
2751         self.inst_creators = list()
2752
2753         self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2754         self.vm_inst1_name = self.guid + '-inst1'
2755         self.vm_inst2_name = self.guid + '-inst2'
2756         self.port_1_name = self.guid + '-vm1-port'
2757         self.port_2_name = self.guid + '-vm2-port'
2758         self.net_config_1 = NetworkConfig(
2759             name=self.guid + '-net1',
2760             subnet_settings=[
2761                 create_network.SubnetConfig(
2762                     cidr=cidr1, name=self.guid + '-subnet1',
2763                     gateway_ip=static_gateway_ip1)])
2764         self.net_config_2 = NetworkConfig(
2765             name=self.guid + '-net2',
2766             subnet_settings=[
2767                 create_network.SubnetConfig(
2768                     cidr=cidr2, name=self.guid + '-subnet2',
2769                     gateway_ip=static_gateway_ip2)])
2770
2771         image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
2772         os_image_settings = openstack_tests.cirros_image_settings(
2773             name=image_name, image_metadata=self.image_metadata)
2774
2775         try:
2776             # Create Image
2777             self.image_creator = OpenStackImage(
2778                 self.os_creds, os_image_settings)
2779             self.image_creator.create()
2780
2781             # First network is public
2782             self.network_creators.append(OpenStackNetwork(
2783                 self.os_creds, self.net_config_1))
2784
2785             # Second network is private
2786             self.network_creators.append(OpenStackNetwork(
2787                 self.os_creds, self.net_config_2))
2788             for network_creator in self.network_creators:
2789                 network_creator.create()
2790
2791             port_settings = [
2792                 PortConfig(
2793                     name=self.guid + '-router-port1',
2794                     ip_addrs=[{
2795                         'subnet_name':
2796                             self.net_config_1.subnet_settings[0].name,
2797                         'ip': static_gateway_ip1
2798                     }],
2799                     network_name=self.net_config_1.name),
2800                 PortConfig(
2801                     name=self.guid + '-router-port2',
2802                     ip_addrs=[{
2803                         'subnet_name':
2804                             self.net_config_2.subnet_settings[0].name,
2805                         'ip': static_gateway_ip2
2806                     }],
2807                     network_name=self.net_config_2.name)]
2808
2809             router_settings = RouterConfig(
2810                 name=self.guid + '-pub-router', port_settings=port_settings)
2811             self.router_creator = OpenStackRouter(
2812                 self.os_creds, router_settings)
2813             self.router_creator.create()
2814
2815             self.flavor_creator = OpenStackFlavor(
2816                 self.admin_os_creds,
2817                 FlavorConfig(name=self.guid + '-flavor-name', ram=512,
2818                              disk=10, vcpus=2,
2819                              metadata=self.flavor_metadata))
2820             self.flavor_creator.create()
2821
2822             sec_grp_name = self.guid + '-sec-grp'
2823             rule1 = SecurityGroupRuleConfig(
2824                 sec_grp_name=sec_grp_name, direction=Direction.ingress,
2825                 protocol=Protocol.icmp)
2826             self.sec_grp_creator = OpenStackSecurityGroup(
2827                 self.os_creds,
2828                 SecurityGroupConfig(
2829                     name=sec_grp_name, rule_settings=[rule1]))
2830             self.sec_grp_creator.create()
2831         except:
2832             self.tearDown()
2833             raise
2834
2835     def tearDown(self):
2836         """
2837         Cleans the created objects
2838         """
2839         for inst_creator in self.inst_creators:
2840             try:
2841                 inst_creator.clean()
2842             except Exception as e:
2843                 logger.error(
2844                     'Unexpected exception cleaning VM instance with message '
2845                     '- %s', e)
2846
2847         if self.flavor_creator:
2848             try:
2849                 self.flavor_creator.clean()
2850             except Exception as e:
2851                 logger.error(
2852                     'Unexpected exception cleaning flavor with message - %s',
2853                     e)
2854
2855         if self.router_creator:
2856             try:
2857                 self.router_creator.clean()
2858             except Exception as e:
2859                 logger.error(
2860                     'Unexpected exception cleaning router with message - %s',
2861                     e)
2862
2863         for network_creator in self.network_creators:
2864             try:
2865                 network_creator.clean()
2866             except Exception as e:
2867                 logger.error(
2868                     'Unexpected exception cleaning network with message - %s',
2869                     e)
2870
2871         if self.sec_grp_creator:
2872             try:
2873                 self.sec_grp_creator.clean()
2874             except Exception as e:
2875                 logger.error(
2876                     'Unexpected exception cleaning security group with message'
2877                     ' - %s', e)
2878
2879         if self.image_creator and not self.image_creator.image_settings.exists:
2880             try:
2881                 self.image_creator.clean()
2882             except Exception as e:
2883                 logger.error(
2884                     'Unexpected exception cleaning image with message - %s', e)
2885
2886         super(self.__class__, self).__clean__()
2887
2888     def test_ping_via_router(self):
2889         """
2890         Tests the creation of two OpenStack instances with one port on
2891         different private networks wit a router in between to ensure that they
2892         can ping
2893         through
2894         """
2895         # Create ports/NICs for instance
2896         ports_settings = []
2897         ctr = 1
2898         for network_creator in self.network_creators:
2899             ports_settings.append(PortConfig(
2900                 name=self.guid + '-port-' + str(ctr),
2901                 network_name=network_creator.network_settings.name))
2902             ctr += 1
2903
2904         # Configure instances
2905         instance1_settings = VmInstanceConfig(
2906             name=self.vm_inst1_name,
2907             flavor=self.flavor_creator.flavor_settings.name,
2908             userdata=_get_ping_userdata(self.ip2),
2909             port_settings=[PortConfig(
2910                 name=self.port_1_name,
2911                 ip_addrs=[{
2912                     'subnet_name':
2913                         self.net_config_1.subnet_settings[0].name,
2914                     'ip': self.ip1
2915                 }],
2916                 network_name=self.network_creators[0].network_settings.name)])
2917         instance2_settings = VmInstanceConfig(
2918             name=self.vm_inst2_name,
2919             flavor=self.flavor_creator.flavor_settings.name,
2920             userdata=_get_ping_userdata(self.ip1),
2921             port_settings=[PortConfig(
2922                 name=self.port_2_name,
2923                 ip_addrs=[{
2924                     'subnet_name':
2925                         self.net_config_2.subnet_settings[0].name,
2926                     'ip': self.ip2
2927                 }],
2928                 network_name=self.network_creators[1].network_settings.name)])
2929
2930         # Create instances
2931         self.inst_creators.append(OpenStackVmInstance(
2932             self.os_creds, instance1_settings,
2933             self.image_creator.image_settings))
2934         self.inst_creators.append(OpenStackVmInstance(
2935             self.os_creds, instance2_settings,
2936             self.image_creator.image_settings))
2937
2938         for inst_creator in self.inst_creators:
2939             inst_creator.create(block=True)
2940
2941         # Check for DHCP lease
2942         self.assertTrue(check_dhcp_lease(self.inst_creators[0], self.ip1))
2943         self.assertTrue(check_dhcp_lease(self.inst_creators[1], self.ip2))
2944
2945         # Effectively blocks until VM has been properly activated
2946         self.assertTrue(check_ping(self.inst_creators[0]))
2947         self.assertTrue(check_ping(self.inst_creators[1]))
2948
2949
2950 class CreateInstanceVolumeTests(OSIntegrationTestCase):
2951     """
2952     Simple instance creation with an attached volume
2953     """
2954
2955     def setUp(self):
2956         """
2957         Instantiates the CreateImage object that is responsible for downloading
2958         and creating an OS image file
2959         within OpenStack
2960         """
2961         super(self.__class__, self).__start__()
2962
2963         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
2964         self.vm_inst_name = guid + '-inst'
2965         self.nova = nova_utils.nova_client(
2966             self.os_creds, self.os_session)
2967         self.neutron = neutron_utils.neutron_client(
2968             self.os_creds, self.os_session)
2969         os_image_settings = openstack_tests.cirros_image_settings(
2970             name=guid + '-image', image_metadata=self.image_metadata)
2971
2972         net_config = openstack_tests.get_priv_net_config(
2973             net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
2974             router_name=guid + '-pub-router', external_net=self.ext_net_name,
2975             netconf_override=self.netconf_override)
2976
2977         self.volume_settings1 = VolumeConfig(
2978             name=self.__class__.__name__ + '-' + str(guid) + '-1')
2979         self.volume_settings2 = VolumeConfig(
2980             name=self.__class__.__name__ + '-' + str(guid) + '-2')
2981
2982         # Initialize for tearDown()
2983         self.image_creator = None
2984         self.flavor_creator = None
2985
2986         self.network_creator = None
2987         self.inst_creator = None
2988         self.volume_creator1 = None
2989         self.volume_creator2 = None
2990
2991         try:
2992             # Create Image
2993             self.image_creator = OpenStackImage(self.os_creds,
2994                                                 os_image_settings)
2995             self.image_creator.create()
2996
2997             # Create Flavor
2998             self.flavor_creator = OpenStackFlavor(
2999                 self.admin_os_creds,
3000                 FlavorConfig(name=guid + '-flavor-name', ram=256, disk=1,
3001                              vcpus=2, metadata=self.flavor_metadata))
3002             self.flavor_creator.create()
3003
3004             # Create Network
3005             self.network_creator = OpenStackNetwork(
3006                 self.os_creds, net_config.network_settings)
3007             self.network_creator.create()
3008
3009             self.port_settings = PortConfig(
3010                 name=guid + '-port',
3011                 network_name=net_config.network_settings.name)
3012
3013             self.volume_creator1 = OpenStackVolume(
3014                 self.os_creds, self.volume_settings1)
3015             self.volume_creator1.create(block=True)
3016
3017             self.volume_creator2 = OpenStackVolume(
3018                 self.os_creds, self.volume_settings2)
3019             self.volume_creator2.create(block=True)
3020
3021         except Exception as e:
3022             self.tearDown()
3023             raise e
3024
3025     def tearDown(self):
3026         """
3027         Cleans the created object
3028         """
3029         if self.inst_creator:
3030             try:
3031                 self.inst_creator.clean()
3032             except Exception as e:
3033                 logger.error(
3034                     'Unexpected exception cleaning VM instance with message '
3035                     '- %s', e)
3036
3037         if self.flavor_creator:
3038             try:
3039                 self.flavor_creator.clean()
3040             except Exception as e:
3041                 logger.error(
3042                     'Unexpected exception cleaning flavor with message - %s',
3043                     e)
3044
3045         if self.network_creator:
3046             try:
3047                 self.network_creator.clean()
3048             except Exception as e:
3049                 logger.error(
3050                     'Unexpected exception cleaning network with message - %s',
3051                     e)
3052
3053         if self.volume_creator2:
3054             try:
3055                 self.volume_creator2.clean()
3056             except Exception as e:
3057                 logger.error(
3058                     'Unexpected exception cleaning volume with message - %s',
3059                     e)
3060
3061         if self.volume_creator1:
3062             try:
3063                 self.volume_creator1.clean()
3064             except Exception as e:
3065                 logger.error(
3066                     'Unexpected exception cleaning volume with message - %s',
3067                     e)
3068
3069         if self.image_creator and not self.image_creator.image_settings.exists:
3070             try:
3071                 self.image_creator.clean()
3072             except Exception as e:
3073                 logger.error(
3074                     'Unexpected exception cleaning image with message - %s', e)
3075
3076         super(self.__class__, self).__clean__()
3077
3078     def test_create_instance_with_one_volume(self):
3079         """
3080         Tests the creation of an OpenStack instance with a single volume.
3081         """
3082         instance_settings = VmInstanceConfig(
3083             name=self.vm_inst_name,
3084             flavor=self.flavor_creator.flavor_settings.name,
3085             port_settings=[self.port_settings],
3086             volume_names=[self.volume_settings1.name])
3087
3088         self.inst_creator = OpenStackVmInstance(
3089             self.os_creds, instance_settings,
3090             self.image_creator.image_settings)
3091
3092         vm_inst = self.inst_creator.create(block=True)
3093         self.assertIsNotNone(nova_utils.get_server(
3094             self.nova, self.neutron, self.keystone,
3095             vm_inst_settings=instance_settings))
3096
3097         self.assertIsNotNone(vm_inst)
3098         self.assertEqual(1, len(vm_inst.volume_ids))
3099         self.assertEqual(self.volume_creator1.get_volume().id,
3100                          vm_inst.volume_ids[0]['id'])
3101
3102     def test_create_instance_with_two_volumes(self):
3103         """
3104         Tests the creation of an OpenStack instance with a single volume.
3105         """
3106         instance_settings = VmInstanceConfig(
3107             name=self.vm_inst_name,
3108             flavor=self.flavor_creator.flavor_settings.name,
3109             port_settings=[self.port_settings],
3110             volume_names=[self.volume_settings1.name,
3111                           self.volume_settings2.name])
3112
3113         self.inst_creator = OpenStackVmInstance(
3114             self.os_creds, instance_settings,
3115             self.image_creator.image_settings)
3116
3117         vm_inst = self.inst_creator.create(block=True)
3118         self.assertIsNotNone(nova_utils.get_server(
3119             self.nova, self.neutron, self.keystone,
3120             vm_inst_settings=instance_settings))
3121
3122         self.assertIsNotNone(vm_inst)
3123         self.assertEqual(2, len(vm_inst.volume_ids))
3124         self.assertEqual(self.volume_creator1.get_volume().id,
3125                          vm_inst.volume_ids[0]['id'])
3126         self.assertEqual(self.volume_creator2.get_volume().id,
3127                          vm_inst.volume_ids[1]['id'])
3128
3129
3130 def check_dhcp_lease(inst_creator, ip, timeout=160):
3131     """
3132     Returns true if the expected DHCP lease has been acquired
3133     :param inst_creator: the SNAPS OpenStackVmInstance object
3134     :param ip: the IP address to look for
3135     :param timeout: how long to query for IP address
3136     :return:
3137     """
3138     found = False
3139     start_time = time.time()
3140
3141     logger.info("Looking for IP %s in the console log" % ip)
3142     full_log = ''
3143     while timeout > time.time() - start_time:
3144         output = inst_creator.get_console_output()
3145         full_log = full_log + output
3146         if re.search(ip, output):
3147             logger.info('DHCP lease obtained logged in console')
3148             found = True
3149             break
3150
3151     if not found:
3152         logger.error('Full console output -\n' + full_log)
3153     else:
3154         logger.debug('Full console output -\n' + full_log)
3155
3156     return found
3157
3158
3159 def _get_ping_userdata(test_ip):
3160     """
3161     Returns the post VM creation script to be added into the VM's userdata
3162     :param test_ip: the IP value to substitute into the script
3163     :return: the bash script contents
3164     """
3165     if test_ip:
3166         return ("#!/bin/sh\n\n"
3167                 "while true; do\n"
3168                 " ping -c 1 %s 2>&1 >/dev/null\n"
3169                 " RES=$?\n"
3170                 " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
3171                 "  echo 'vPing OK'\n"
3172                 "  break\n"
3173                 " else\n"
3174                 "  echo 'vPing KO'\n"
3175                 " fi\n"
3176                 " sleep 1\n"
3177                 "done\n" % test_ip)
3178     return None
3179
3180
3181 def check_ping(vm_creator, timeout=160):
3182     """
3183     Check for VM for ping result
3184     """
3185     tries = 0
3186
3187     while tries < timeout:
3188         time.sleep(1)
3189         p_console = vm_creator.get_console_output()
3190         if "vPing OK" in p_console:
3191             return True
3192         elif "failed to read iid from metadata" in p_console or tries > 5:
3193             return False
3194         tries += 1
3195
3196     return False