Merge "Enable SFC scenarios for Gambia"
[apex.git] / apex / tests / test_apex_overcloud_deploy.py
1 ##############################################################################
2 # Copyright (c) 2016 Dan Radez (dradez@redhat.com) (Red Hat)
3 #
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 ##############################################################################
9
10 import mock
11 import os
12 import sys
13 import unittest
14
15 from mock import patch
16 from mock import MagicMock
17 from mock import mock_open
18 from io import StringIO
19
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
34
35 from nose.tools import (
36     assert_regexp_matches,
37     assert_raises,
38     assert_in,
39     assert_not_in,
40     assert_greater,
41     assert_equal)
42
43
44 class TestOvercloudDeploy(unittest.TestCase):
45     @classmethod
46     def setup_class(cls):
47         """This method is run once for each class before any tests are run"""
48
49     @classmethod
50     def teardown_class(cls):
51         """This method is run once for each class _after_ all tests are run"""
52
53     def setup(self):
54         """This method is run once before _each_ test method is executed"""
55
56     def teardown(self):
57         """This method is run once after _each_ test method is executed"""
58
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])
64
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), [])
70
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])
77
78     def test_build_sdn_env_list_with_string(self):
79         ds = {'sdn_controller': 'opendaylight',
80               'sriov': 'xxx'}
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)
85
86     def test_build_sdn_env_list_with_default(self):
87         ds = {'sdn_controller': 'opendaylight',
88               'vpn': True}
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)
93
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,
99                                mock_prep_sriov):
100         mock_sdn_list.return_value = []
101         ds = {'deploy_options':
102               {'ha_enabled': True,
103                'congress': True,
104                'tacker': True,
105                'containers': False,
106                'barometer': True,
107                'ceph': False,
108                'sriov': False,
109                'vim': 'openstack'
110                },
111               'global_params': MagicMock()}
112
113         ns = {'ntp': ['ntp']}
114         inv = MagicMock()
115         inv.get_node_counts.return_value = (3, 2)
116         virt = True
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)
125
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,
130                                               mock_prep_sriov):
131         ds = {'deploy_options':
132               {'ha_enabled': True,
133                'congress': False,
134                'tacker': False,
135                'containers': True,
136                'barometer': False,
137                'vpn': False,
138                'ceph': True,
139                'sdn_controller': 'opendaylight',
140                'sriov': False,
141                'os_version': 'queens',
142                'vim': 'openstack'
143                },
144               'global_params': MagicMock()}
145
146         ns = {'ntp': ['ntp']}
147         inv = MagicMock()
148         inv.get_node_counts.return_value = (3, 2)
149         virt = True
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)
170
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']}
185         inv = MagicMock()
186         inv.get_node_counts.return_value = (3, 2)
187         virt = False
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)
196
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,
203                         mock_inject_odl):
204         ds_opts = {'dataplane': 'fdio',
205                    'sdn_controller': 'opendaylight',
206                    'odl_version': 'master',
207                    'vpn': False,
208                    'sriov': False}
209         ds = {'deploy_options': MagicMock(),
210               'global_params': MagicMock()}
211         ds['deploy_options'].__getitem__.side_effect = \
212             lambda i: ds_opts.get(i, MagicMock())
213         ns = 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()
217
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,
223                                   mock_virt_utils):
224         ds_opts = {'dataplane': 'fdio',
225                    'vpn': False,
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())
231         ns = MagicMock()
232         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
233         mock_virt_utils.virt_customize.assert_called()
234
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',
244                    'vpn': False,
245                    'sfc': False,
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()
254         ns = 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()
258
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()
278         ns = 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'])
287
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()
307         ns = 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'])
315
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,
323                                         mock_oc_builder):
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())
331         ns = 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()
335
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,
341                                 mock_virt_utils):
342         ds_opts = {'dataplane': 'ovs',
343                    'vpn': False,
344                    'sfc': False,
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())
350         ns = MagicMock()
351         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
352         mock_virt_utils.virt_customize.assert_called()
353
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,
362                                     mock_inject_quagga):
363         ds_opts = {'dataplane': 'ovs',
364                    'sdn_controller': 'opendaylight',
365                    'vpn': True,
366                    'sfc': False,
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()
375         ns = 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()
380
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',
392                        'vpn': False,
393                        'sfc': True,
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()
402             ns = 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()
407
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')
413
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)
418
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]
434             }}
435         ds = {'global_params': {'ha_enabled': False},
436               'deploy_options':
437               {'sdn_controller': 'opendaylight',
438                'odl_vpp_routing_node': 'test',
439                'dataplane': 'ovs_dpdk',
440                'sriov': 'xxx',
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',
447                    'networks':
448                    {'tenant':
449                     {'nic_mapping': {'controller':
450                                      {'members': ['tenant_nic']},
451                                      'compute':
452                                      {'members': ['tenant_nic']}}},
453                     'external':
454                     [{'nic_mapping': {'controller':
455                                       {'members': ['ext_nic']},
456                                       'compute':
457                                       {'members': ['ext_nic']}}}]}}
458         inv = MagicMock()
459         inv.get_node_counts.return_value = (1, 0)
460         try:
461             # Swap stdout
462             saved_stdout = sys.stdout
463             out = StringIO()
464             sys.stdout = out
465             ns = MagicMock()
466             ns.enabled_network_list = ['external', 'tenant']
467             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
468             # run test
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],
478                 }},
479                 mock.ANY, default_flow_style=False
480             )
481         finally:
482             # put stdout back
483             sys.stdout = saved_stdout
484
485     @patch('apex.overcloud.deploy.fileinput')
486     @patch('apex.overcloud.deploy.shutil')
487     @patch('builtins.open', mock_open())
488     def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
489         mock_fileinput.input.return_value = \
490             ['NeutronVPPAgentPhysnets']
491         ds = {'global_params': {'ha_enabled': False},
492               'deploy_options':
493               {'sdn_controller': False,
494                'dataplane': 'fdio',
495                'sriov': 'xxx',
496                'performance': {'Compute': {},
497                                'Controller': {}}}}
498         ns_dict = {'domain_name': 'test.domain',
499                    'networks':
500                    {'tenant':
501                     {'nic_mapping': {'controller':
502                                      {'members': ['tenant_nic']},
503                                      'compute':
504                                      {'members': ['tenant_nic']}}},
505                     'external':
506                     [{'nic_mapping': {'controller':
507                                       {'members': ['ext_nic']},
508                                       'compute':
509                                       {'members': ['ext_nic']}}}]}}
510         inv = MagicMock()
511         inv.get_node_counts.return_value = (3, 2)
512         try:
513             # Swap stdout
514             saved_stdout = sys.stdout
515             out = StringIO()
516             sys.stdout = out
517             ns = MagicMock()
518             ns.enabled_network_list = ['external', 'tenant']
519             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
520             # run test
521             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
522             output = out.getvalue().strip()
523             assert_in('NeutronVPPAgentPhysnets: '
524                       '\'datacentre:tenant_nic,external:tap0\'',
525                       output)
526             assert_in('NeutronVPPAgentPhysnets', output)
527         finally:
528             # put stdout back
529             sys.stdout = saved_stdout
530
531     @patch('apex.overcloud.deploy.fileinput')
532     @patch('apex.overcloud.deploy.shutil')
533     @patch('builtins.open', mock_open())
534     def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
535         mock_fileinput.input.return_value = \
536             ['OS::TripleO::Services::NeutronDhcpAgent',
537              'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
538         ds = {'global_params': {'ha_enabled': False},
539               'deploy_options':
540               {'sdn_controller': 'opendaylight',
541                'dataplane': 'fdio',
542                'sriov': 'xxx',
543                'dvr': True}}
544         ns_dict = {'domain_name': 'test.domain',
545                    'networks':
546                    {'tenant':
547                     {'nic_mapping': {'controller':
548                                      {'members': ['tenant_nic']},
549                                      'compute':
550                                      {'members': ['tenant_nic']}}},
551                     'external':
552                     [{'nic_mapping': {'controller':
553                                       {'members': ['ext_nic']},
554                                       'compute':
555                                       {'members': ['ext_nic']}}}]}}
556         inv = MagicMock()
557         inv.get_node_counts.return_value = (3, 2)
558         try:
559             # Swap stdout
560             saved_stdout = sys.stdout
561             out = StringIO()
562             sys.stdout = out
563             ns = MagicMock()
564             ns.enabled_network_list = ['external', 'tenant']
565             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
566             # run test
567             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
568             output = out.getvalue().strip()
569             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
570         finally:
571             # put stdout back
572             sys.stdout = saved_stdout
573
574     @patch('apex.overcloud.deploy.fileinput')
575     @patch('apex.overcloud.deploy.shutil')
576     @patch('builtins.open', mock_open())
577     def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
578         mock_fileinput.input.return_value = \
579             ['NeutronNetworkVLANRanges',
580              'NeutronNetworkType', 'NeutronBridgeMappings']
581         ds = {'global_params': {'ha_enabled': False},
582               'deploy_options':
583               {'sdn_controller': False,
584                'dataplane': 'ovs',
585                'sriov': 'xxx',
586                'dvr': True}}
587         ns_dict = {'domain_name': 'test.domain',
588                    'networks':
589                    {'tenant':
590                     {'nic_mapping': {'controller':
591                                      {'members': ['tenant_nic']},
592                                      'compute':
593                                      {'members': ['tenant_nic']}},
594                      'segmentation_type': 'vlan',
595                      'overlay_id_range': 'vlan:500:600'
596                      },
597                     'external':
598                     [{'nic_mapping': {'controller':
599                                       {'members': ['ext_nic']},
600                                       'compute':
601                                       {'members': ['ext_nic']}}}]}}
602         inv = MagicMock()
603         inv.get_node_counts.return_value = (3, 2)
604         try:
605             # Swap stdout
606             saved_stdout = sys.stdout
607             out = StringIO()
608             sys.stdout = out
609             ns = MagicMock()
610             ns.enabled_network_list = ['external', 'tenant']
611             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
612             # run test
613             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
614             output = out.getvalue().strip()
615             assert_in('NeutronNetworkVLANRanges: '
616                       'vlan:500:600,datacentre:1:1000', output)
617             assert_in('NeutronNetworkType: vlan', output)
618             assert_in('NeutronBridgeMappings: '
619                       'vlan:br-vlan,datacentre:br-ex', output)
620             assert_not_in('OpenDaylightProviderMappings', output)
621         finally:
622             # put stdout back
623             sys.stdout = saved_stdout
624
625     @patch('apex.overcloud.deploy.fileinput')
626     @patch('apex.overcloud.deploy.shutil')
627     @patch('builtins.open', mock_open())
628     def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
629         mock_fileinput.input.return_value = \
630             ['NeutronNetworkVLANRanges',
631              'NeutronNetworkType',
632              'NeutronBridgeMappings',
633              'OpenDaylightProviderMappings']
634         ds = {'global_params': {'ha_enabled': False},
635               'deploy_options':
636               {'sdn_controller': 'opendaylight',
637                'dataplane': 'ovs',
638                'sriov': 'xxx',
639                'dvr': True}}
640         ns_dict = {'domain_name': 'test.domain',
641                    'networks':
642                    {'tenant':
643                     {'nic_mapping': {'controller':
644                                      {'members': ['tenant_nic']},
645                                      'compute':
646                                      {'members': ['tenant_nic']}},
647                      'segmentation_type': 'vlan',
648                      'overlay_id_range': 'vlan:500:600'
649                      },
650                     'external':
651                     [{'nic_mapping': {'controller':
652                                       {'members': ['ext_nic']},
653                                       'compute':
654                                       {'members': ['ext_nic']}}}]}}
655         inv = MagicMock()
656         inv.get_node_counts.return_value = (3, 2)
657         try:
658             # Swap stdout
659             saved_stdout = sys.stdout
660             out = StringIO()
661             sys.stdout = out
662             ns = MagicMock()
663             ns.enabled_network_list = ['external', 'tenant']
664             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
665             # run test
666             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
667             output = out.getvalue().strip()
668             assert_in('NeutronNetworkVLANRanges: '
669                       'vlan:500:600,datacentre:1:1000', output)
670             assert_in('NeutronNetworkType: vlan', output)
671             assert_in('NeutronBridgeMappings: '
672                       'vlan:br-vlan,datacentre:br-ex', output)
673             assert_in('OpenDaylightProviderMappings: '
674                       'vlan:br-vlan,datacentre:br-ex', output)
675         finally:
676             # put stdout back
677             sys.stdout = saved_stdout
678
679     def test_generate_ceph_key(self):
680         assert_equal(len(generate_ceph_key()), 40)
681
682     @patch('apex.overcloud.deploy.generate_ceph_key')
683     @patch('apex.overcloud.deploy.fileinput')
684     @patch('apex.overcloud.deploy.os.path.isfile')
685     @patch('builtins.open', mock_open())
686     def test_prep_storage_env(self, mock_isfile, mock_fileinput,
687                               mock_ceph_key):
688         mock_fileinput.input.return_value = \
689             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
690         ds = {'deploy_options': {
691             'ceph_device': '/dev/sdx',
692             'containers': False
693         }}
694         ns = {}
695         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
696
697     @patch('apex.overcloud.deploy.utils.edit_tht_env')
698     @patch('apex.overcloud.deploy.generate_ceph_key')
699     @patch('apex.overcloud.deploy.fileinput')
700     @patch('apex.overcloud.deploy.os.path.isfile')
701     @patch('builtins.open', mock_open())
702     def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
703                                          mock_ceph_key, mock_edit_tht):
704         mock_fileinput.input.return_value = \
705             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
706         ds = {'deploy_options': {
707               'ceph_device': '/dev/sdx',
708               'containers': True,
709               'os_version': 'master'
710               }, 'global_params': {'ha_enabled': False}}
711         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
712                                                {'ip': '192.0.2.1'}}}
713               }
714         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
715         ceph_params = {
716             'CephPoolDefaultSize': 2,
717             'CephAnsibleExtraConfig': {
718                 'centos_package_dependencies': [],
719                 'ceph_osd_docker_memory_limit': '1g',
720                 'ceph_mds_docker_memory_limit': '1g'
721             },
722             'CephPoolDefaultPgNum': 32,
723             'CephAnsibleDisksConfig': {
724                 'devices': ['/dev/sdx'],
725                 'journal_size': 512,
726                 'osd_scenario': 'collocated'
727             }
728         }
729         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
730                                          'parameter_defaults',
731                                          ceph_params)
732
733     @patch('apex.overcloud.deploy.os.path.isfile')
734     @patch('builtins.open', mock_open())
735     def test_prep_storage_env_raises(self, mock_isfile):
736         mock_isfile.return_value = False
737         ds = {'deploy_options': MagicMock()}
738         ns = {}
739         assert_raises(ApexDeployException, prep_storage_env, ds,
740                       ns, virtual=False, tmp_dir='/tmp')
741
742     @patch('apex.overcloud.deploy.generate_ceph_key')
743     @patch('apex.overcloud.deploy.fileinput')
744     @patch('apex.overcloud.deploy.os.path.isfile')
745     @patch('builtins.open', mock_open())
746     def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
747         ds = {'deploy_options':
748               {'sdn_controller': 'opendaylight',
749                'sriov': 'xxx'}}
750         try:
751             # Swap stdout
752             saved_stdout = sys.stdout
753             out = StringIO()
754             sys.stdout = out
755             # Run tests
756             mock_fileinput.input.return_value = \
757                 ['#  NovaSchedulerDefaultFilters',
758                  '#  NovaSchedulerAvailableFilters',
759                  '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
760                  '#NeutronSriovNumVFs: \"ens20f2:5\"',
761                  '#NovaPCIPassthrough:',
762                  '#  - devname: \"ens20f2\"',
763                  '#    physical_network: \"datacentre\"']
764             prep_sriov_env(ds, '/tmp')
765             output = out.getvalue().strip()
766             assert_in('NovaSchedulerDefaultFilters', output)
767             assert_in('NovaSchedulerAvailableFilters', output)
768             assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
769             assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
770             assert_in('NovaPCIPassthrough:', output)
771             assert_in('- devname: \"xxx\"', output)
772             assert_in('physical_network: \"nfv_sriov\"', output)
773         finally:
774             # put stdout back
775             sys.stdout = saved_stdout
776
777     @patch('apex.overcloud.deploy.os.path.isfile')
778     @patch('builtins.open', mock_open())
779     def test_prep_sriov_env_raises(self, mock_isfile):
780         ds_opts = {'sriov': True}
781         ds = {'deploy_options': MagicMock()}
782         ds['deploy_options'].__getitem__.side_effect = \
783             lambda i: ds_opts.get(i, MagicMock())
784         mock_isfile.return_value = False
785         ds = {'deploy_options': MagicMock()}
786         assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
787
788     def test_external_network_cmds(self):
789         ds = {'deploy_options':
790               {'sdn_controller': 'opendaylight',
791                'dataplane': 'ovs'}}
792
793         cidr = MagicMock()
794         cidr.version = 6
795         ns_dict = {'networks':
796                    {'external': [{'floating_ip_range': (0, 1),
797                                   'nic_mapping':
798                                   {'compute': {'vlan': 'native'}},
799                                   'gateway': 'gw',
800                                   'cidr': cidr}]}}
801         ns = MagicMock()
802         ns.enabled_network_list = ['external']
803         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
804         cmds = ' '.join(external_network_cmds(ns, ds))
805         assert_in('--external', cmds)
806         assert_in('--allocation-pool start=0,end=1', cmds)
807         assert_in('--gateway gw', cmds)
808         assert_in('--network external', cmds)
809         assert_in('--provider-physical-network datacentre', cmds)
810
811     def test_external_network_cmds_nosdn_fdio(self):
812         ds = {'deploy_options':
813               {'sdn_controller': False,
814                'dataplane': 'fdio'}}
815
816         cidr = MagicMock()
817         cidr.version = 6
818         ns_dict = {'networks':
819                    {'external': [{'floating_ip_range': (0, 1),
820                                   'nic_mapping':
821                                   {'compute': {'vlan': 'native'}},
822                                   'gateway': 'gw',
823                                   'cidr': cidr}]}}
824         ns = MagicMock()
825         ns.enabled_network_list = ['external']
826         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
827         cmds = ' '.join(external_network_cmds(ns, ds))
828         assert_in('--external', cmds)
829         assert_in('--allocation-pool start=0,end=1', cmds)
830         assert_in('--gateway gw', cmds)
831         assert_in('--network external', cmds)
832         assert_in('--provider-physical-network external', cmds)
833
834     def test_external_network_cmds_no_ext(self):
835         ds = {'deploy_options':
836               {'sdn_controller': 'opendaylight',
837                'dataplane': 'ovs'}}
838
839         cidr = MagicMock()
840         cidr.version = 6
841         ns_dict = {'apex':
842                    {'networks':
843                     {'admin':
844                      {'introspection_range': (0, 1),
845                       'nic_mapping':
846                       {'compute': {'vlan': '123'}},
847                       'gateway': 'gw',
848                       'cidr': cidr}}}}
849         ns = MagicMock()
850         ns.enabled_network_list = ['admin']
851         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
852         cmds = ' '.join(external_network_cmds(ns, ds))
853         assert_in('--external', cmds)
854         assert_in('--allocation-pool start=0,end=1', cmds)
855         assert_in('--network external', cmds)
856         assert_in('--provider-network-type vlan', cmds)
857
858     @patch('apex.overcloud.deploy.parsers')
859     def test_create_congress_cmds(self, mock_parsers):
860         assert_greater(len(create_congress_cmds('overcloud_file')), 0)
861
862     @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
863     def test_create_congress_cmds_raises(self, mock_parsers):
864         mock_parsers.return_value.__getitem__.side_effect = KeyError()
865         assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
866
867     def test_get_docker_sdn_files(self):
868         ds_opts = {'ha_enabled': True,
869                    'congress': True,
870                    'tacker': True,
871                    'containers': False,
872                    'barometer': True,
873                    'ceph': False,
874                    'vpn': True,
875                    'sdn_controller': 'opendaylight',
876                    'os_version': 'queens'
877                    }
878         output = get_docker_sdn_files(ds_opts)
879         compare = ['/usr/share/openstack-tripleo-heat-templates/'
880                    'environments/services/neutron-opendaylight.yaml',
881                    '/usr/share/openstack-tripleo-heat-templates/environments'
882                    '/services/neutron-bgpvpn-opendaylight.yaml']
883         self.assertEqual(output, compare)