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',
245 'odl_version': con.DEFAULT_ODL_VERSION,
246 'odl_vpp_netvirt': True}
247 ds = {'deploy_options': MagicMock(),
248 'global_params': MagicMock()}
249 ds['deploy_options'].__getitem__.side_effect = \
250 lambda i: ds_opts.get(i, MagicMock())
251 ds['deploy_options'].__contains__.side_effect = \
252 lambda i: True if i in ds_opts else MagicMock()
254 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
255 mock_virt_utils.virt_customize.assert_called()
256 mock_inject_odl.assert_called()
258 @patch('apex.overcloud.deploy.c_builder')
259 @patch('apex.overcloud.deploy.oc_builder')
260 @patch('apex.overcloud.deploy.virt_utils')
261 @patch('apex.overcloud.deploy.shutil')
262 @patch('apex.overcloud.deploy.os.path')
263 @patch('builtins.open', mock_open())
264 def test_prep_image_sdn_odl_upstream_containers_patches(
265 self, mock_os_path, mock_shutil, mock_virt_utils,
266 mock_oc_builder, mock_c_builder):
267 ds_opts = {'dataplane': 'ovs',
268 'sdn_controller': 'opendaylight',
269 'odl_version': con.DEFAULT_ODL_VERSION,
270 'odl_vpp_netvirt': True}
271 ds = {'deploy_options': MagicMock(),
272 'global_params': MagicMock()}
273 ds['deploy_options'].__getitem__.side_effect = \
274 lambda i: ds_opts.get(i, MagicMock())
275 ds['deploy_options'].__contains__.side_effect = \
276 lambda i: True if i in ds_opts else MagicMock()
278 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
279 patches = ['dummy_nova_patch']
280 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
281 docker_tag='latest', patches=patches)
282 mock_oc_builder.inject_opendaylight.assert_called()
283 mock_virt_utils.virt_customize.assert_called()
284 mock_c_builder.add_upstream_patches.assert_called()
285 self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
287 @patch('apex.overcloud.deploy.c_builder')
288 @patch('apex.overcloud.deploy.oc_builder')
289 @patch('apex.overcloud.deploy.virt_utils')
290 @patch('apex.overcloud.deploy.shutil')
291 @patch('apex.overcloud.deploy.os.path')
292 @patch('builtins.open', mock_open())
293 def test_prep_image_nosdn_upstream_containers_patches(
294 self, mock_os_path, mock_shutil, mock_virt_utils,
295 mock_oc_builder, mock_c_builder):
296 ds_opts = {'dataplane': 'ovs',
297 'sdn_controller': False,
298 'odl_version': con.DEFAULT_ODL_VERSION,
299 'odl_vpp_netvirt': False}
300 ds = {'deploy_options': MagicMock(),
301 'global_params': MagicMock()}
302 ds['deploy_options'].__getitem__.side_effect = \
303 lambda i: ds_opts.get(i, MagicMock())
304 ds['deploy_options'].__contains__.side_effect = \
305 lambda i: True if i in ds_opts else MagicMock()
307 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
308 patches = ['dummy_nova_patch']
309 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
310 docker_tag='latest', patches=patches)
311 mock_virt_utils.virt_customize.assert_called()
312 mock_c_builder.add_upstream_patches.assert_called()
313 self.assertListEqual(sorted(rv), ['nova-api'])
315 @patch('apex.overcloud.deploy.oc_builder')
316 @patch('apex.overcloud.deploy.virt_utils')
317 @patch('apex.overcloud.deploy.shutil')
318 @patch('apex.overcloud.deploy.os.path')
319 @patch('builtins.open', mock_open())
320 def test_prep_image_sdn_odl_not_def(self, mock_os_path,
321 mock_shutil, mock_virt_utils,
323 ds_opts = {'dataplane': 'ovs',
324 'sdn_controller': 'opendaylight',
325 'odl_version': 'uncommon'}
326 ds = {'deploy_options': MagicMock(),
327 'global_params': MagicMock()}
328 ds['deploy_options'].__getitem__.side_effect = \
329 lambda i: ds_opts.get(i, MagicMock())
331 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
332 mock_virt_utils.virt_customize.assert_called()
333 mock_oc_builder.inject_opendaylight.assert_called()
335 @patch('apex.overcloud.deploy.virt_utils')
336 @patch('apex.overcloud.deploy.shutil')
337 @patch('apex.overcloud.deploy.os.path')
338 @patch('builtins.open', mock_open())
339 def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
341 ds_opts = {'dataplane': 'ovs',
343 'sdn_controller': 'ovn'}
344 ds = {'deploy_options': MagicMock(),
345 'global_params': MagicMock()}
346 ds['deploy_options'].__getitem__.side_effect = \
347 lambda i: ds_opts.get(i, MagicMock())
349 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
350 mock_virt_utils.virt_customize.assert_called()
352 @patch('apex.builders.overcloud_builder.inject_quagga')
353 @patch('apex.builders.overcloud_builder.inject_opendaylight')
354 @patch('apex.overcloud.deploy.virt_utils')
355 @patch('apex.overcloud.deploy.shutil')
356 @patch('apex.overcloud.deploy.os.path')
357 @patch('builtins.open', mock_open())
358 def test_prep_image_sdn_odl_vpn(self, mock_os_path, mock_shutil,
359 mock_virt_utils, mock_inject_odl,
361 ds_opts = {'dataplane': 'ovs',
362 'sdn_controller': 'opendaylight',
364 'odl_version': con.DEFAULT_ODL_VERSION,
365 'odl_vpp_netvirt': True}
366 ds = {'deploy_options': MagicMock(),
367 'global_params': MagicMock()}
368 ds['deploy_options'].__getitem__.side_effect = \
369 lambda i: ds_opts.get(i, MagicMock())
370 ds['deploy_options'].__contains__.side_effect = \
371 lambda i: True if i in ds_opts else MagicMock()
373 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
374 mock_virt_utils.virt_customize.assert_called()
375 mock_inject_odl.assert_called()
376 mock_inject_quagga.assert_called()
378 @patch('apex.overcloud.deploy.os.path.isfile')
379 def test_prep_image_no_image(self, mock_isfile):
380 mock_isfile.return_value = False
381 assert_raises(ApexDeployException, prep_image,
382 {}, {}, 'undercloud.qcow2', '/tmp')
384 def test_make_ssh_key(self):
385 priv, pub = make_ssh_key()
386 assert_in('-----BEGIN PRIVATE KEY-----', priv)
387 assert_in('ssh-rsa', pub)
389 @patch('apex.overcloud.deploy.yaml')
390 @patch('apex.overcloud.deploy.fileinput')
391 @patch('apex.overcloud.deploy.shutil')
392 @patch('builtins.open', mock_open())
393 def test_prep_env(self, mock_shutil, mock_fileinput, mock_yaml):
394 mock_fileinput.input.return_value = \
395 ['CloudDomain', 'replace_private_key', 'replace_public_key',
396 'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
397 'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
398 'ComputeExtraConfigPre', 'resource_registry',
399 'NovaSchedulerDefaultFilters']
400 mock_yaml.safe_load.return_value = {
401 'parameter_defaults': {
402 'ControllerServices': [1, 2, 3],
403 'ComputeServices': [3, 4, 5]
405 ds = {'global_params': {'ha_enabled': False},
407 {'sdn_controller': 'opendaylight',
408 'odl_vpp_routing_node': 'test',
409 'dataplane': 'ovs_dpdk',
411 'performance': {'Compute': {'vpp': {'main-core': 'test',
412 'corelist-workers': 'test'},
413 'ovs': {'dpdk_cores': 'test'},
414 'kernel': {'test': 'test'}},
415 'Controller': {'vpp': 'test'}}}}
416 ns_dict = {'domain_name': 'test.domain',
419 {'nic_mapping': {'controller':
420 {'members': ['tenant_nic']},
422 {'members': ['tenant_nic']}}},
424 [{'nic_mapping': {'controller':
425 {'members': ['ext_nic']},
427 {'members': ['ext_nic']}}}]}}
429 inv.get_node_counts.return_value = (1, 0)
432 saved_stdout = sys.stdout
436 ns.enabled_network_list = ['external', 'tenant']
437 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
439 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
440 output = out.getvalue().strip()
441 assert_in('CloudDomain: test.domain', output)
442 assert_in('ssh-rsa', output)
443 assert_in('ComputeKernelArgs: \'test=test \'', output)
444 assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
445 mock_yaml.safe_dump.assert_called_with(
446 {'parameter_defaults': {
447 'ControllerServices': [1, 2, 3, 4, 5],
449 mock.ANY, default_flow_style=False
453 sys.stdout = saved_stdout
455 @patch('apex.overcloud.deploy.fileinput')
456 @patch('apex.overcloud.deploy.shutil')
457 def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
458 mock_fileinput.input.return_value = \
459 ['NeutronVPPAgentPhysnets']
460 ds = {'global_params': {'ha_enabled': False},
462 {'sdn_controller': False,
465 'performance': {'Compute': {},
467 ns_dict = {'domain_name': 'test.domain',
470 {'nic_mapping': {'controller':
471 {'members': ['tenant_nic']},
473 {'members': ['tenant_nic']}}},
475 [{'nic_mapping': {'controller':
476 {'members': ['ext_nic']},
478 {'members': ['ext_nic']}}}]}}
480 inv.get_node_counts.return_value = (3, 2)
483 saved_stdout = sys.stdout
487 ns.enabled_network_list = ['external', 'tenant']
488 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
490 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
491 output = out.getvalue().strip()
492 assert_in('NeutronVPPAgentPhysnets: '
493 '\'datacentre:tenant_nic,external:tap0\'',
495 assert_in('NeutronVPPAgentPhysnets', output)
498 sys.stdout = saved_stdout
500 @patch('apex.overcloud.deploy.fileinput')
501 @patch('apex.overcloud.deploy.shutil')
502 def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
503 mock_fileinput.input.return_value = \
504 ['OS::TripleO::Services::NeutronDhcpAgent',
505 'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
506 ds = {'global_params': {'ha_enabled': False},
508 {'sdn_controller': 'opendaylight',
512 ns_dict = {'domain_name': 'test.domain',
515 {'nic_mapping': {'controller':
516 {'members': ['tenant_nic']},
518 {'members': ['tenant_nic']}}},
520 [{'nic_mapping': {'controller':
521 {'members': ['ext_nic']},
523 {'members': ['ext_nic']}}}]}}
525 inv.get_node_counts.return_value = (3, 2)
528 saved_stdout = sys.stdout
532 ns.enabled_network_list = ['external', 'tenant']
533 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
535 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
536 output = out.getvalue().strip()
537 assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
540 sys.stdout = saved_stdout
542 @patch('apex.overcloud.deploy.fileinput')
543 @patch('apex.overcloud.deploy.shutil')
544 def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
545 mock_fileinput.input.return_value = \
546 ['NeutronNetworkVLANRanges',
547 'NeutronNetworkType', 'NeutronBridgeMappings']
548 ds = {'global_params': {'ha_enabled': False},
550 {'sdn_controller': False,
554 ns_dict = {'domain_name': 'test.domain',
557 {'nic_mapping': {'controller':
558 {'members': ['tenant_nic']},
560 {'members': ['tenant_nic']}},
561 'segmentation_type': 'vlan',
562 'overlay_id_range': 'vlan:500:600'
565 [{'nic_mapping': {'controller':
566 {'members': ['ext_nic']},
568 {'members': ['ext_nic']}}}]}}
570 inv.get_node_counts.return_value = (3, 2)
573 saved_stdout = sys.stdout
577 ns.enabled_network_list = ['external', 'tenant']
578 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
580 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
581 output = out.getvalue().strip()
582 assert_in('NeutronNetworkVLANRanges: '
583 'vlan:500:600,datacentre:1:1000', output)
584 assert_in('NeutronNetworkType: vlan', output)
585 assert_in('NeutronBridgeMappings: '
586 'vlan:br-vlan,datacentre:br-ex', output)
587 assert_not_in('OpenDaylightProviderMappings', output)
590 sys.stdout = saved_stdout
592 @patch('apex.overcloud.deploy.fileinput')
593 @patch('apex.overcloud.deploy.shutil')
594 def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
595 mock_fileinput.input.return_value = \
596 ['NeutronNetworkVLANRanges',
597 'NeutronNetworkType',
598 'NeutronBridgeMappings',
599 'OpenDaylightProviderMappings']
600 ds = {'global_params': {'ha_enabled': False},
602 {'sdn_controller': 'opendaylight',
606 ns_dict = {'domain_name': 'test.domain',
609 {'nic_mapping': {'controller':
610 {'members': ['tenant_nic']},
612 {'members': ['tenant_nic']}},
613 'segmentation_type': 'vlan',
614 'overlay_id_range': 'vlan:500:600'
617 [{'nic_mapping': {'controller':
618 {'members': ['ext_nic']},
620 {'members': ['ext_nic']}}}]}}
622 inv.get_node_counts.return_value = (3, 2)
625 saved_stdout = sys.stdout
629 ns.enabled_network_list = ['external', 'tenant']
630 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
632 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
633 output = out.getvalue().strip()
634 assert_in('NeutronNetworkVLANRanges: '
635 'vlan:500:600,datacentre:1:1000', output)
636 assert_in('NeutronNetworkType: vlan', output)
637 assert_in('NeutronBridgeMappings: '
638 'vlan:br-vlan,datacentre:br-ex', output)
639 assert_in('OpenDaylightProviderMappings: '
640 'vlan:br-vlan,datacentre:br-ex', output)
643 sys.stdout = saved_stdout
645 def test_generate_ceph_key(self):
646 assert_equal(len(generate_ceph_key()), 40)
648 @patch('apex.overcloud.deploy.generate_ceph_key')
649 @patch('apex.overcloud.deploy.fileinput')
650 @patch('apex.overcloud.deploy.os.path.isfile')
651 @patch('builtins.open', mock_open())
652 def test_prep_storage_env(self, mock_isfile, mock_fileinput,
654 mock_fileinput.input.return_value = \
655 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
656 ds = {'deploy_options': {
657 'ceph_device': '/dev/sdx',
661 prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
663 @patch('apex.overcloud.deploy.utils.edit_tht_env')
664 @patch('apex.overcloud.deploy.generate_ceph_key')
665 @patch('apex.overcloud.deploy.fileinput')
666 @patch('apex.overcloud.deploy.os.path.isfile')
667 @patch('builtins.open', mock_open())
668 def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
669 mock_ceph_key, mock_edit_tht):
670 mock_fileinput.input.return_value = \
671 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
672 ds = {'deploy_options': {
673 'ceph_device': '/dev/sdx',
675 'os_version': 'master'
676 }, 'global_params': {'ha_enabled': False}}
677 ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
678 {'ip': '192.0.2.1'}}}
680 prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
682 'CephPoolDefaultSize': 2,
683 'CephAnsibleExtraConfig': {
684 'centos_package_dependencies': [],
685 'ceph_osd_docker_memory_limit': '1g',
686 'ceph_mds_docker_memory_limit': '1g'
688 'CephPoolDefaultPgNum': 32,
689 'CephAnsibleDisksConfig': {
690 'devices': ['/dev/sdx'],
692 'osd_scenario': 'collocated'
695 mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
696 'parameter_defaults',
699 @patch('apex.overcloud.deploy.os.path.isfile')
700 @patch('builtins.open', mock_open())
701 def test_prep_storage_env_raises(self, mock_isfile):
702 mock_isfile.return_value = False
703 ds = {'deploy_options': MagicMock()}
705 assert_raises(ApexDeployException, prep_storage_env, ds,
706 ns, virtual=False, tmp_dir='/tmp')
708 @patch('apex.overcloud.deploy.generate_ceph_key')
709 @patch('apex.overcloud.deploy.fileinput')
710 @patch('apex.overcloud.deploy.os.path.isfile')
711 @patch('builtins.open', mock_open())
712 def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
713 ds = {'deploy_options':
714 {'sdn_controller': 'opendaylight',
718 saved_stdout = sys.stdout
722 mock_fileinput.input.return_value = \
723 ['# NovaSchedulerDefaultFilters',
724 '# NovaSchedulerAvailableFilters',
725 '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
726 '#NeutronSriovNumVFs: \"ens20f2:5\"',
727 '#NovaPCIPassthrough:',
728 '# - devname: \"ens20f2\"',
729 '# physical_network: \"datacentre\"']
730 prep_sriov_env(ds, '/tmp')
731 output = out.getvalue().strip()
732 assert_in('NovaSchedulerDefaultFilters', output)
733 assert_in('NovaSchedulerAvailableFilters', output)
734 assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
735 assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
736 assert_in('NovaPCIPassthrough:', output)
737 assert_in('- devname: \"xxx\"', output)
738 assert_in('physical_network: \"nfv_sriov\"', output)
741 sys.stdout = saved_stdout
743 @patch('apex.overcloud.deploy.os.path.isfile')
744 @patch('builtins.open', mock_open())
745 def test_prep_sriov_env_raises(self, mock_isfile):
746 ds_opts = {'sriov': True}
747 ds = {'deploy_options': MagicMock()}
748 ds['deploy_options'].__getitem__.side_effect = \
749 lambda i: ds_opts.get(i, MagicMock())
750 mock_isfile.return_value = False
751 ds = {'deploy_options': MagicMock()}
752 assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
754 def test_external_network_cmds(self):
755 ds = {'deploy_options':
756 {'sdn_controller': 'opendaylight',
761 ns_dict = {'networks':
762 {'external': [{'floating_ip_range': (0, 1),
764 {'compute': {'vlan': 'native'}},
768 ns.enabled_network_list = ['external']
769 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
770 cmds = ' '.join(external_network_cmds(ns, ds))
771 assert_in('--external', cmds)
772 assert_in('--allocation-pool start=0,end=1', cmds)
773 assert_in('--gateway gw', cmds)
774 assert_in('--network external', cmds)
775 assert_in('--provider-physical-network datacentre', cmds)
777 def test_external_network_cmds_nosdn_fdio(self):
778 ds = {'deploy_options':
779 {'sdn_controller': False,
780 'dataplane': 'fdio'}}
784 ns_dict = {'networks':
785 {'external': [{'floating_ip_range': (0, 1),
787 {'compute': {'vlan': 'native'}},
791 ns.enabled_network_list = ['external']
792 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
793 cmds = ' '.join(external_network_cmds(ns, ds))
794 assert_in('--external', cmds)
795 assert_in('--allocation-pool start=0,end=1', cmds)
796 assert_in('--gateway gw', cmds)
797 assert_in('--network external', cmds)
798 assert_in('--provider-physical-network external', cmds)
800 def test_external_network_cmds_no_ext(self):
801 ds = {'deploy_options':
802 {'sdn_controller': 'opendaylight',
810 {'introspection_range': (0, 1),
812 {'compute': {'vlan': '123'}},
816 ns.enabled_network_list = ['admin']
817 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
818 cmds = ' '.join(external_network_cmds(ns, ds))
819 assert_in('--external', cmds)
820 assert_in('--allocation-pool start=0,end=1', cmds)
821 assert_in('--network external', cmds)
822 assert_in('--provider-network-type vlan', cmds)
824 @patch('apex.overcloud.deploy.parsers')
825 def test_create_congress_cmds(self, mock_parsers):
826 assert_greater(len(create_congress_cmds('overcloud_file')), 0)
828 @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
829 def test_create_congress_cmds_raises(self, mock_parsers):
830 mock_parsers.return_value.__getitem__.side_effect = KeyError()
831 assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
833 def test_get_docker_sdn_files(self):
834 ds_opts = {'ha_enabled': True,
841 'sdn_controller': 'opendaylight',
842 'os_version': 'queens'
844 output = get_docker_sdn_files(ds_opts)
845 compare = ['/usr/share/openstack-tripleo-heat-templates/'
846 'environments/services/neutron-opendaylight.yaml',
847 '/usr/share/openstack-tripleo-heat-templates/environments'
848 '/services/neutron-bgpvpn-opendaylight.yaml']
849 self.assertEqual(output, compare)