diff --git a/tripleoclient/tests/test_utils.py b/tripleoclient/tests/test_utils.py index 27f9e1485..f1b6e2b79 100644 --- a/tripleoclient/tests/test_utils.py +++ b/tripleoclient/tests/test_utils.py @@ -444,6 +444,89 @@ class TestWaitForStackUtil(TestCase): result = utils.wait_for_stack_ready(self.mock_orchestration, 'stack') self.assertEqual(False, result) + def test_check_heat_network_config(self): + stack_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'val', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'val', + } + env_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'val', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'val', + } + mock_stack = mock.MagicMock() + mock_stack.environment = mock.MagicMock() + mock_stack.environment.return_value = { + 'resource_registry': stack_reg, + } + env = { + 'resource_registry': env_reg + } + + self.assertRaises(exceptions.InvalidConfiguration, + utils.check_nic_config_with_ansible, + mock_stack, env) + + def test_check_heat_missing_network_config(self): + stack_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'val', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'val', + } + env_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'OS::Heat::None', + } + mock_stack = mock.MagicMock() + mock_stack.environment = mock.MagicMock() + mock_stack.environment.return_value = { + 'resource_registry': stack_reg, + } + env = { + 'resource_registry': env_reg + } + + self.assertRaises(exceptions.InvalidConfiguration, + utils.check_nic_config_with_ansible, + mock_stack, env) + + def test_check_heat_none_network_config(self): + stack_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'val', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'val', + } + env_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'OS::Heat::None', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'OS::Heat::None', + } + mock_stack = mock.MagicMock() + mock_stack.environment = mock.MagicMock() + mock_stack.environment.return_value = { + 'resource_registry': stack_reg, + } + env = { + 'resource_registry': env_reg, + 'parameter_defaults': {'NetworkConfigWithAnsible': True} + } + utils.check_nic_config_with_ansible(mock_stack, env) + + def test_check_heat_network_config_no_ansible(self): + stack_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'val', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'val', + } + env_reg = { + 'OS::TripleO::Controller::Net::SoftwareConfig': 'val', + 'OS::TripleO::Compute::Net::SoftwareConfig': 'val', + } + mock_stack = mock.MagicMock() + mock_stack.environment = mock.MagicMock() + mock_stack.environment.return_value = { + 'resource_registry': stack_reg, + } + env = { + 'resource_registry': env_reg, + 'parameter_defaults': {'NetworkConfigWithAnsible': False} + } + utils.check_nic_config_with_ansible(mock_stack, env) + def test_check_stack_network_matches_env_files(self): stack_reg = { 'OS::TripleO::Network': 'val', diff --git a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py index 0c2e9293b..bc40a0cf3 100644 --- a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py +++ b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py @@ -171,6 +171,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.cmd._download_missing_files_from_plan = self.real_download_missing shutil.rmtree = self.real_shutil + @mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_get_ctlplane_attrs', autospec=True, return_value={}) @mock.patch('tripleoclient.utils.copy_clouds_yaml') @@ -195,7 +196,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): mock_events, mock_stack_network_check, mock_ceph_fsid, mock_get_undercloud_host_entry, mock_copy, - mock_get_ctlplane_attrs): + mock_get_ctlplane_attrs, mock_nic_ansible): fixture = deployment.DeploymentWorkflowFixture() self.useFixture(fixture) clients = self.app.client_manager @@ -605,6 +606,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): object_client.put_container.assert_called_once_with( 'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'}) + @mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_get_undercloud_host_entry', autospec=True, @@ -627,7 +629,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): mock_events, mock_stack_network_check, mock_ceph_fsid, mock_get_undercloud_host_entry, - mock_copy): + mock_copy, mock_nic_ansible): fixture = deployment.DeploymentWorkflowFixture() self.useFixture(fixture) plane_management_fixture = deployment.PlanManagementFixture() @@ -695,6 +697,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.cmd.take_action, parsed_args) self.assertFalse(mock_deploy_tht.called) + @mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @@ -707,7 +710,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): def test_environment_dirs(self, mock_deploy_heat, mock_update_parameters, mock_post_config, mock_stack_network_check, mock_ceph_fsid, - mock_copy): + mock_copy, mock_nic_ansible): fixture = deployment.DeploymentWorkflowFixture() self.useFixture(fixture) plane_management_fixture = deployment.PlanManagementFixture() @@ -1002,6 +1005,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.assertFalse(utils_fixture.mock_deploy_tht.called) self.assertFalse(mock_create_tempest_deployer_input.called) + @mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_get_undercloud_host_entry', autospec=True, @@ -1015,7 +1019,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): def test_answers_file(self, mock_rmtree, mock_tmpdir, mock_heat_deploy, mock_stack_network_check, mock_ceph_fsid, mock_get_undercloud_host_entry, - mock_copy): + mock_copy, mock_nic_ansible): fixture = deployment.DeploymentWorkflowFixture() self.useFixture(fixture) clients = self.app.client_manager @@ -1090,6 +1094,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): object_client.put_container.assert_called_once_with( 'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'}) + @mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @@ -1106,7 +1111,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): mock_create_parameters_env, mock_stack_network_check, mock_ceph_fsid, - mock_get_undercloud_host_entry): + mock_get_undercloud_host_entry, + mock_nic_ansible): plane_management_fixture = deployment.PlanManagementFixture() self.useFixture(plane_management_fixture) clients = self.app.client_manager @@ -1507,6 +1513,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.assertTrue(fixture.mock_config_download.called) mock_copy.assert_called_once() + @mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_get_ctlplane_attrs', autospec=True, return_value={}) @mock.patch('tripleoclient.utils.copy_clouds_yaml') @@ -1526,7 +1533,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self, mock_plan_man, mock_hc, mock_stack_network_check, mock_ceph_fsid, mock_hd, mock_overcloudrc, mock_get_undercloud_host_entry, mock_copy, - mock_get_ctlplane_attrs): + mock_get_ctlplane_attrs, mock_nic_ansible): fixture = deployment.DeploymentWorkflowFixture() self.useFixture(fixture) utils_fixture = deployment.UtilsOvercloudFixture() diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index de7849787..d0146e923 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -1057,6 +1057,42 @@ def check_ceph_fsid_matches_env_files(stack, environment): stack_ceph_fsid)) +def check_nic_config_with_ansible(stack, environment): + registry = environment.get('resource_registry', {}) + stack_registry = {} + is_ansible_config_stack = True + if stack: + stack_registry = stack.environment().get( + 'resource_registry', {}) + is_ansible_config_stack = stack.environment().get( + 'parameter_defaults', {}).get( + 'NetworkConfigWithAnsible', True) + + is_ansible_config = environment.get( + 'parameter_defaults', {}).get( + 'NetworkConfigWithAnsible', is_ansible_config_stack) + + nic_configs_in_update = set() + if is_ansible_config: + for k, v in registry.items(): + if k.endswith('Net::SoftwareConfig'): + if v != 'OS::Heat::None': + raise exceptions.InvalidConfiguration( + "DEPRECATED: Old heat nic configs are used, " + "Migrate to ansible jinja templates or use " + "'NetworkConfigWithAnsible: false' " + "in 'parameter_defaults'.") + nic_configs_in_update.add(k) + for k, v in stack_registry.items(): + if (k.endswith('Net::SoftwareConfig') and v != 'OS::Heat::None' + and k not in nic_configs_in_update): + raise exceptions.InvalidConfiguration( + "DEPRECATED: Old heat nic configs are used, " + "Migrate to ansible jinja templates or use " + "'NetworkConfigWithAnsible: false' " + "in 'parameter_defaults'.") + + def check_stack_network_matches_env_files(stack, environment): """Check stack against proposed env files to ensure non-breaking change diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index 14cc5d4b6..d488c628a 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -533,6 +533,9 @@ class DeployOvercloud(command.Command): tht_root, parsed_args.stack) template_utils.deep_update(env, bp_cleanup) + # check migration to new nic config with ansible + utils.check_nic_config_with_ansible(stack, env) + # FIXME(shardy) It'd be better to validate this via mistral # e.g part of the plan create/update workflow number_controllers = int(parameters.get('ControllerCount', 0))