diff --git a/instack_undercloud/tests/test_undercloud.py b/instack_undercloud/tests/test_undercloud.py index ac4bbba9e..291a01e0a 100644 --- a/instack_undercloud/tests/test_undercloud.py +++ b/instack_undercloud/tests/test_undercloud.py @@ -28,6 +28,7 @@ from oslotest import mockpatch from six.moves import configparser from instack_undercloud import undercloud +from instack_undercloud import validator undercloud._configure_logging(undercloud.DEFAULT_LOG_LEVEL, None) @@ -81,10 +82,13 @@ class TestUndercloud(BaseTestCase): @mock.patch('instack_undercloud.undercloud._check_memory') @mock.patch('instack_undercloud.undercloud._check_sysctl') @mock.patch('instack_undercloud.undercloud._validate_network') - def test_validate_configuration(self, mock_validate_network, + @mock.patch('instack_undercloud.undercloud._validate_passwords_file') + def test_validate_configuration(self, mock_vpf, + mock_validate_network, mock_check_memory, mock_check_hostname, mock_check_sysctl): undercloud._validate_configuration() + self.assertTrue(mock_vpf.called) self.assertTrue(mock_validate_network.called) self.assertTrue(mock_check_memory.called) self.assertTrue(mock_check_hostname.called) @@ -199,6 +203,22 @@ class TestCheckSysctl(BaseTestCase): undercloud._check_sysctl() +@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 0afb8d9a9..747b091f4 100644 --- a/instack_undercloud/undercloud.py +++ b/instack_undercloud/undercloud.py @@ -630,12 +630,29 @@ def _validate_cidr(): CONF.set_override('network_cidr', '192.0.2.0/24') +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() _check_memory() _check_sysctl() _validate_network() + _validate_passwords_file() except RuntimeError as e: LOG.error('ERROR: An error occured during configuration validation, ' 'please check your host configuration and try again. '