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.isfile')
201 @patch('builtins.open', mock_open())
202 def test_prep_image(self, mock_is_file, mock_shutil, mock_virt_utils,
204 mock_is_file.return_value = True
205 ds_opts = {'dataplane': 'fdio',
206 'sdn_controller': 'opendaylight',
207 'odl_version': 'master',
210 ds = {'deploy_options': MagicMock(),
211 'global_params': MagicMock()}
212 ds['deploy_options'].__getitem__.side_effect = \
213 lambda i: ds_opts.get(i, MagicMock())
215 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
216 mock_virt_utils.virt_customize.assert_called()
217 mock_inject_odl.assert_called()
219 @patch('apex.overcloud.deploy.virt_utils')
220 @patch('apex.overcloud.deploy.shutil')
221 @patch('apex.overcloud.deploy.os.path.isfile')
222 @patch('builtins.open', mock_open())
223 def test_prep_image_sdn_false(self, mock_is_file, mock_shutil,
225 mock_is_file.return_value = True
226 ds_opts = {'dataplane': 'fdio',
228 'sdn_controller': False}
229 ds = {'deploy_options': MagicMock(),
230 'global_params': MagicMock()}
231 ds['deploy_options'].__getitem__.side_effect = \
232 lambda i: ds_opts.get(i, MagicMock())
234 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
235 mock_virt_utils.virt_customize.assert_called()
237 @patch('apex.overcloud.deploy.utils.fetch_upstream_and_unpack')
238 @patch('apex.builders.overcloud_builder.inject_opendaylight')
239 @patch('apex.overcloud.deploy.virt_utils')
240 @patch('apex.overcloud.deploy.shutil')
241 @patch('apex.overcloud.deploy.os.path.isfile')
242 @patch('builtins.open', mock_open())
243 def test_prep_image_sdn_odl(self, mock_is_file, mock_shutil,
244 mock_virt_utils, mock_inject_odl, mock_fetch):
245 mock_is_file.return_value = True
246 ds_opts = {'dataplane': 'ovs',
247 'sdn_controller': 'opendaylight',
250 'odl_version': con.DEFAULT_ODL_VERSION,
251 'odl_vpp_netvirt': True}
252 ds = {'deploy_options': MagicMock(),
253 'global_params': MagicMock()}
254 ds['deploy_options'].__getitem__.side_effect = \
255 lambda i: ds_opts.get(i, MagicMock())
256 ds['deploy_options'].__contains__.side_effect = \
257 lambda i: True if i in ds_opts else MagicMock()
259 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
260 mock_virt_utils.virt_customize.assert_called()
261 mock_inject_odl.assert_called()
263 @patch('apex.overcloud.deploy.c_builder')
264 @patch('apex.overcloud.deploy.oc_builder')
265 @patch('apex.overcloud.deploy.virt_utils')
266 @patch('apex.overcloud.deploy.shutil')
267 @patch('apex.overcloud.deploy.os.path.isfile')
268 @patch('builtins.open', mock_open())
269 def test_prep_image_sdn_odl_upstream_containers_patches(
270 self, mock_is_file, mock_shutil, mock_virt_utils,
271 mock_oc_builder, mock_c_builder):
272 mock_is_file.return_value = True
273 ds_opts = {'dataplane': 'ovs',
274 'sdn_controller': 'opendaylight',
275 'odl_version': con.DEFAULT_ODL_VERSION,
276 'odl_vpp_netvirt': True}
277 ds = {'deploy_options': MagicMock(),
278 'global_params': MagicMock()}
279 ds['deploy_options'].__getitem__.side_effect = \
280 lambda i: ds_opts.get(i, MagicMock())
281 ds['deploy_options'].__contains__.side_effect = \
282 lambda i: True if i in ds_opts else MagicMock()
284 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
285 patches = ['dummy_nova_patch']
286 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
287 docker_tag='latest', patches=patches)
288 mock_oc_builder.inject_opendaylight.assert_called()
289 mock_virt_utils.virt_customize.assert_called()
290 mock_c_builder.add_upstream_patches.assert_called()
291 self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
293 @patch('apex.overcloud.deploy.c_builder')
294 @patch('apex.overcloud.deploy.oc_builder')
295 @patch('apex.overcloud.deploy.virt_utils')
296 @patch('apex.overcloud.deploy.shutil')
297 @patch('apex.overcloud.deploy.os.path.isfile')
298 @patch('builtins.open', mock_open())
299 def test_prep_image_nosdn_upstream_containers_patches(
300 self, mock_is_file, mock_shutil, mock_virt_utils,
301 mock_oc_builder, mock_c_builder):
302 mock_is_file.return_value = True
303 ds_opts = {'dataplane': 'ovs',
304 'sdn_controller': False,
305 'odl_version': con.DEFAULT_ODL_VERSION,
306 'odl_vpp_netvirt': False}
307 ds = {'deploy_options': MagicMock(),
308 'global_params': MagicMock()}
309 ds['deploy_options'].__getitem__.side_effect = \
310 lambda i: ds_opts.get(i, MagicMock())
311 ds['deploy_options'].__contains__.side_effect = \
312 lambda i: True if i in ds_opts else MagicMock()
314 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
315 patches = ['dummy_nova_patch']
316 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
317 docker_tag='latest', patches=patches)
318 mock_virt_utils.virt_customize.assert_called()
319 mock_c_builder.add_upstream_patches.assert_called()
320 self.assertListEqual(sorted(rv), ['nova-api'])
322 @patch('apex.overcloud.deploy.oc_builder')
323 @patch('apex.overcloud.deploy.virt_utils')
324 @patch('apex.overcloud.deploy.shutil')
325 @patch('apex.overcloud.deploy.os.path.isfile')
326 @patch('builtins.open', mock_open())
327 def test_prep_image_sdn_odl_not_def(self, mock_is_file,
328 mock_shutil, mock_virt_utils,
330 mock_is_file.return_value = True
331 ds_opts = {'dataplane': 'ovs',
332 'sdn_controller': 'opendaylight',
333 'odl_version': 'uncommon'}
334 ds = {'deploy_options': MagicMock(),
335 'global_params': MagicMock()}
336 ds['deploy_options'].__getitem__.side_effect = \
337 lambda i: ds_opts.get(i, MagicMock())
339 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
340 mock_virt_utils.virt_customize.assert_called()
341 mock_oc_builder.inject_opendaylight.assert_called()
343 @patch('apex.overcloud.deploy.virt_utils')
344 @patch('apex.overcloud.deploy.shutil')
345 @patch('apex.overcloud.deploy.os.path.isfile')
346 @patch('builtins.open', mock_open())
347 def test_prep_image_sdn_ovn(self, mock_is_file, mock_shutil,
349 mock_is_file.return_value = True
350 ds_opts = {'dataplane': 'ovs',
353 'sdn_controller': 'ovn'}
354 ds = {'deploy_options': MagicMock(),
355 'global_params': MagicMock()}
356 ds['deploy_options'].__getitem__.side_effect = \
357 lambda i: ds_opts.get(i, MagicMock())
359 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
360 mock_virt_utils.virt_customize.assert_called()
362 @patch('apex.overcloud.deploy.utils.fetch_upstream_and_unpack')
363 @patch('apex.builders.overcloud_builder.inject_quagga')
364 @patch('apex.builders.overcloud_builder.inject_opendaylight')
365 @patch('apex.overcloud.deploy.virt_utils')
366 @patch('apex.overcloud.deploy.shutil')
367 @patch('apex.overcloud.deploy.os.path.isfile')
368 @patch('builtins.open', mock_open())
369 def test_prep_image_sdn_odl_vpn(self, mock_is_file, mock_shutil,
370 mock_virt_utils, mock_inject_odl,
371 mock_inject_quagga, mock_fetch):
372 mock_is_file.return_value = True
373 ds_opts = {'dataplane': 'ovs',
374 'sdn_controller': 'opendaylight',
377 'odl_version': con.DEFAULT_ODL_VERSION,
378 'odl_vpp_netvirt': True}
379 ds = {'deploy_options': MagicMock(),
380 'global_params': MagicMock()}
381 ds['deploy_options'].__getitem__.side_effect = \
382 lambda i: ds_opts.get(i, MagicMock())
383 ds['deploy_options'].__contains__.side_effect = \
384 lambda i: True if i in ds_opts else MagicMock()
386 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
387 mock_virt_utils.virt_customize.assert_called()
388 mock_inject_odl.assert_called()
389 mock_inject_quagga.assert_called()
391 @patch('apex.builders.overcloud_builder.inject_ovs_nsh')
392 @patch('apex.builders.overcloud_builder.inject_opendaylight')
393 @patch('apex.overcloud.deploy.virt_utils')
394 @patch('apex.overcloud.deploy.shutil')
395 @patch('apex.overcloud.deploy.os.path.isfile')
396 @patch('builtins.open', mock_open())
397 def test_prep_image_sdn_odl_sfc(self, mock_is_file, mock_shutil,
398 mock_virt_utils, mock_inject_odl,
399 mock_inject_ovs_nsh):
400 mock_is_file.return_value = True
401 ds_opts = {'dataplane': 'ovs',
402 'sdn_controller': 'opendaylight',
405 'odl_version': con.DEFAULT_ODL_VERSION,
406 'odl_vpp_netvirt': True}
407 ds = {'deploy_options': MagicMock(),
408 'global_params': MagicMock()}
409 ds['deploy_options'].__getitem__.side_effect = \
410 lambda i: ds_opts.get(i, MagicMock())
411 ds['deploy_options'].__contains__.side_effect = \
412 lambda i: True if i in ds_opts else MagicMock()
414 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
415 mock_virt_utils.virt_customize.assert_called()
416 mock_inject_odl.assert_called()
417 mock_inject_ovs_nsh.assert_called()
419 @patch('apex.overcloud.deploy.os.path.isfile')
420 def test_prep_image_no_image(self, mock_isfile):
421 mock_isfile.return_value = False
422 assert_raises(ApexDeployException, prep_image,
423 {}, {}, 'undercloud.qcow2', '/tmp')
425 def test_make_ssh_key(self):
426 priv, pub = make_ssh_key()
427 assert_in('-----BEGIN PRIVATE KEY-----', priv)
428 assert_in('ssh-rsa', pub)
430 @patch('apex.overcloud.deploy.yaml')
431 @patch('apex.overcloud.deploy.fileinput')
432 @patch('apex.overcloud.deploy.shutil')
433 @patch('builtins.open', mock_open())
434 def test_prep_env(self, mock_shutil, mock_fileinput, mock_yaml):
435 mock_fileinput.input.return_value = \
436 ['CloudDomain', 'replace_private_key', 'replace_public_key',
437 'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
438 'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
439 'ComputeExtraConfigPre', 'resource_registry',
440 'NovaSchedulerDefaultFilters']
441 mock_yaml.safe_load.return_value = {
442 'parameter_defaults': {
443 'ControllerServices': [1, 2, 3],
444 'ComputeServices': [3, 4, 5]
446 ds = {'global_params': {'ha_enabled': False},
448 {'sdn_controller': 'opendaylight',
449 'odl_vpp_routing_node': 'test',
450 'dataplane': 'ovs_dpdk',
452 'performance': {'Compute': {'vpp': {'main-core': 'test',
453 'corelist-workers': 'test'},
454 'ovs': {'dpdk_cores': 'test'},
455 'kernel': {'test': 'test'}},
456 'Controller': {'vpp': 'test'}}}}
457 ns_dict = {'domain_name': 'test.domain',
460 {'nic_mapping': {'controller':
461 {'members': ['tenant_nic']},
463 {'members': ['tenant_nic']}}},
465 [{'nic_mapping': {'controller':
466 {'members': ['ext_nic']},
468 {'members': ['ext_nic']}}}]}}
470 inv.get_node_counts.return_value = (1, 0)
473 saved_stdout = sys.stdout
477 ns.enabled_network_list = ['external', 'tenant']
478 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
480 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
481 output = out.getvalue().strip()
482 assert_in('CloudDomain: test.domain', output)
483 assert_in('ssh-rsa', output)
484 assert_in('ComputeKernelArgs: \'test=test \'', output)
485 assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
486 mock_yaml.safe_dump.assert_called_with(
487 {'parameter_defaults': {
488 'ControllerServices': [1, 2, 3, 4, 5],
490 mock.ANY, default_flow_style=False
494 sys.stdout = saved_stdout
496 @patch('apex.overcloud.deploy.fileinput')
497 @patch('apex.overcloud.deploy.shutil')
498 @patch('builtins.open', mock_open())
499 def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
500 mock_fileinput.input.return_value = \
501 ['NeutronVPPAgentPhysnets']
502 ds = {'global_params': {'ha_enabled': False},
504 {'sdn_controller': False,
507 'performance': {'Compute': {},
509 ns_dict = {'domain_name': 'test.domain',
512 {'nic_mapping': {'controller':
513 {'members': ['tenant_nic']},
515 {'members': ['tenant_nic']}}},
517 [{'nic_mapping': {'controller':
518 {'members': ['ext_nic']},
520 {'members': ['ext_nic']}}}]}}
522 inv.get_node_counts.return_value = (3, 2)
525 saved_stdout = sys.stdout
529 ns.enabled_network_list = ['external', 'tenant']
530 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
532 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
533 output = out.getvalue().strip()
534 assert_in('NeutronVPPAgentPhysnets: '
535 '\'datacentre:tenant_nic,external:tap0\'',
537 assert_in('NeutronVPPAgentPhysnets', output)
540 sys.stdout = saved_stdout
542 @patch('apex.overcloud.deploy.fileinput')
543 @patch('apex.overcloud.deploy.shutil')
544 @patch('builtins.open', mock_open())
545 def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
546 mock_fileinput.input.return_value = \
547 ['OS::TripleO::Services::NeutronDhcpAgent',
548 'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
549 ds = {'global_params': {'ha_enabled': False},
551 {'sdn_controller': 'opendaylight',
555 ns_dict = {'domain_name': 'test.domain',
558 {'nic_mapping': {'controller':
559 {'members': ['tenant_nic']},
561 {'members': ['tenant_nic']}}},
563 [{'nic_mapping': {'controller':
564 {'members': ['ext_nic']},
566 {'members': ['ext_nic']}}}]}}
568 inv.get_node_counts.return_value = (3, 2)
571 saved_stdout = sys.stdout
575 ns.enabled_network_list = ['external', 'tenant']
576 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
578 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
579 output = out.getvalue().strip()
580 assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
583 sys.stdout = saved_stdout
585 @patch('apex.overcloud.deploy.fileinput')
586 @patch('apex.overcloud.deploy.shutil')
587 @patch('builtins.open', mock_open())
588 def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
589 mock_fileinput.input.return_value = \
590 ['NeutronNetworkVLANRanges',
591 'NeutronNetworkType', 'NeutronBridgeMappings']
592 ds = {'global_params': {'ha_enabled': False},
594 {'sdn_controller': False,
598 ns_dict = {'domain_name': 'test.domain',
601 {'nic_mapping': {'controller':
602 {'members': ['tenant_nic']},
604 {'members': ['tenant_nic']}},
605 'segmentation_type': 'vlan',
606 'overlay_id_range': 'vlan:500:600'
609 [{'nic_mapping': {'controller':
610 {'members': ['ext_nic']},
612 {'members': ['ext_nic']}}}]}}
614 inv.get_node_counts.return_value = (3, 2)
617 saved_stdout = sys.stdout
621 ns.enabled_network_list = ['external', 'tenant']
622 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
624 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
625 output = out.getvalue().strip()
626 assert_in('NeutronNetworkVLANRanges: '
627 'vlan:500:600,datacentre:1:1000', output)
628 assert_in('NeutronNetworkType: vlan', output)
629 assert_in('NeutronBridgeMappings: '
630 'vlan:br-vlan,datacentre:br-ex', output)
631 assert_not_in('OpenDaylightProviderMappings', output)
634 sys.stdout = saved_stdout
636 @patch('apex.overcloud.deploy.fileinput')
637 @patch('apex.overcloud.deploy.shutil')
638 @patch('builtins.open', mock_open())
639 def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
640 mock_fileinput.input.return_value = \
641 ['NeutronNetworkVLANRanges',
642 'NeutronNetworkType',
643 'NeutronBridgeMappings',
644 'OpenDaylightProviderMappings']
645 ds = {'global_params': {'ha_enabled': False},
647 {'sdn_controller': 'opendaylight',
651 ns_dict = {'domain_name': 'test.domain',
654 {'nic_mapping': {'controller':
655 {'members': ['tenant_nic']},
657 {'members': ['tenant_nic']}},
658 'segmentation_type': 'vlan',
659 'overlay_id_range': 'vlan:500:600'
662 [{'nic_mapping': {'controller':
663 {'members': ['ext_nic']},
665 {'members': ['ext_nic']}}}]}}
667 inv.get_node_counts.return_value = (3, 2)
670 saved_stdout = sys.stdout
674 ns.enabled_network_list = ['external', 'tenant']
675 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
677 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
678 output = out.getvalue().strip()
679 assert_in('NeutronNetworkVLANRanges: '
680 'vlan:500:600,datacentre:1:1000', output)
681 assert_in('NeutronNetworkType: vlan', output)
682 assert_in('NeutronBridgeMappings: '
683 'vlan:br-vlan,datacentre:br-ex', output)
684 assert_in('OpenDaylightProviderMappings: '
685 'vlan:br-vlan,datacentre:br-ex', output)
688 sys.stdout = saved_stdout
690 def test_generate_ceph_key(self):
691 assert_equal(len(generate_ceph_key()), 40)
693 @patch('apex.overcloud.deploy.generate_ceph_key')
694 @patch('apex.overcloud.deploy.fileinput')
695 @patch('apex.overcloud.deploy.os.path.isfile')
696 @patch('builtins.open', mock_open())
697 def test_prep_storage_env(self, mock_isfile, mock_fileinput,
699 mock_fileinput.input.return_value = \
700 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
701 ds = {'deploy_options': {
702 'ceph_device': '/dev/sdx',
706 prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
708 @patch('apex.overcloud.deploy.utils.edit_tht_env')
709 @patch('apex.overcloud.deploy.generate_ceph_key')
710 @patch('apex.overcloud.deploy.fileinput')
711 @patch('apex.overcloud.deploy.os.path.isfile')
712 @patch('builtins.open', mock_open())
713 def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
714 mock_ceph_key, mock_edit_tht):
715 mock_fileinput.input.return_value = \
716 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
717 ds = {'deploy_options': {
718 'ceph_device': '/dev/sdx',
720 'os_version': 'master'
721 }, 'global_params': {'ha_enabled': False}}
722 ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
723 {'ip': '192.0.2.1'}}}
725 prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
727 'CephPoolDefaultSize': 2,
728 'CephAnsibleExtraConfig': {
729 'centos_package_dependencies': [],
730 'ceph_osd_docker_memory_limit': '1g',
731 'ceph_mds_docker_memory_limit': '1g'
733 'CephPoolDefaultPgNum': 32,
734 'CephAnsibleDisksConfig': {
735 'devices': ['/dev/sdx'],
737 'osd_scenario': 'collocated'
740 mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
741 'parameter_defaults',
744 @patch('apex.overcloud.deploy.os.path.isfile')
745 @patch('builtins.open', mock_open())
746 def test_prep_storage_env_raises(self, mock_isfile):
747 mock_isfile.return_value = False
748 ds = {'deploy_options': MagicMock()}
750 assert_raises(ApexDeployException, prep_storage_env, ds,
751 ns, virtual=False, tmp_dir='/tmp')
753 @patch('apex.overcloud.deploy.generate_ceph_key')
754 @patch('apex.overcloud.deploy.fileinput')
755 @patch('apex.overcloud.deploy.os.path.isfile')
756 @patch('builtins.open', mock_open())
757 def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
758 ds = {'deploy_options':
759 {'sdn_controller': 'opendaylight',
763 saved_stdout = sys.stdout
767 mock_fileinput.input.return_value = \
768 ['# NovaSchedulerDefaultFilters',
769 '# NovaSchedulerAvailableFilters',
770 '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
771 '#NeutronSriovNumVFs: \"ens20f2:5\"',
772 '#NovaPCIPassthrough:',
773 '# - devname: \"ens20f2\"',
774 '# physical_network: \"datacentre\"']
775 prep_sriov_env(ds, '/tmp')
776 output = out.getvalue().strip()
777 assert_in('NovaSchedulerDefaultFilters', output)
778 assert_in('NovaSchedulerAvailableFilters', output)
779 assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
780 assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
781 assert_in('NovaPCIPassthrough:', output)
782 assert_in('- devname: \"xxx\"', output)
783 assert_in('physical_network: \"nfv_sriov\"', output)
786 sys.stdout = saved_stdout
788 @patch('apex.overcloud.deploy.os.path.isfile')
789 @patch('builtins.open', mock_open())
790 def test_prep_sriov_env_raises(self, mock_isfile):
791 ds_opts = {'sriov': True}
792 ds = {'deploy_options': MagicMock()}
793 ds['deploy_options'].__getitem__.side_effect = \
794 lambda i: ds_opts.get(i, MagicMock())
795 mock_isfile.return_value = False
796 ds = {'deploy_options': MagicMock()}
797 assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
799 def test_external_network_cmds(self):
800 ds = {'deploy_options':
801 {'sdn_controller': 'opendaylight',
806 ns_dict = {'networks':
807 {'external': [{'floating_ip_range': (0, 1),
809 {'compute': {'vlan': 'native'}},
813 ns.enabled_network_list = ['external']
814 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
815 cmds = ' '.join(external_network_cmds(ns, ds))
816 assert_in('--external', cmds)
817 assert_in('--allocation-pool start=0,end=1', cmds)
818 assert_in('--gateway gw', cmds)
819 assert_in('--network external', cmds)
820 assert_in('--provider-physical-network datacentre', cmds)
822 def test_external_network_cmds_nosdn_fdio(self):
823 ds = {'deploy_options':
824 {'sdn_controller': False,
825 'dataplane': 'fdio'}}
829 ns_dict = {'networks':
830 {'external': [{'floating_ip_range': (0, 1),
832 {'compute': {'vlan': 'native'}},
836 ns.enabled_network_list = ['external']
837 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
838 cmds = ' '.join(external_network_cmds(ns, ds))
839 assert_in('--external', cmds)
840 assert_in('--allocation-pool start=0,end=1', cmds)
841 assert_in('--gateway gw', cmds)
842 assert_in('--network external', cmds)
843 assert_in('--provider-physical-network external', cmds)
845 def test_external_network_cmds_no_ext(self):
846 ds = {'deploy_options':
847 {'sdn_controller': 'opendaylight',
855 {'introspection_range': (0, 1),
857 {'compute': {'vlan': '123'}},
861 ns.enabled_network_list = ['admin']
862 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
863 cmds = ' '.join(external_network_cmds(ns, ds))
864 assert_in('--external', cmds)
865 assert_in('--allocation-pool start=0,end=1', cmds)
866 assert_in('--network external', cmds)
867 assert_in('--provider-network-type vlan', cmds)
869 @patch('apex.overcloud.deploy.parsers')
870 def test_create_congress_cmds(self, mock_parsers):
871 assert_greater(len(create_congress_cmds('overcloud_file')), 0)
873 @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
874 def test_create_congress_cmds_raises(self, mock_parsers):
875 mock_parsers.return_value.__getitem__.side_effect = KeyError()
876 assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
878 def test_get_docker_sdn_files(self):
879 ds_opts = {'ha_enabled': True,
886 'sdn_controller': 'opendaylight',
887 'os_version': 'queens'
889 output = get_docker_sdn_files(ds_opts)
890 compare = ['/usr/share/openstack-tripleo-heat-templates/'
891 'environments/services/neutron-opendaylight.yaml',
892 '/usr/share/openstack-tripleo-heat-templates/environments'
893 '/services/neutron-bgpvpn-opendaylight.yaml']
894 self.assertEqual(output, compare)