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.oc_builder')
288 @patch('apex.overcloud.deploy.virt_utils')
289 @patch('apex.overcloud.deploy.shutil')
290 @patch('apex.overcloud.deploy.os.path')
291 @patch('builtins.open', mock_open())
292 def test_prep_image_sdn_odl_not_def(self, mock_os_path,
293 mock_shutil, mock_virt_utils,
295 ds_opts = {'dataplane': 'ovs',
296 'sdn_controller': 'opendaylight',
297 'odl_version': 'uncommon'}
298 ds = {'deploy_options': MagicMock(),
299 'global_params': MagicMock()}
300 ds['deploy_options'].__getitem__.side_effect = \
301 lambda i: ds_opts.get(i, MagicMock())
303 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
304 mock_virt_utils.virt_customize.assert_called()
305 mock_oc_builder.inject_opendaylight.assert_called()
307 @patch('apex.overcloud.deploy.virt_utils')
308 @patch('apex.overcloud.deploy.shutil')
309 @patch('apex.overcloud.deploy.os.path')
310 @patch('builtins.open', mock_open())
311 def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
313 ds_opts = {'dataplane': 'ovs',
315 'sdn_controller': 'ovn'}
316 ds = {'deploy_options': MagicMock(),
317 'global_params': MagicMock()}
318 ds['deploy_options'].__getitem__.side_effect = \
319 lambda i: ds_opts.get(i, MagicMock())
321 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
322 mock_virt_utils.virt_customize.assert_called()
324 @patch('apex.builders.overcloud_builder.inject_quagga')
325 @patch('apex.builders.overcloud_builder.inject_opendaylight')
326 @patch('apex.overcloud.deploy.virt_utils')
327 @patch('apex.overcloud.deploy.shutil')
328 @patch('apex.overcloud.deploy.os.path')
329 @patch('builtins.open', mock_open())
330 def test_prep_image_sdn_odl_vpn(self, mock_os_path, mock_shutil,
331 mock_virt_utils, mock_inject_odl,
333 ds_opts = {'dataplane': 'ovs',
334 'sdn_controller': 'opendaylight',
336 'odl_version': con.DEFAULT_ODL_VERSION,
337 'odl_vpp_netvirt': True}
338 ds = {'deploy_options': MagicMock(),
339 'global_params': MagicMock()}
340 ds['deploy_options'].__getitem__.side_effect = \
341 lambda i: ds_opts.get(i, MagicMock())
342 ds['deploy_options'].__contains__.side_effect = \
343 lambda i: True if i in ds_opts else MagicMock()
345 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
346 mock_virt_utils.virt_customize.assert_called()
347 mock_inject_odl.assert_called()
348 mock_inject_quagga.assert_called()
350 @patch('apex.overcloud.deploy.os.path.isfile')
351 def test_prep_image_no_image(self, mock_isfile):
352 mock_isfile.return_value = False
353 assert_raises(ApexDeployException, prep_image,
354 {}, {}, 'undercloud.qcow2', '/tmp')
356 def test_make_ssh_key(self):
357 priv, pub = make_ssh_key()
358 assert_in('-----BEGIN PRIVATE KEY-----', priv)
359 assert_in('ssh-rsa', pub)
361 @patch('apex.overcloud.deploy.yaml')
362 @patch('apex.overcloud.deploy.fileinput')
363 @patch('apex.overcloud.deploy.shutil')
364 @patch('builtins.open', mock_open())
365 def test_prep_env(self, mock_shutil, mock_fileinput, mock_yaml):
366 mock_fileinput.input.return_value = \
367 ['CloudDomain', 'replace_private_key', 'replace_public_key',
368 'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
369 'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
370 'ComputeExtraConfigPre', 'resource_registry',
371 'NovaSchedulerDefaultFilters']
372 mock_yaml.safe_load.return_value = {
373 'parameter_defaults': {
374 'ControllerServices': [1, 2, 3],
375 'ComputeServices': [3, 4, 5]
377 ds = {'global_params': {'ha_enabled': False},
379 {'sdn_controller': 'opendaylight',
380 'odl_vpp_routing_node': 'test',
381 'dataplane': 'ovs_dpdk',
383 'performance': {'Compute': {'vpp': {'main-core': 'test',
384 'corelist-workers': 'test'},
385 'ovs': {'dpdk_cores': 'test'},
386 'kernel': {'test': 'test'}},
387 'Controller': {'vpp': 'test'}}}}
388 ns_dict = {'domain_name': 'test.domain',
391 {'nic_mapping': {'controller':
392 {'members': ['tenant_nic']},
394 {'members': ['tenant_nic']}}},
396 [{'nic_mapping': {'controller':
397 {'members': ['ext_nic']},
399 {'members': ['ext_nic']}}}]}}
401 inv.get_node_counts.return_value = (1, 0)
404 saved_stdout = sys.stdout
408 ns.enabled_network_list = ['external', 'tenant']
409 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
411 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
412 output = out.getvalue().strip()
413 assert_in('CloudDomain: test.domain', output)
414 assert_in('ssh-rsa', output)
415 assert_in('ComputeKernelArgs: \'test=test \'', output)
416 assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
417 mock_yaml.safe_dump.assert_called_with(
418 {'parameter_defaults': {
419 'ControllerServices': [1, 2, 3, 4, 5],
421 mock.ANY, default_flow_style=False
425 sys.stdout = saved_stdout
427 @patch('apex.overcloud.deploy.fileinput')
428 @patch('apex.overcloud.deploy.shutil')
429 def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
430 mock_fileinput.input.return_value = \
431 ['NeutronVPPAgentPhysnets']
432 ds = {'global_params': {'ha_enabled': False},
434 {'sdn_controller': False,
437 'performance': {'Compute': {},
439 ns_dict = {'domain_name': 'test.domain',
442 {'nic_mapping': {'controller':
443 {'members': ['tenant_nic']},
445 {'members': ['tenant_nic']}}},
447 [{'nic_mapping': {'controller':
448 {'members': ['ext_nic']},
450 {'members': ['ext_nic']}}}]}}
452 inv.get_node_counts.return_value = (3, 2)
455 saved_stdout = sys.stdout
459 ns.enabled_network_list = ['external', 'tenant']
460 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
462 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
463 output = out.getvalue().strip()
464 assert_in('NeutronVPPAgentPhysnets: '
465 '\'datacentre:tenant_nic,external:tap0\'',
467 assert_in('NeutronVPPAgentPhysnets', output)
470 sys.stdout = saved_stdout
472 @patch('apex.overcloud.deploy.fileinput')
473 @patch('apex.overcloud.deploy.shutil')
474 def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
475 mock_fileinput.input.return_value = \
476 ['OS::TripleO::Services::NeutronDhcpAgent',
477 'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
478 ds = {'global_params': {'ha_enabled': False},
480 {'sdn_controller': 'opendaylight',
484 ns_dict = {'domain_name': 'test.domain',
487 {'nic_mapping': {'controller':
488 {'members': ['tenant_nic']},
490 {'members': ['tenant_nic']}}},
492 [{'nic_mapping': {'controller':
493 {'members': ['ext_nic']},
495 {'members': ['ext_nic']}}}]}}
497 inv.get_node_counts.return_value = (3, 2)
500 saved_stdout = sys.stdout
504 ns.enabled_network_list = ['external', 'tenant']
505 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
507 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
508 output = out.getvalue().strip()
509 assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
512 sys.stdout = saved_stdout
514 @patch('apex.overcloud.deploy.fileinput')
515 @patch('apex.overcloud.deploy.shutil')
516 def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
517 mock_fileinput.input.return_value = \
518 ['NeutronNetworkVLANRanges',
519 'NeutronNetworkType', 'NeutronBridgeMappings']
520 ds = {'global_params': {'ha_enabled': False},
522 {'sdn_controller': False,
526 ns_dict = {'domain_name': 'test.domain',
529 {'nic_mapping': {'controller':
530 {'members': ['tenant_nic']},
532 {'members': ['tenant_nic']}},
533 'segmentation_type': 'vlan',
534 'overlay_id_range': 'vlan:500:600'
537 [{'nic_mapping': {'controller':
538 {'members': ['ext_nic']},
540 {'members': ['ext_nic']}}}]}}
542 inv.get_node_counts.return_value = (3, 2)
545 saved_stdout = sys.stdout
549 ns.enabled_network_list = ['external', 'tenant']
550 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
552 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
553 output = out.getvalue().strip()
554 assert_in('NeutronNetworkVLANRanges: '
555 'vlan:500:600,datacentre:1:1000', output)
556 assert_in('NeutronNetworkType: vlan', output)
557 assert_in('NeutronBridgeMappings: '
558 'vlan:br-vlan,datacentre:br-ex', output)
559 assert_not_in('OpenDaylightProviderMappings', output)
562 sys.stdout = saved_stdout
564 @patch('apex.overcloud.deploy.fileinput')
565 @patch('apex.overcloud.deploy.shutil')
566 def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
567 mock_fileinput.input.return_value = \
568 ['NeutronNetworkVLANRanges',
569 'NeutronNetworkType',
570 'NeutronBridgeMappings',
571 'OpenDaylightProviderMappings']
572 ds = {'global_params': {'ha_enabled': False},
574 {'sdn_controller': 'opendaylight',
578 ns_dict = {'domain_name': 'test.domain',
581 {'nic_mapping': {'controller':
582 {'members': ['tenant_nic']},
584 {'members': ['tenant_nic']}},
585 'segmentation_type': 'vlan',
586 'overlay_id_range': 'vlan:500:600'
589 [{'nic_mapping': {'controller':
590 {'members': ['ext_nic']},
592 {'members': ['ext_nic']}}}]}}
594 inv.get_node_counts.return_value = (3, 2)
597 saved_stdout = sys.stdout
601 ns.enabled_network_list = ['external', 'tenant']
602 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
604 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
605 output = out.getvalue().strip()
606 assert_in('NeutronNetworkVLANRanges: '
607 'vlan:500:600,datacentre:1:1000', output)
608 assert_in('NeutronNetworkType: vlan', output)
609 assert_in('NeutronBridgeMappings: '
610 'vlan:br-vlan,datacentre:br-ex', output)
611 assert_in('OpenDaylightProviderMappings: '
612 'vlan:br-vlan,datacentre:br-ex', output)
615 sys.stdout = saved_stdout
617 def test_generate_ceph_key(self):
618 assert_equal(len(generate_ceph_key()), 40)
620 @patch('apex.overcloud.deploy.generate_ceph_key')
621 @patch('apex.overcloud.deploy.fileinput')
622 @patch('apex.overcloud.deploy.os.path.isfile')
623 @patch('builtins.open', mock_open())
624 def test_prep_storage_env(self, mock_isfile, mock_fileinput,
626 mock_fileinput.input.return_value = \
627 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
628 ds = {'deploy_options': {
629 'ceph_device': '/dev/sdx',
633 prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
635 @patch('apex.overcloud.deploy.utils.edit_tht_env')
636 @patch('apex.overcloud.deploy.generate_ceph_key')
637 @patch('apex.overcloud.deploy.fileinput')
638 @patch('apex.overcloud.deploy.os.path.isfile')
639 @patch('builtins.open', mock_open())
640 def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
641 mock_ceph_key, mock_edit_tht):
642 mock_fileinput.input.return_value = \
643 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
644 ds = {'deploy_options': {
645 'ceph_device': '/dev/sdx',
647 'os_version': 'master'
648 }, 'global_params': {'ha_enabled': False}}
649 ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
650 {'ip': '192.0.2.1'}}}
652 prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
654 'CephPoolDefaultSize': 2,
655 'CephAnsibleExtraConfig': {
656 'centos_package_dependencies': [],
657 'ceph_osd_docker_memory_limit': '1g',
658 'ceph_mds_docker_memory_limit': '1g'
660 'CephPoolDefaultPgNum': 32,
661 'CephAnsibleDisksConfig': {
662 'devices': ['/dev/sdx'],
664 'osd_scenario': 'collocated'
667 mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
668 'parameter_defaults',
671 @patch('apex.overcloud.deploy.os.path.isfile')
672 @patch('builtins.open', mock_open())
673 def test_prep_storage_env_raises(self, mock_isfile):
674 mock_isfile.return_value = False
675 ds = {'deploy_options': MagicMock()}
677 assert_raises(ApexDeployException, prep_storage_env, ds,
678 ns, virtual=False, tmp_dir='/tmp')
680 @patch('apex.overcloud.deploy.generate_ceph_key')
681 @patch('apex.overcloud.deploy.fileinput')
682 @patch('apex.overcloud.deploy.os.path.isfile')
683 @patch('builtins.open', mock_open())
684 def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
685 ds = {'deploy_options':
686 {'sdn_controller': 'opendaylight',
690 saved_stdout = sys.stdout
694 mock_fileinput.input.return_value = \
695 ['# NovaSchedulerDefaultFilters',
696 '# NovaSchedulerAvailableFilters',
697 '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
698 '#NeutronSriovNumVFs: \"ens20f2:5\"',
699 '#NovaPCIPassthrough:',
700 '# - devname: \"ens20f2\"',
701 '# physical_network: \"datacentre\"']
702 prep_sriov_env(ds, '/tmp')
703 output = out.getvalue().strip()
704 assert_in('NovaSchedulerDefaultFilters', output)
705 assert_in('NovaSchedulerAvailableFilters', output)
706 assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
707 assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
708 assert_in('NovaPCIPassthrough:', output)
709 assert_in('- devname: \"xxx\"', output)
710 assert_in('physical_network: \"nfv_sriov\"', output)
713 sys.stdout = saved_stdout
715 @patch('apex.overcloud.deploy.os.path.isfile')
716 @patch('builtins.open', mock_open())
717 def test_prep_sriov_env_raises(self, mock_isfile):
718 ds_opts = {'sriov': True}
719 ds = {'deploy_options': MagicMock()}
720 ds['deploy_options'].__getitem__.side_effect = \
721 lambda i: ds_opts.get(i, MagicMock())
722 mock_isfile.return_value = False
723 ds = {'deploy_options': MagicMock()}
724 assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
726 def test_external_network_cmds(self):
727 ds = {'deploy_options':
728 {'sdn_controller': 'opendaylight',
733 ns_dict = {'networks':
734 {'external': [{'floating_ip_range': (0, 1),
736 {'compute': {'vlan': 'native'}},
740 ns.enabled_network_list = ['external']
741 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
742 cmds = ' '.join(external_network_cmds(ns, ds))
743 assert_in('--external', cmds)
744 assert_in('--allocation-pool start=0,end=1', cmds)
745 assert_in('--gateway gw', cmds)
746 assert_in('--network external', cmds)
747 assert_in('--provider-physical-network datacentre', cmds)
749 def test_external_network_cmds_nosdn_fdio(self):
750 ds = {'deploy_options':
751 {'sdn_controller': False,
752 'dataplane': 'fdio'}}
756 ns_dict = {'networks':
757 {'external': [{'floating_ip_range': (0, 1),
759 {'compute': {'vlan': 'native'}},
763 ns.enabled_network_list = ['external']
764 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
765 cmds = ' '.join(external_network_cmds(ns, ds))
766 assert_in('--external', cmds)
767 assert_in('--allocation-pool start=0,end=1', cmds)
768 assert_in('--gateway gw', cmds)
769 assert_in('--network external', cmds)
770 assert_in('--provider-physical-network external', cmds)
772 def test_external_network_cmds_no_ext(self):
773 ds = {'deploy_options':
774 {'sdn_controller': 'opendaylight',
782 {'introspection_range': (0, 1),
784 {'compute': {'vlan': '123'}},
788 ns.enabled_network_list = ['admin']
789 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
790 cmds = ' '.join(external_network_cmds(ns, ds))
791 assert_in('--external', cmds)
792 assert_in('--allocation-pool start=0,end=1', cmds)
793 assert_in('--network external', cmds)
794 assert_in('--provider-network-type vlan', cmds)
796 @patch('apex.overcloud.deploy.parsers')
797 def test_create_congress_cmds(self, mock_parsers):
798 assert_greater(len(create_congress_cmds('overcloud_file')), 0)
800 @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
801 def test_create_congress_cmds_raises(self, mock_parsers):
802 mock_parsers.return_value.__getitem__.side_effect = KeyError()
803 assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
805 def test_get_docker_sdn_files(self):
806 ds_opts = {'ha_enabled': True,
813 'sdn_controller': 'opendaylight',
814 'os_version': 'queens'
816 output = get_docker_sdn_files(ds_opts)
817 compare = ['/usr/share/openstack-tripleo-heat-templates/'
818 'environments/services/neutron-opendaylight.yaml',
819 '/usr/share/openstack-tripleo-heat-templates/environments'
820 '/services/neutron-bgpvpn-opendaylight.yaml']
821 self.assertEqual(output, compare)