1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
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:
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
21 from snaps.config.network import SubnetConfig, NetworkConfig, PortConfig
22 from snaps.config.flavor import FlavorConfig
23 from snaps.config.keypair import KeypairConfig
24 from snaps.config.qos import Consumer
25 from snaps.domain.flavor import Flavor
26 from snaps.domain.volume import (
27 Volume, VolumeType, VolumeTypeEncryption, QoSSpec)
28 from snaps.openstack import (
29 create_image, create_network, create_router, create_flavor,
30 create_keypairs, create_instance)
31 from snaps.openstack.create_qos import Consumer
32 from snaps.openstack.create_network import OpenStackNetwork
33 from snaps.openstack.create_security_group import (
34 SecurityGroupRuleSettings, Direction, Protocol, OpenStackSecurityGroup,
35 SecurityGroupSettings)
36 from snaps.openstack.tests import openstack_tests
37 from snaps.openstack.tests.os_source_file_test import OSComponentTestCase
38 from snaps.openstack.utils import (
39 neutron_utils, settings_utils, nova_utils, glance_utils)
41 __author__ = 'spisarski'
43 logger = logging.getLogger('nova_utils_tests')
46 class SettingsUtilsNetworkingTests(OSComponentTestCase):
48 Tests the ability to reverse engineer NetworkConfig objects from existing
49 networks deployed to OpenStack
54 Instantiates OpenStack instances that cannot be spawned by Heat
56 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
57 self.network_name = guid + '-net'
58 self.subnet_name = guid + '-subnet'
59 self.net_creator = None
60 self.neutron = neutron_utils.neutron_client(self.os_creds)
64 Cleans the image and downloaded image file
68 self.net_creator.clean()
72 def test_derive_net_settings_no_subnet(self):
74 Validates the utility function settings_utils#create_network_config
75 returns an acceptable NetworkConfig object and ensures that the
76 new settings object will not cause the new OpenStackNetwork instance
77 to create another network
79 net_settings = NetworkConfig(name=self.network_name)
80 self.net_creator = OpenStackNetwork(self.os_creds, net_settings)
81 network = self.net_creator.create()
83 derived_settings = settings_utils.create_network_config(
84 self.neutron, network)
86 self.assertIsNotNone(derived_settings)
87 self.assertEqual(net_settings.name, derived_settings.name)
88 self.assertEqual(net_settings.admin_state_up,
89 derived_settings.admin_state_up)
90 self.assertEqual(net_settings.external, derived_settings.external)
91 self.assertEqual(len(net_settings.subnet_settings),
92 len(derived_settings.subnet_settings))
94 net_creator = OpenStackNetwork(self.os_creds, derived_settings)
95 derived_network = net_creator.create()
97 self.assertEqual(network, derived_network)
99 def test_derive_net_settings_two_subnets(self):
101 Validates the utility function settings_utils#create_network_config
102 returns an acceptable NetworkConfig object
104 subnet_settings = list()
105 subnet_settings.append(SubnetConfig(name='sub1', cidr='10.0.0.0/24'))
106 subnet_settings.append(SubnetConfig(name='sub2', cidr='10.0.1.0/24'))
107 net_settings = NetworkConfig(
108 name=self.network_name, subnet_settings=subnet_settings)
109 self.net_creator = OpenStackNetwork(self.os_creds, net_settings)
110 network = self.net_creator.create()
112 derived_settings = settings_utils.create_network_config(
113 self.neutron, network)
115 self.assertIsNotNone(derived_settings)
116 self.assertEqual(net_settings.name, derived_settings.name)
117 self.assertEqual(net_settings.admin_state_up,
118 derived_settings.admin_state_up)
119 self.assertEqual(net_settings.external, derived_settings.external)
120 self.assertEqual(len(net_settings.subnet_settings),
121 len(derived_settings.subnet_settings))
123 # Validate the first subnet
124 orig_sub1 = net_settings.subnet_settings[0]
126 for derived_sub in derived_settings.subnet_settings:
127 if orig_sub1.name == derived_sub.name:
128 self.assertEqual(orig_sub1.cidr, derived_sub.cidr)
131 self.assertTrue(found)
133 # Validate the second subnet
134 orig_sub2 = net_settings.subnet_settings[1]
136 for derived_sub in derived_settings.subnet_settings:
137 if orig_sub2.name == derived_sub.name:
138 self.assertEqual(orig_sub2.cidr, derived_sub.cidr)
139 self.assertEqual(orig_sub2.ip_version, derived_sub.ip_version)
142 self.assertTrue(found)
145 class SettingsUtilsVmInstTests(OSComponentTestCase):
147 Tests the ability to reverse engineer VmInstanceSettings objects from
148 existing VMs/servers deployed to OpenStack
153 Instantiates the CreateImage object that is responsible for downloading
154 and creating an OS image file within OpenStack
156 self.nova = nova_utils.nova_client(self.os_creds)
157 self.glance = glance_utils.glance_client(self.os_creds)
158 self.neutron = neutron_utils.neutron_client(self.os_creds)
160 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
161 self.keypair_priv_filepath = 'tmp/' + guid
162 self.keypair_pub_filepath = self.keypair_priv_filepath + '.pub'
163 self.keypair_name = guid + '-kp'
164 self.vm_inst_name = guid + '-inst'
165 self.test_file_local_path = 'tmp/' + guid + '-hello.txt'
166 self.port_1_name = guid + '-port-1'
167 self.port_2_name = guid + '-port-2'
168 self.floating_ip_name = guid + 'fip1'
170 # Setup members to cleanup just in case they don't get created
171 self.inst_creator = None
172 self.keypair_creator = None
173 self.sec_grp_creator = None
174 self.flavor_creator = None
175 self.router_creator = None
176 self.network_creator = None
177 self.image_creator = None
181 os_image_settings = openstack_tests.cirros_image_settings(
182 name=guid + '-' + '-image',
183 image_metadata=self.image_metadata)
184 self.image_creator = create_image.OpenStackImage(self.os_creds,
186 self.image_creator.create()
188 # First network is public
189 self.pub_net_config = openstack_tests.get_pub_net_config(
190 net_name=guid + '-pub-net', subnet_name=guid + '-pub-subnet',
191 router_name=guid + '-pub-router',
192 external_net=self.ext_net_name)
194 self.network_creator = create_network.OpenStackNetwork(
195 self.os_creds, self.pub_net_config.network_settings)
196 self.network_creator.create()
199 self.router_creator = create_router.OpenStackRouter(
200 self.os_creds, self.pub_net_config.router_settings)
201 self.router_creator.create()
204 self.flavor_creator = create_flavor.OpenStackFlavor(
207 name=guid + '-flavor-name', ram=256, disk=1, vcpus=1))
208 self.flavor_creator.create()
211 self.keypair_creator = create_keypairs.OpenStackKeypair(
212 self.os_creds, KeypairConfig(
213 name=self.keypair_name,
214 public_filepath=self.keypair_pub_filepath,
215 private_filepath=self.keypair_priv_filepath))
216 self.keypair_creator.create()
218 # Create Security Group
219 sec_grp_name = guid + '-sec-grp'
220 rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
221 direction=Direction.ingress,
222 protocol=Protocol.icmp)
223 rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name,
224 direction=Direction.ingress,
225 protocol=Protocol.tcp,
228 self.sec_grp_creator = OpenStackSecurityGroup(
230 SecurityGroupSettings(name=sec_grp_name,
231 rule_settings=[rule1, rule2]))
232 self.sec_grp_creator.create()
235 ports_settings = list()
236 ports_settings.append(
238 name=self.port_1_name,
239 network_name=self.pub_net_config.network_settings.name))
241 instance_settings = create_instance.VmInstanceSettings(
242 name=self.vm_inst_name,
243 flavor=self.flavor_creator.flavor_settings.name,
244 port_settings=ports_settings,
245 floating_ip_settings=[create_instance.FloatingIpSettings(
246 name=self.floating_ip_name, port_name=self.port_1_name,
247 router_name=self.pub_net_config.router_settings.name)])
249 self.inst_creator = create_instance.OpenStackVmInstance(
250 self.os_creds, instance_settings,
251 self.image_creator.image_settings,
252 keypair_settings=self.keypair_creator.keypair_settings)
259 Cleans the created objects
261 if self.inst_creator:
263 self.inst_creator.clean()
267 if self.sec_grp_creator:
269 self.sec_grp_creator.clean()
273 if self.keypair_creator:
275 self.keypair_creator.clean()
279 if self.flavor_creator:
281 self.flavor_creator.clean()
285 if os.path.isfile(self.keypair_pub_filepath):
287 os.remove(self.keypair_pub_filepath)
291 if os.path.isfile(self.keypair_priv_filepath):
293 os.remove(self.keypair_priv_filepath)
297 if self.router_creator:
299 self.router_creator.clean()
303 if self.network_creator:
305 self.network_creator.clean()
309 if self.image_creator and not self.image_creator.image_settings.exists:
311 self.image_creator.clean()
315 if os.path.isfile(self.test_file_local_path):
316 os.remove(self.test_file_local_path)
318 # super(self.__class__, self).__clean__()
320 def test_derive_vm_inst_settings(self):
322 Validates the utility function settings_utils#create_vm_inst_settings
323 returns an acceptable VmInstanceSettings object
325 self.inst_creator.create(block=True)
327 server = nova_utils.get_server(
328 self.nova, vm_inst_settings=self.inst_creator.instance_settings)
329 derived_vm_settings = settings_utils.create_vm_inst_settings(
330 self.nova, self.neutron, server)
331 self.assertIsNotNone(derived_vm_settings)
332 self.assertIsNotNone(derived_vm_settings.port_settings)
333 self.assertIsNotNone(derived_vm_settings.floating_ip_settings)
335 def test_derive_image_settings(self):
337 Validates the utility function settings_utils#create_image_settings
338 returns an acceptable ImageConfig object
340 self.inst_creator.create(block=True)
342 server = nova_utils.get_server(
343 self.nova, vm_inst_settings=self.inst_creator.instance_settings)
344 derived_image_settings = settings_utils.determine_image_config(
345 self.glance, server, [self.image_creator.image_settings])
346 self.assertIsNotNone(derived_image_settings)
347 self.assertEqual(self.image_creator.image_settings.name,
348 derived_image_settings.name)
351 class SettingsUtilsUnitTests(unittest.TestCase):
353 Exercises the settings_utils.py functions around volumes
356 def test_vol_settings_from_vol(self):
358 name='vol-name', volume_id='vol-id', description='desc', size=99,
359 vol_type='vol-type', availability_zone='zone1', multi_attach=True)
360 settings = settings_utils.create_volume_config(volume)
361 self.assertEqual(volume.name, settings.name)
362 self.assertEqual(volume.description, settings.description)
363 self.assertEqual(volume.size, settings.size)
364 self.assertEqual(volume.type, settings.type_name)
365 self.assertEqual(volume.availability_zone, settings.availability_zone)
366 self.assertEqual(volume.multi_attach, settings.multi_attach)
368 def test_vol_type_settings_from_vol(self):
369 encryption = VolumeTypeEncryption(
370 volume_encryption_id='vol-encrypt-id', volume_type_id='vol-typ-id',
371 control_location='front-end', provider='FooClass', cipher='1',
373 qos_spec = QoSSpec(name='qos-spec-name', spec_id='qos-spec-id',
374 consumer=Consumer.back_end)
375 volume_type = VolumeType(
376 name='vol-type-name', volume_type_id='vol-type-id', public=True,
377 encryption=encryption, qos_spec=qos_spec)
379 settings = settings_utils.create_volume_type_config(volume_type)
380 self.assertEqual(volume_type.name, settings.name)
381 self.assertEqual(volume_type.public, settings.public)
383 encrypt_settings = settings.encryption
384 self.assertIsNotNone(encrypt_settings)
385 self.assertEqual(encryption.control_location,
386 encrypt_settings.control_location.value)
387 self.assertEqual(encryption.cipher, encrypt_settings.cipher)
388 self.assertEqual(encryption.key_size, encrypt_settings.key_size)
390 self.assertEqual(qos_spec.name, settings.qos_spec_name)
392 def test_flavor_settings_from_flavor(self):
394 name='flavor-name', flavor_id='flavor-id', ram=99, disk=101,
395 vcpus=9, ephemeral=3, swap=5, rxtx_factor=7, is_public=False)
396 settings = settings_utils.create_flavor_config(flavor)
397 self.assertEqual(flavor.name, settings.name)
398 self.assertEqual(flavor.id, settings.flavor_id)
399 self.assertEqual(flavor.ram, settings.ram)
400 self.assertEqual(flavor.disk, settings.disk)
401 self.assertEqual(flavor.vcpus, settings.vcpus)
402 self.assertEqual(flavor.ephemeral, settings.ephemeral)
403 self.assertEqual(flavor.swap, settings.swap)
404 self.assertEqual(flavor.rxtx_factor, settings.rxtx_factor)
405 self.assertEqual(flavor.is_public, settings.is_public)