From b86f03e3b5ac82ce8b6a92a07116647cfdf6cd79 Mon Sep 17 00:00:00 2001 From: Ben Nemec Date: Thu, 6 Jul 2017 15:49:08 +0000 Subject: [PATCH] Fail-fast if the undercloud-passwords.conf file is missing On undercloud updates/upgrades, if the undercloud-passwords.conf file was deleted or moved it will break some services because there are passwords that cannot be changed. This validates that the file exists and stops immediately with a message explaining the problem if the file is missing. Change-Id: Ic83d6afc8dc2128874b97cc414ea28272e7d6639 Closes-Bug: 1702709 (cherry picked from commit 74123de347437e6953429f27ab1a89adcf8ac085) --- instack_undercloud/tests/test_undercloud.py | 21 ++++++++++++++++++++- instack_undercloud/undercloud.py | 17 +++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/instack_undercloud/tests/test_undercloud.py b/instack_undercloud/tests/test_undercloud.py index 4ae6ca221..8dcf837b4 100644 --- a/instack_undercloud/tests/test_undercloud.py +++ b/instack_undercloud/tests/test_undercloud.py @@ -149,10 +149,13 @@ class TestUndercloud(BaseTestCase): @mock.patch('instack_undercloud.undercloud._check_sysctl') @mock.patch('instack_undercloud.undercloud._validate_network') @mock.patch('instack_undercloud.undercloud._validate_no_ip_change') - def test_validate_configuration(self, mock_vnic, mock_validate_network, + @mock.patch('instack_undercloud.undercloud._validate_passwords_file') + def test_validate_configuration(self, mock_vpf, mock_vnic, + mock_validate_network, mock_check_memory, mock_check_hostname, mock_check_sysctl): undercloud._validate_configuration() + self.assertTrue(mock_vpf.called) self.assertTrue(mock_vnic.called) self.assertTrue(mock_validate_network.called) self.assertTrue(mock_check_memory.called) @@ -310,6 +313,22 @@ class TestNoIPChange(BaseTestCase): undercloud._validate_no_ip_change() +@mock.patch('os.path.isfile') +class TestPasswordsFileExists(BaseTestCase): + def test_new_install(self, mock_isfile): + mock_isfile.side_effect = [False] + undercloud._validate_passwords_file() + + def test_update_exists(self, mock_isfile): + mock_isfile.side_effect = [True, True] + undercloud._validate_passwords_file() + + def test_update_missing(self, mock_isfile): + mock_isfile.side_effect = [True, False] + self.assertRaises(validator.FailedValidation, + undercloud._validate_passwords_file) + + class TestGenerateEnvironment(BaseTestCase): def setUp(self): super(TestGenerateEnvironment, self).setUp() diff --git a/instack_undercloud/undercloud.py b/instack_undercloud/undercloud.py index cf74f1c04..e5421169e 100644 --- a/instack_undercloud/undercloud.py +++ b/instack_undercloud/undercloud.py @@ -678,6 +678,22 @@ def _validate_no_ip_change(): raise validator.FailedValidation(message) +def _validate_passwords_file(): + """Disallow updates if the passwords file is missing + + If the undercloud was already deployed, the passwords file needs to be + present so passwords that can't be changed are persisted. If the file + is missing it will break the undercloud, so we should fail-fast and let + the user know about the problem. + """ + if (os.path.isfile(os.path.expanduser('~/stackrc')) and + not os.path.isfile(PATHS.PASSWORD_PATH)): + message = ('The %s file is missing. This will cause all service ' + 'passwords to change and break the existing undercloud. ' % + PATHS.PASSWORD_PATH) + raise validator.FailedValidation(message) + + def _validate_configuration(): try: _check_hostname() @@ -685,6 +701,7 @@ def _validate_configuration(): _check_sysctl() _validate_network() _validate_no_ip_change() + _validate_passwords_file() except RuntimeError as e: LOG.error('An error occurred during configuration validation, ' 'please check your host configuration and try again. '