From fc56cb1192f4ff16a6a20d74d63b6d0c81a0ab91 Mon Sep 17 00:00:00 2001 From: Jaganathan Palanisamy Date: Thu, 12 Dec 2019 11:13:49 +0530 Subject: [PATCH] Derive network config fails Derive network config fails for a role when using any interface routes with list_concat_unique in network configuration and no user inputs provided. Change-Id: I26bb26411f22c34ead1b2bfb2a616ddf65f69489 Closes-Bug: #1856124 (cherry picked from commit 81e823c6222b580ca78f4cfa92008e08b9926e1e) (cherry picked from commit 9e5bcae62c8bbcd952253a5611c49dd848a091d7) --- tripleo_common/actions/parameters.py | 10 ++ .../tests/actions/test_parameters.py | 145 ++++++++++++++++++ 2 files changed, 155 insertions(+) diff --git a/tripleo_common/actions/parameters.py b/tripleo_common/actions/parameters.py index 3df8a957d..731894de1 100644 --- a/tripleo_common/actions/parameters.py +++ b/tripleo_common/actions/parameters.py @@ -670,6 +670,16 @@ class GetNetworkConfigAction(templates.ProcessTemplatesAction): if isinstance(processed_data, actions.Result): return processed_data + # Default temporary value is used when no user input for any + # interface routes for the role networks to find network config. + role_networks = processed_data['template'].get('resources', {}).get( + self.role_name + 'GroupVars', {}).get('properties', {}).get( + 'value', {}).get('role_networks', []) + for nw in role_networks: + rt = nw + 'InterfaceRoutes' + if rt not in processed_data['environment']['parameter_defaults']: + processed_data['environment']['parameter_defaults'][rt] = [[]] + # stacks.preview method raises validation message if stack is # already deployed. here renaming container to get preview data. container_temp = self.container + "-TEMP" diff --git a/tripleo_common/tests/actions/test_parameters.py b/tripleo_common/tests/actions/test_parameters.py index 2ae78d7fa..c8552ac92 100644 --- a/tripleo_common/tests/actions/test_parameters.py +++ b/tripleo_common/tests/actions/test_parameters.py @@ -1500,6 +1500,151 @@ class GetNetworkConfigActionTest(base.TestCase): stack_name='overcloud-TEMP', ) + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'cache_set') + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'cache_get') + @mock.patch('heatclient.common.template_utils.' + 'process_multiple_environments_and_files') + @mock.patch('heatclient.common.template_utils.get_template_contents') + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'get_orchestration_client') + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'get_workflow_client') + @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') + def test_run_valid_network_config_with_no_interface_routes_inputs( + self, mock_get_object_client, mock_get_workflow_client, + mock_get_orchestration_client, mock_get_template_contents, + mock_process_multiple_environments_and_files, + mock_cache_get, + mock_cache_set): + + mock_ctx = mock.MagicMock() + swift = mock.MagicMock(url="http://test.com") + mock_env = yaml.safe_dump({ + 'temp_environment': 'temp_environment', + 'template': 'template', + 'environments': [{u'path': u'environments/test.yaml'}] + }, default_flow_style=False) + swift.get_object.side_effect = ( + ({}, mock_env), + swiftexceptions.ClientException('atest2'), + ({}, mock_env) + ) + mock_get_object_client.return_value = swift + + mock_get_template_contents.return_value = ({}, { + 'heat_template_version': '2016-04-30', + 'resources': {'ComputeGroupVars': {'properties': { + 'value': {'role_networks': ['InternalApi', 'Storage']} + } + }} + }) + mock_process_multiple_environments_and_files.return_value = ( + {}, {'parameter_defaults': {}}) + + mock_heat = mock.MagicMock() + mock_heat.stacks.preview.return_value = mock.Mock(resources=[{ + "resource_identity": {"stack_name": "overcloud-TEMP-Compute-0"}, + "resource_name": "OsNetConfigImpl", + "properties": {"config": "echo \'{\"network_config\": {}}\'" + " > /etc/os-net-config/config.json"} + }]) + + mock_get_orchestration_client.return_value = mock_heat + + mock_cache_get.return_value = None + expected = {"network_config": {}} + # Test + action = parameters.GetNetworkConfigAction(container='overcloud', + role_name='Compute') + result = action.run(mock_ctx) + self.assertEqual(expected, result) + mock_heat.stacks.preview.assert_called_once_with( + environment={'parameter_defaults': { + 'InternalApiInterfaceRoutes': [[]], + 'StorageInterfaceRoutes': [[]]}}, + files={}, + template={'heat_template_version': '2016-04-30', + 'resources': {'ComputeGroupVars': { + 'properties': {'value': { + 'role_networks': ['InternalApi', + 'Storage']}}}}}, + stack_name='overcloud-TEMP', + ) + + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'cache_set') + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'cache_get') + @mock.patch('heatclient.common.template_utils.' + 'process_multiple_environments_and_files') + @mock.patch('heatclient.common.template_utils.get_template_contents') + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'get_orchestration_client') + @mock.patch('tripleo_common.actions.base.TripleOAction.' + 'get_workflow_client') + @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') + def test_run_valid_network_config_with_interface_routes_inputs( + self, mock_get_object_client, mock_get_workflow_client, + mock_get_orchestration_client, mock_get_template_contents, + mock_process_multiple_environments_and_files, + mock_cache_get, + mock_cache_set): + + mock_ctx = mock.MagicMock() + swift = mock.MagicMock(url="http://test.com") + mock_env = yaml.safe_dump({ + 'temp_environment': 'temp_environment', + 'template': 'template', + 'environments': [{u'path': u'environments/test.yaml'}] + }, default_flow_style=False) + swift.get_object.side_effect = ( + ({}, mock_env), + swiftexceptions.ClientException('atest2'), + ({}, mock_env) + ) + mock_get_object_client.return_value = swift + + mock_get_template_contents.return_value = ({}, { + 'heat_template_version': '2016-04-30', + 'resources': {'ComputeGroupVars': {'properties': { + 'value': {'role_networks': ['InternalApi', 'Storage']}}}} + }) + mock_process_multiple_environments_and_files.return_value = ( + {}, {'parameter_defaults': { + 'InternalApiInterfaceRoutes': ['test1'], + 'StorageInterfaceRoutes': ['test2']}}) + + mock_heat = mock.MagicMock() + mock_heat.stacks.preview.return_value = mock.Mock(resources=[{ + "resource_identity": {"stack_name": "overcloud-TEMP-Compute-0"}, + "resource_name": "OsNetConfigImpl", + "properties": {"config": "echo \'{\"network_config\": {}}\'" + " > /etc/os-net-config/config.json"} + }]) + + mock_get_orchestration_client.return_value = mock_heat + + mock_cache_get.return_value = None + expected = {"network_config": {}} + # Test + action = parameters.GetNetworkConfigAction(container='overcloud', + role_name='Compute') + result = action.run(mock_ctx) + self.assertEqual(expected, result) + mock_heat.stacks.preview.assert_called_once_with( + environment={'parameter_defaults': { + 'InternalApiInterfaceRoutes': ['test1'], + 'StorageInterfaceRoutes': ['test2']}}, + files={}, + template={'heat_template_version': '2016-04-30', + 'resources': {'ComputeGroupVars': {'properties': { + 'value': {'role_networks': ['InternalApi', + 'Storage']}}}}}, + stack_name='overcloud-TEMP', + ) + @mock.patch('tripleo_common.actions.base.TripleOAction.' 'cache_set') @mock.patch('tripleo_common.actions.base.TripleOAction.'