diff --git a/tripleoclient/tests/test_utils.py b/tripleoclient/tests/test_utils.py index 6962af8f6..2628819b2 100644 --- a/tripleoclient/tests/test_utils.py +++ b/tripleoclient/tests/test_utils.py @@ -1971,3 +1971,24 @@ class TestGetCtlplaneAttrs(base.TestCase): } } self.assertEqual(expected, utils.get_ctlplane_attrs()) + + +class TestGetHostEntry(base.TestCase): + + @mock.patch('subprocess.Popen', autospec=True) + def test_get_undercloud_host_entry(self, mock_popen): + mock_process = mock.Mock() + mock_hosts = { + 'fd12::1 uc.ctlplane.localdomain uc.ctlplane': + 'fd12::1 uc.ctlplane.localdomain uc.ctlplane', + 'fd12::1 uc.ctlplane.localdomain uc.ctlplane\n' + 'fd12::1 uc.ctlplane.localdomain uc.ctlplane': + 'fd12::1 uc.ctlplane.localdomain uc.ctlplane', + '1.2.3.4 uc.ctlplane foo uc.ctlplane bar uc.ctlplane': + '1.2.3.4 uc.ctlplane foo bar' + } + for value, expected in mock_hosts.items(): + mock_process.communicate.return_value = (value, '') + mock_process.returncode = 0 + mock_popen.return_value = mock_process + self.assertEqual(expected, utils.get_undercloud_host_entry()) diff --git a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py index c11f52ac3..454594a0b 100644 --- a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py +++ b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py @@ -131,8 +131,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True, return_value={}) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @@ -251,8 +250,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.workflows.deployment.create_overcloudrc', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.workflows.parameters.invoke_plan_env_workflows', autospec=True) @@ -354,8 +352,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): 'process_environment_and_files', autospec=True) @mock.patch('os.chdir') @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @@ -442,8 +439,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): 'process_environment_and_files', autospec=True) @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, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @@ -717,8 +713,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): except ValueError as value_error: self.assertIn('/fake/path', str(value_error)) - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'create_env_files', autospec=True) @@ -757,8 +752,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): autospec=True, return_value={}) @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, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @@ -866,8 +860,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True, return_value={}) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @@ -984,8 +977,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_rc_params', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'create_env_files', autospec=True) @@ -1023,8 +1015,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_rc_params', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'create_env_files', autospec=True) @@ -1064,8 +1055,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_rc_params', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'create_env_files', autospec=True) @@ -1106,8 +1096,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): 'create_env_files', autospec=True) @mock.patch('tripleoclient.utils.get_rc_params', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'deploy_tripleo_heat_templates', autospec=True) @@ -1148,8 +1137,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): 'create_env_files', autospec=True) @mock.patch('tripleoclient.utils.get_rc_params', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.utils.create_tempest_deployer_input', autospec=True) @@ -1194,8 +1182,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_rc_params', autospec=True) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'create_env_files', autospec=True) @@ -1248,8 +1235,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True, return_value={}) @mock.patch('tripleoclient.utils.copy_clouds_yaml') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_heat_deploy', autospec=True) @@ -1317,8 +1303,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_update_parameters') - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'create_env_files', autospec=True) @@ -1485,24 +1470,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): verbosity=3, workdir=mock.ANY) - @mock.patch('subprocess.Popen', autospec=True) - def test__get_undercloud_host_entry(self, mock_popen): - mock_process = mock.Mock() - mock_hosts = { - 'fd12::1 uc.ctlplane.localdomain uc.ctlplane': - 'fd12::1 uc.ctlplane.localdomain uc.ctlplane', - 'fd12::1 uc.ctlplane.localdomain uc.ctlplane\n' - 'fd12::1 uc.ctlplane.localdomain uc.ctlplane': - 'fd12::1 uc.ctlplane.localdomain uc.ctlplane', - '1.2.3.4 uc.ctlplane foo uc.ctlplane bar uc.ctlplane': - '1.2.3.4 uc.ctlplane foo bar' - } - for value, expected in mock_hosts.items(): - mock_process.communicate.return_value = (value, '') - mock_process.returncode = 0 - mock_popen.return_value = mock_process - self.assertEqual(expected, self.cmd._get_undercloud_host_entry()) - def test_check_limit_warning(self): mock_warning = mock.MagicMock() mock_log = mock.MagicMock() diff --git a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py index ebd8140d4..84c8b1caf 100644 --- a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py +++ b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py @@ -70,8 +70,7 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare): @mock.patch('tripleoclient.utils.ensure_run_as_normal_user') @mock.patch('tripleoclient.utils.prompt_user_for_confirmation', return_value=True) - @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' - '_get_undercloud_host_entry', autospec=True, + @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') @mock.patch('tripleoclient.v1.overcloud_update.UpdatePrepare.log', autospec=True) diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index 0c0dea139..4e443f832 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -2714,3 +2714,34 @@ def get_ctlplane_attrs(): }) return net_attributes_map + + +def cleanup_host_entry(entry): + # remove any tab or space excess + entry_stripped = re.sub('[ \t]+', ' ', str(entry).rstrip()) + # removes any duplicate identical lines + unique_lines = list(set(entry_stripped.splitlines())) + ret = '' + for line in unique_lines: + # remove any duplicate word + hosts_unique = (' '.join( + collections.OrderedDict((w, w) for w in line.split()).keys())) + if hosts_unique != '': + ret += hosts_unique + '\n' + return ret.rstrip('\n') + + +def get_undercloud_host_entry(): + """Get hosts entry for undercloud ctlplane network + + The host entry will be added on overcloud nodes + """ + ctlplane_hostname = '.'.join([get_short_hostname(), 'ctlplane']) + cmd = ['getent', 'hosts', ctlplane_hostname] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, + universal_newlines=True) + out, err = process.communicate() + if process.returncode != 0: + raise exceptions.DeploymentError('No entry for %s in /etc/hosts' + % ctlplane_hostname) + return cleanup_host_entry(out) diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index b985f0b64..955cdc10b 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -14,7 +14,6 @@ # import argparse -from collections import OrderedDict import os import os.path from oslo_config import cfg @@ -22,10 +21,8 @@ from oslo_log import log as logging from oslo_utils import excutils from prettytable import PrettyTable from pwd import getpwuid -import re import shutil import six -import subprocess import time import yaml @@ -121,41 +118,12 @@ class DeployOvercloud(command.Command): parameters[param] = getattr(args, arg) parameters[ - 'UndercloudHostsEntries'] = [self._get_undercloud_host_entry()] + 'UndercloudHostsEntries'] = [utils.get_undercloud_host_entry()] parameters['CtlplaneNetworkAttributes'] = utils.get_ctlplane_attrs() return parameters - def _cleanup_host_entry(self, entry): - # remove any tab or space excess - entry_stripped = re.sub('[ \t]+', ' ', str(entry).rstrip()) - # removes any duplicate identical lines - unique_lines = list(set(entry_stripped.splitlines())) - ret = '' - for line in unique_lines: - # remove any duplicate word - hosts_unique = (' '.join( - OrderedDict((w, w) for w in line.split()).keys())) - if hosts_unique != '': - ret += hosts_unique + '\n' - return ret.rstrip('\n') - - def _get_undercloud_host_entry(self): - """Get hosts entry for undercloud ctlplane network - - The host entry will be added on overcloud nodes - """ - ctlplane_hostname = '.'.join([utils.get_short_hostname(), 'ctlplane']) - cmd = ['getent', 'hosts', ctlplane_hostname] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, - universal_newlines=True) - out, err = process.communicate() - if process.returncode != 0: - raise exceptions.DeploymentError('No entry for %s in /etc/hosts' - % ctlplane_hostname) - return self._cleanup_host_entry(out) - def _check_limit_skiplist_warning(self, env): if env.get('parameter_defaults').get('DeploymentServerBlacklist'): msg = _('[WARNING] DeploymentServerBlacklist is defined and will '