1 ##############################################################################
2 # Copyright (c) 2016 Dan Radez (dradez@redhat.com) (Red Hat)
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
15 from mock import patch
16 from mock import MagicMock
17 from mock import mock_open
18 from io import StringIO
20 from apex.common import constants as con
21 from apex.common.exceptions import ApexDeployException
22 from apex.overcloud.deploy import build_sdn_env_list
23 from apex.overcloud.deploy import create_deploy_cmd
24 from apex.overcloud.deploy import prep_image
25 from apex.overcloud.deploy import make_ssh_key
26 from apex.overcloud.deploy import prep_env
27 from apex.overcloud.deploy import generate_ceph_key
28 from apex.overcloud.deploy import prep_storage_env
29 from apex.overcloud.deploy import prep_sriov_env
30 from apex.overcloud.deploy import external_network_cmds
31 from apex.overcloud.deploy import create_congress_cmds
32 from apex.overcloud.deploy import SDN_FILE_MAP
33 from apex.overcloud.deploy import get_docker_sdn_files
35 from nose.tools import (
36 assert_regexp_matches,
44 class TestOvercloudDeploy(unittest.TestCase):
47 """This method is run once for each class before any tests are run"""
50 def teardown_class(cls):
51 """This method is run once for each class _after_ all tests are run"""
54 """This method is run once before _each_ test method is executed"""
57 """This method is run once after _each_ test method is executed"""
59 def test_build_sdn_env_list(self):
60 ds = {'sdn_controller': 'opendaylight'}
61 sdn_map = {'opendaylight': 'test'}
62 res = '/usr/share/openstack-tripleo-heat-templates/environments/test'
63 assert_equal(build_sdn_env_list(ds, sdn_map), [res])
65 def test_build_sdn_env_list_dict(self):
66 ds = {'opendaylight': True,
67 'sdn_controller': None}
68 sdn_map = {'opendaylight': {}}
69 assert_equal(build_sdn_env_list(ds, sdn_map), [])
71 def test_build_sdn_env_list_tuple(self):
72 ds = {'opendaylight': 'test',
73 'sdn_controller': None}
74 sdn_map = {'opendaylight': ('test', 'test')}
75 res = '/usr/share/openstack-tripleo-heat-templates/environments/test'
76 assert_equal(build_sdn_env_list(ds, sdn_map), [res])
78 def test_build_sdn_env_list_with_string(self):
79 ds = {'sdn_controller': 'opendaylight',
81 prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
82 res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
83 os.path.join(prefix, 'neutron-opendaylight-sriov.yaml')]
84 assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
86 def test_build_sdn_env_list_with_default(self):
87 ds = {'sdn_controller': 'opendaylight',
89 prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
90 res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
91 os.path.join(prefix, 'neutron-bgpvpn-opendaylight.yaml')]
92 assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
94 @patch('apex.overcloud.deploy.prep_sriov_env')
95 @patch('apex.overcloud.deploy.prep_storage_env')
96 @patch('apex.overcloud.deploy.build_sdn_env_list')
97 @patch('builtins.open', mock_open())
98 def test_create_deploy_cmd(self, mock_sdn_list, mock_prep_storage,
100 mock_sdn_list.return_value = []
101 ds = {'deploy_options':
111 'global_params': MagicMock()}
113 ns = {'ntp': ['ntp']}
115 inv.get_node_counts.return_value = (3, 2)
117 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
118 assert_in('--ntp-server ntp', result_cmd)
119 assert_in('enable_tacker.yaml', result_cmd)
120 assert_in('enable_congress.yaml', result_cmd)
121 assert_in('enable_barometer.yaml', result_cmd)
122 assert_in('virtual-environment.yaml', result_cmd)
123 assert_in('--control-scale 3', result_cmd)
124 assert_in('--compute-scale 2', result_cmd)
126 @patch('apex.overcloud.deploy.prep_sriov_env')
127 @patch('apex.overcloud.deploy.prep_storage_env')
128 @patch('builtins.open', mock_open())
129 def test_create_deploy_cmd_containers_sdn(self, mock_prep_storage,
131 ds = {'deploy_options':
139 'sdn_controller': 'opendaylight',
141 'os_version': 'queens',
144 'global_params': MagicMock()}
146 ns = {'ntp': ['ntp']}
148 inv.get_node_counts.return_value = (3, 2)
150 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
151 assert_in('--ntp-server ntp', result_cmd)
152 assert_not_in('enable_tacker.yaml', result_cmd)
153 assert_not_in('enable_congress.yaml', result_cmd)
154 assert_not_in('enable_barometer.yaml', result_cmd)
155 assert_in('virtual-environment.yaml', result_cmd)
156 assert_in('--control-scale 3', result_cmd)
157 assert_in('--compute-scale 2', result_cmd)
158 assert_in('docker-images.yaml', result_cmd)
159 assert_in('sdn-images.yaml', result_cmd)
160 assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
161 '/docker.yaml', result_cmd)
162 assert_in('/usr/share/openstack-tripleo-heat-templates/environments/'
163 'storage-environment.yaml', result_cmd)
164 assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
165 '/services/neutron-opendaylight.yaml', result_cmd)
166 ds['deploy_options']['os_version'] = 'master'
167 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
168 assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
169 '/services/neutron-opendaylight.yaml', result_cmd)
171 @patch('apex.overcloud.deploy.prep_sriov_env')
172 @patch('apex.overcloud.deploy.prep_storage_env')
173 @patch('apex.overcloud.deploy.build_sdn_env_list')
174 @patch('builtins.open', mock_open())
175 def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
176 mock_prep_storage, mock_prep_sriov):
177 mock_sdn_list.return_value = []
178 ds = {'deploy_options': MagicMock(),
179 'global_params': MagicMock()}
180 ds['global_params'].__getitem__.side_effect = \
181 lambda i: False if i == 'ha_enabled' else MagicMock()
182 ds['deploy_options'].__getitem__.side_effect = \
183 lambda i: 'master' if i == 'os_version' else MagicMock()
184 ns = {'ntp': ['ntp']}
186 inv.get_node_counts.return_value = (3, 2)
188 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
189 assert_in('--ntp-server ntp', result_cmd)
190 assert_in('--control-scale 1', result_cmd)
191 assert_in('--compute-scale 2', result_cmd)
192 assert_in('baremetal-environment.yaml', result_cmd)
193 assert_not_in('enable_tacker.yaml', result_cmd)
194 assert_not_in('enable_congress.yaml', result_cmd)
195 assert_not_in('enable_barometer.yaml', result_cmd)
197 @patch('apex.builders.overcloud_builder.inject_opendaylight')
198 @patch('apex.overcloud.deploy.virt_utils')
199 @patch('apex.overcloud.deploy.shutil')
200 @patch('apex.overcloud.deploy.os.path')
201 @patch('builtins.open', mock_open())
202 def test_prep_image(self, mock_os_path, mock_shutil, mock_virt_utils,
204 ds_opts = {'dataplane': 'fdio',
205 'sdn_controller': 'opendaylight',
206 'odl_version': 'master',
209 ds = {'deploy_options': MagicMock(),
210 'global_params': MagicMock()}
211 ds['deploy_options'].__getitem__.side_effect = \
212 lambda i: ds_opts.get(i, MagicMock())
214 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
215 mock_virt_utils.virt_customize.assert_called()
216 mock_inject_odl.assert_called()
218 @patch('apex.overcloud.deploy.virt_utils')
219 @patch('apex.overcloud.deploy.shutil')
220 @patch('apex.overcloud.deploy.os.path')
221 @patch('builtins.open', mock_open())
222 def test_prep_image_sdn_false(self, mock_os_path, mock_shutil,
224 ds_opts = {'dataplane': 'fdio',
226 'sdn_controller': False}
227 ds = {'deploy_options': MagicMock(),
228 'global_params': MagicMock()}
229 ds['deploy_options'].__getitem__.side_effect = \
230 lambda i: ds_opts.get(i, MagicMock())
232 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
233 mock_virt_utils.virt_customize.assert_called()
235 @patch('apex.builders.overcloud_builder.inject_opendaylight')
236 @patch('apex.overcloud.deploy.virt_utils')
237 @patch('apex.overcloud.deploy.shutil')
238 @patch('apex.overcloud.deploy.os.path')
239 @patch('builtins.open', mock_open())
240 def test_prep_image_sdn_odl(self, mock_os_path, mock_shutil,
241 mock_virt_utils, mock_inject_odl):
242 ds_opts = {'dataplane': 'ovs',
243 'sdn_controller': 'opendaylight',
246 'odl_version': con.DEFAULT_ODL_VERSION,
247 'odl_vpp_netvirt': True}
248 ds = {'deploy_options': MagicMock(),
249 'global_params': MagicMock()}
250 ds['deploy_options'].__getitem__.side_effect = \
251 lambda i: ds_opts.get(i, MagicMock())
252 ds['deploy_options'].__contains__.side_effect = \
253 lambda i: True if i in ds_opts else MagicMock()
255 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
256 mock_virt_utils.virt_customize.assert_called()
257 mock_inject_odl.assert_called()
259 @patch('apex.overcloud.deploy.c_builder')
260 @patch('apex.overcloud.deploy.oc_builder')
261 @patch('apex.overcloud.deploy.virt_utils')
262 @patch('apex.overcloud.deploy.shutil')
263 @patch('apex.overcloud.deploy.os.path')
264 @patch('builtins.open', mock_open())
265 def test_prep_image_sdn_odl_upstream_containers_patches(
266 self, mock_os_path, mock_shutil, mock_virt_utils,
267 mock_oc_builder, mock_c_builder):
268 ds_opts = {'dataplane': 'ovs',
269 'sdn_controller': 'opendaylight',
270 'odl_version': con.DEFAULT_ODL_VERSION,
271 'odl_vpp_netvirt': True}
272 ds = {'deploy_options': MagicMock(),
273 'global_params': MagicMock()}
274 ds['deploy_options'].__getitem__.side_effect = \
275 lambda i: ds_opts.get(i, MagicMock())
276 ds['deploy_options'].__contains__.side_effect = \
277 lambda i: True if i in ds_opts else MagicMock()
279 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
280 patches = ['dummy_nova_patch']
281 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
282 docker_tag='latest', patches=patches)
283 mock_oc_builder.inject_opendaylight.assert_called()
284 mock_virt_utils.virt_customize.assert_called()
285 mock_c_builder.add_upstream_patches.assert_called()
286 self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
288 @patch('apex.overcloud.deploy.c_builder')
289 @patch('apex.overcloud.deploy.oc_builder')
290 @patch('apex.overcloud.deploy.virt_utils')
291 @patch('apex.overcloud.deploy.shutil')
292 @patch('apex.overcloud.deploy.os.path')
293 @patch('builtins.open', mock_open())
294 def test_prep_image_nosdn_upstream_containers_patches(
295 self, mock_os_path, mock_shutil, mock_virt_utils,
296 mock_oc_builder, mock_c_builder):
297 ds_opts = {'dataplane': 'ovs',
298 'sdn_controller': False,
299 'odl_version': con.DEFAULT_ODL_VERSION,
300 'odl_vpp_netvirt': False}
301 ds = {'deploy_options': MagicMock(),
302 'global_params': MagicMock()}
303 ds['deploy_options'].__getitem__.side_effect = \
304 lambda i: ds_opts.get(i, MagicMock())
305 ds['deploy_options'].__contains__.side_effect = \
306 lambda i: True if i in ds_opts else MagicMock()
308 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
309 patches = ['dummy_nova_patch']
310 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
311 docker_tag='latest', patches=patches)
312 mock_virt_utils.virt_customize.assert_called()
313 mock_c_builder.add_upstream_patches.assert_called()
314 self.assertListEqual(sorted(rv), ['nova-api'])
316 @patch('apex.overcloud.deploy.oc_builder')
317 @patch('apex.overcloud.deploy.virt_utils')
318 @patch('apex.overcloud.deploy.shutil')
319 @patch('apex.overcloud.deploy.os.path')
320 @patch('builtins.open', mock_open())
321 def test_prep_image_sdn_odl_not_def(self, mock_os_path,
322 mock_shutil, mock_virt_utils,
324 ds_opts = {'dataplane': 'ovs',
325 'sdn_controller': 'opendaylight',
326 'odl_version': 'uncommon'}
327 ds = {'deploy_options': MagicMock(),
328 'global_params': MagicMock()}
329 ds['deploy_options'].__getitem__.side_effect = \
330 lambda i: ds_opts.get(i, MagicMock())
332 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
333 mock_virt_utils.virt_customize.assert_called()
334 mock_oc_builder.inject_opendaylight.assert_called()
336 @patch('apex.overcloud.deploy.virt_utils')
337 @patch('apex.overcloud.deploy.shutil')
338 @patch('apex.overcloud.deploy.os.path')
339 @patch('builtins.open', mock_open())
340 def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
342 ds_opts = {'dataplane': 'ovs',
345 'sdn_controller': 'ovn'}
346 ds = {'deploy_options': MagicMock(),
347 'global_params': MagicMock()}
348 ds['deploy_options'].__getitem__.side_effect = \
349 lambda i: ds_opts.get(i, MagicMock())
351 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
352 mock_virt_utils.virt_customize.assert_called()
354 @patch('apex.builders.overcloud_builder.inject_quagga')
355 @patch('apex.builders.overcloud_builder.inject_opendaylight')
356 @patch('apex.overcloud.deploy.virt_utils')
357 @patch('apex.overcloud.deploy.shutil')
358 @patch('apex.overcloud.deploy.os.path')
359 @patch('builtins.open', mock_open())
360 def test_prep_image_sdn_odl_vpn(self, mock_os_path, mock_shutil,
361 mock_virt_utils, mock_inject_odl,
363 ds_opts = {'dataplane': 'ovs',
364 'sdn_controller': 'opendaylight',
367 'odl_version': con.DEFAULT_ODL_VERSION,
368 'odl_vpp_netvirt': True}
369 ds = {'deploy_options': MagicMock(),
370 'global_params': MagicMock()}
371 ds['deploy_options'].__getitem__.side_effect = \
372 lambda i: ds_opts.get(i, MagicMock())
373 ds['deploy_options'].__contains__.side_effect = \
374 lambda i: True if i in ds_opts else MagicMock()
376 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
377 mock_virt_utils.virt_customize.assert_called()
378 mock_inject_odl.assert_called()
379 mock_inject_quagga.assert_called()
381 @patch('apex.builders.overcloud_builder.inject_ovs_nsh')
382 @patch('apex.builders.overcloud_builder.inject_opendaylight')
383 @patch('apex.overcloud.deploy.virt_utils')
384 @patch('apex.overcloud.deploy.shutil')
385 @patch('apex.overcloud.deploy.os.path')
386 @patch('builtins.open', mock_open())
387 def test_prep_image_sdn_odl_sfc(self, mock_os_path, mock_shutil,
388 mock_virt_utils, mock_inject_odl,
389 mock_inject_ovs_nsh):
390 ds_opts = {'dataplane': 'ovs',
391 'sdn_controller': 'opendaylight',
394 'odl_version': con.DEFAULT_ODL_VERSION,
395 'odl_vpp_netvirt': True}
396 ds = {'deploy_options': MagicMock(),
397 'global_params': MagicMock()}
398 ds['deploy_options'].__getitem__.side_effect = \
399 lambda i: ds_opts.get(i, MagicMock())
400 ds['deploy_options'].__contains__.side_effect = \
401 lambda i: True if i in ds_opts else MagicMock()
403 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
404 mock_virt_utils.virt_customize.assert_called()
405 mock_inject_odl.assert_called()
406 mock_inject_ovs_nsh.assert_called()
408 @patch('apex.overcloud.deploy.os.path.isfile')
409 def test_prep_image_no_image(self, mock_isfile):
410 mock_isfile.return_value = False
411 assert_raises(ApexDeployException, prep_image,
412 {}, {}, 'undercloud.qcow2', '/tmp')
414 def test_make_ssh_key(self):
415 priv, pub = make_ssh_key()
416 assert_in('-----BEGIN PRIVATE KEY-----', priv)
417 assert_in('ssh-rsa', pub)
419 @patch('apex.overcloud.deploy.yaml')
420 @patch('apex.overcloud.deploy.fileinput')
421 @patch('apex.overcloud.deploy.shutil')
422 @patch('builtins.open', mock_open())
423 def test_prep_env(self, mock_shutil, mock_fileinput, mock_yaml):
424 mock_fileinput.input.return_value = \
425 ['CloudDomain', 'replace_private_key', 'replace_public_key',
426 'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
427 'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
428 'ComputeExtraConfigPre', 'resource_registry',
429 'NovaSchedulerDefaultFilters']
430 mock_yaml.safe_load.return_value = {
431 'parameter_defaults': {
432 'ControllerServices': [1, 2, 3],
433 'ComputeServices': [3, 4, 5]
435 ds = {'global_params': {'ha_enabled': False},
437 {'sdn_controller': 'opendaylight',
438 'odl_vpp_routing_node': 'test',
439 'dataplane': 'ovs_dpdk',
441 'performance': {'Compute': {'vpp': {'main-core': 'test',
442 'corelist-workers': 'test'},
443 'ovs': {'dpdk_cores': 'test'},
444 'kernel': {'test': 'test'}},
445 'Controller': {'vpp': 'test'}}}}
446 ns_dict = {'domain_name': 'test.domain',
449 {'nic_mapping': {'controller':
450 {'members': ['tenant_nic']},
452 {'members': ['tenant_nic']}}},
454 [{'nic_mapping': {'controller':
455 {'members': ['ext_nic']},
457 {'members': ['ext_nic']}}}]}}
459 inv.get_node_counts.return_value = (1, 0)
462 saved_stdout = sys.stdout
466 ns.enabled_network_list = ['external', 'tenant']
467 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
469 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
470 output = out.getvalue().strip()
471 assert_in('CloudDomain: test.domain', output)
472 assert_in('ssh-rsa', output)
473 assert_in('ComputeKernelArgs: \'test=test \'', output)
474 assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
475 mock_yaml.safe_dump.assert_called_with(
476 {'parameter_defaults': {
477 'ControllerServices': [1, 2, 3, 4, 5],
479 mock.ANY, default_flow_style=False
483 sys.stdout = saved_stdout
485 @patch('apex.overcloud.deploy.fileinput')
486 @patch('apex.overcloud.deploy.shutil')
487 def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
488 mock_fileinput.input.return_value = \
489 ['NeutronVPPAgentPhysnets']
490 ds = {'global_params': {'ha_enabled': False},
492 {'sdn_controller': False,
495 'performance': {'Compute': {},
497 ns_dict = {'domain_name': 'test.domain',
500 {'nic_mapping': {'controller':
501 {'members': ['tenant_nic']},
503 {'members': ['tenant_nic']}}},
505 [{'nic_mapping': {'controller':
506 {'members': ['ext_nic']},
508 {'members': ['ext_nic']}}}]}}
510 inv.get_node_counts.return_value = (3, 2)
513 saved_stdout = sys.stdout
517 ns.enabled_network_list = ['external', 'tenant']
518 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
520 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
521 output = out.getvalue().strip()
522 assert_in('NeutronVPPAgentPhysnets: '
523 '\'datacentre:tenant_nic,external:tap0\'',
525 assert_in('NeutronVPPAgentPhysnets', output)
528 sys.stdout = saved_stdout
530 @patch('apex.overcloud.deploy.fileinput')
531 @patch('apex.overcloud.deploy.shutil')
532 def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
533 mock_fileinput.input.return_value = \
534 ['OS::TripleO::Services::NeutronDhcpAgent',
535 'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
536 ds = {'global_params': {'ha_enabled': False},
538 {'sdn_controller': 'opendaylight',
542 ns_dict = {'domain_name': 'test.domain',
545 {'nic_mapping': {'controller':
546 {'members': ['tenant_nic']},
548 {'members': ['tenant_nic']}}},
550 [{'nic_mapping': {'controller':
551 {'members': ['ext_nic']},
553 {'members': ['ext_nic']}}}]}}
555 inv.get_node_counts.return_value = (3, 2)
558 saved_stdout = sys.stdout
562 ns.enabled_network_list = ['external', 'tenant']
563 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
565 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
566 output = out.getvalue().strip()
567 assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
570 sys.stdout = saved_stdout
572 @patch('apex.overcloud.deploy.fileinput')
573 @patch('apex.overcloud.deploy.shutil')
574 def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
575 mock_fileinput.input.return_value = \
576 ['NeutronNetworkVLANRanges',
577 'NeutronNetworkType', 'NeutronBridgeMappings']
578 ds = {'global_params': {'ha_enabled': False},
580 {'sdn_controller': False,
584 ns_dict = {'domain_name': 'test.domain',
587 {'nic_mapping': {'controller':
588 {'members': ['tenant_nic']},
590 {'members': ['tenant_nic']}},
591 'segmentation_type': 'vlan',
592 'overlay_id_range': 'vlan:500:600'
595 [{'nic_mapping': {'controller':
596 {'members': ['ext_nic']},
598 {'members': ['ext_nic']}}}]}}
600 inv.get_node_counts.return_value = (3, 2)
603 saved_stdout = sys.stdout
607 ns.enabled_network_list = ['external', 'tenant']
608 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
610 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
611 output = out.getvalue().strip()
612 assert_in('NeutronNetworkVLANRanges: '
613 'vlan:500:600,datacentre:1:1000', output)
614 assert_in('NeutronNetworkType: vlan', output)
615 assert_in('NeutronBridgeMappings: '
616 'vlan:br-vlan,datacentre:br-ex', output)
617 assert_not_in('OpenDaylightProviderMappings', output)
620 sys.stdout = saved_stdout
622 @patch('apex.overcloud.deploy.fileinput')
623 @patch('apex.overcloud.deploy.shutil')
624 def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
625 mock_fileinput.input.return_value = \
626 ['NeutronNetworkVLANRanges',
627 'NeutronNetworkType',
628 'NeutronBridgeMappings',
629 'OpenDaylightProviderMappings']
630 ds = {'global_params': {'ha_enabled': False},
632 {'sdn_controller': 'opendaylight',
636 ns_dict = {'domain_name': 'test.domain',
639 {'nic_mapping': {'controller':
640 {'members': ['tenant_nic']},
642 {'members': ['tenant_nic']}},
643 'segmentation_type': 'vlan',
644 'overlay_id_range': 'vlan:500:600'
647 [{'nic_mapping': {'controller':
648 {'members': ['ext_nic']},
650 {'members': ['ext_nic']}}}]}}
652 inv.get_node_counts.return_value = (3, 2)
655 saved_stdout = sys.stdout
659 ns.enabled_network_list = ['external', 'tenant']
660 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
662 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
663 output = out.getvalue().strip()
664 assert_in('NeutronNetworkVLANRanges: '
665 'vlan:500:600,datacentre:1:1000', output)
666 assert_in('NeutronNetworkType: vlan', output)
667 assert_in('NeutronBridgeMappings: '
668 'vlan:br-vlan,datacentre:br-ex', output)
669 assert_in('OpenDaylightProviderMappings: '
670 'vlan:br-vlan,datacentre:br-ex', output)
673 sys.stdout = saved_stdout
675 def test_generate_ceph_key(self):
676 assert_equal(len(generate_ceph_key()), 40)
678 @patch('apex.overcloud.deploy.generate_ceph_key')
679 @patch('apex.overcloud.deploy.fileinput')
680 @patch('apex.overcloud.deploy.os.path.isfile')
681 @patch('builtins.open', mock_open())
682 def test_prep_storage_env(self, mock_isfile, mock_fileinput,
684 mock_fileinput.input.return_value = \
685 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
686 ds = {'deploy_options': {
687 'ceph_device': '/dev/sdx',
691 prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
693 @patch('apex.overcloud.deploy.utils.edit_tht_env')
694 @patch('apex.overcloud.deploy.generate_ceph_key')
695 @patch('apex.overcloud.deploy.fileinput')
696 @patch('apex.overcloud.deploy.os.path.isfile')
697 @patch('builtins.open', mock_open())
698 def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
699 mock_ceph_key, mock_edit_tht):
700 mock_fileinput.input.return_value = \
701 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
702 ds = {'deploy_options': {
703 'ceph_device': '/dev/sdx',
705 'os_version': 'master'
706 }, 'global_params': {'ha_enabled': False}}
707 ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
708 {'ip': '192.0.2.1'}}}
710 prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
712 'CephPoolDefaultSize': 2,
713 'CephAnsibleExtraConfig': {
714 'centos_package_dependencies': [],
715 'ceph_osd_docker_memory_limit': '1g',
716 'ceph_mds_docker_memory_limit': '1g'
718 'CephPoolDefaultPgNum': 32,
719 'CephAnsibleDisksConfig': {
720 'devices': ['/dev/sdx'],
722 'osd_scenario': 'collocated'
725 mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
726 'parameter_defaults',
729 @patch('apex.overcloud.deploy.os.path.isfile')
730 @patch('builtins.open', mock_open())
731 def test_prep_storage_env_raises(self, mock_isfile):
732 mock_isfile.return_value = False
733 ds = {'deploy_options': MagicMock()}
735 assert_raises(ApexDeployException, prep_storage_env, ds,
736 ns, virtual=False, tmp_dir='/tmp')
738 @patch('apex.overcloud.deploy.generate_ceph_key')
739 @patch('apex.overcloud.deploy.fileinput')
740 @patch('apex.overcloud.deploy.os.path.isfile')
741 @patch('builtins.open', mock_open())
742 def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
743 ds = {'deploy_options':
744 {'sdn_controller': 'opendaylight',
748 saved_stdout = sys.stdout
752 mock_fileinput.input.return_value = \
753 ['# NovaSchedulerDefaultFilters',
754 '# NovaSchedulerAvailableFilters',
755 '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
756 '#NeutronSriovNumVFs: \"ens20f2:5\"',
757 '#NovaPCIPassthrough:',
758 '# - devname: \"ens20f2\"',
759 '# physical_network: \"datacentre\"']
760 prep_sriov_env(ds, '/tmp')
761 output = out.getvalue().strip()
762 assert_in('NovaSchedulerDefaultFilters', output)
763 assert_in('NovaSchedulerAvailableFilters', output)
764 assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
765 assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
766 assert_in('NovaPCIPassthrough:', output)
767 assert_in('- devname: \"xxx\"', output)
768 assert_in('physical_network: \"nfv_sriov\"', output)
771 sys.stdout = saved_stdout
773 @patch('apex.overcloud.deploy.os.path.isfile')
774 @patch('builtins.open', mock_open())
775 def test_prep_sriov_env_raises(self, mock_isfile):
776 ds_opts = {'sriov': True}
777 ds = {'deploy_options': MagicMock()}
778 ds['deploy_options'].__getitem__.side_effect = \
779 lambda i: ds_opts.get(i, MagicMock())
780 mock_isfile.return_value = False
781 ds = {'deploy_options': MagicMock()}
782 assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
784 def test_external_network_cmds(self):
785 ds = {'deploy_options':
786 {'sdn_controller': 'opendaylight',
791 ns_dict = {'networks':
792 {'external': [{'floating_ip_range': (0, 1),
794 {'compute': {'vlan': 'native'}},
798 ns.enabled_network_list = ['external']
799 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
800 cmds = ' '.join(external_network_cmds(ns, ds))
801 assert_in('--external', cmds)
802 assert_in('--allocation-pool start=0,end=1', cmds)
803 assert_in('--gateway gw', cmds)
804 assert_in('--network external', cmds)
805 assert_in('--provider-physical-network datacentre', cmds)
807 def test_external_network_cmds_nosdn_fdio(self):
808 ds = {'deploy_options':
809 {'sdn_controller': False,
810 'dataplane': 'fdio'}}
814 ns_dict = {'networks':
815 {'external': [{'floating_ip_range': (0, 1),
817 {'compute': {'vlan': 'native'}},
821 ns.enabled_network_list = ['external']
822 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
823 cmds = ' '.join(external_network_cmds(ns, ds))
824 assert_in('--external', cmds)
825 assert_in('--allocation-pool start=0,end=1', cmds)
826 assert_in('--gateway gw', cmds)
827 assert_in('--network external', cmds)
828 assert_in('--provider-physical-network external', cmds)
830 def test_external_network_cmds_no_ext(self):
831 ds = {'deploy_options':
832 {'sdn_controller': 'opendaylight',
840 {'introspection_range': (0, 1),
842 {'compute': {'vlan': '123'}},
846 ns.enabled_network_list = ['admin']
847 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
848 cmds = ' '.join(external_network_cmds(ns, ds))
849 assert_in('--external', cmds)
850 assert_in('--allocation-pool start=0,end=1', cmds)
851 assert_in('--network external', cmds)
852 assert_in('--provider-network-type vlan', cmds)
854 @patch('apex.overcloud.deploy.parsers')
855 def test_create_congress_cmds(self, mock_parsers):
856 assert_greater(len(create_congress_cmds('overcloud_file')), 0)
858 @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
859 def test_create_congress_cmds_raises(self, mock_parsers):
860 mock_parsers.return_value.__getitem__.side_effect = KeyError()
861 assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
863 def test_get_docker_sdn_files(self):
864 ds_opts = {'ha_enabled': True,
871 'sdn_controller': 'opendaylight',
872 'os_version': 'queens'
874 output = get_docker_sdn_files(ds_opts)
875 compare = ['/usr/share/openstack-tripleo-heat-templates/'
876 'environments/services/neutron-opendaylight.yaml',
877 '/usr/share/openstack-tripleo-heat-templates/environments'
878 '/services/neutron-bgpvpn-opendaylight.yaml']
879 self.assertEqual(output, compare)