From f623a7726f8ad90129fca85023ce6b63420a6af0 Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Tue, 20 Jan 2015 06:11:08 -0500 Subject: [PATCH] Enable password set in case of rescued instances In the case of rescued instances, the user password has already been set for an instance, and it cannot be posted anymore to the http metadata service. In this case we still have to set the new password and warn the user that the password has already been posted to the metadata service and it cannot be changed anymore. Change-Id: I9b52af6bf8bac2c394bc4a9eb30a983594fa1e68 Closes-Bug: #1391818 --- .../plugins/windows/setuserpassword.py | 46 ++++++++++--------- .../plugins/windows/test_setuserpassword.py | 4 +- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/cloudbaseinit/plugins/windows/setuserpassword.py b/cloudbaseinit/plugins/windows/setuserpassword.py index c407ba70..6efcb162 100644 --- a/cloudbaseinit/plugins/windows/setuserpassword.py +++ b/cloudbaseinit/plugins/windows/setuserpassword.py @@ -70,14 +70,19 @@ class SetUserPasswordPlugin(base.BasePlugin): return password def _set_metadata_password(self, password, service): - ssh_pub_key = self._get_ssh_public_key(service) - if ssh_pub_key: - enc_password_b64 = self._encrypt_password(ssh_pub_key, - password) - return service.post_password(enc_password_b64) - else: - LOG.info('No SSH public key available for password encryption') + if service.is_password_set: + LOG.debug('User\'s password already set in the instance metadata ' + 'and it cannot be updated in the instance metadata') return True + else: + ssh_pub_key = self._get_ssh_public_key(service) + if ssh_pub_key: + enc_password_b64 = self._encrypt_password(ssh_pub_key, + password) + return service.post_password(enc_password_b64) + else: + LOG.info('No SSH public key available for password encryption') + return True def _set_password(self, service, osutils, user_name): password = self._get_password(service, osutils) @@ -91,20 +96,17 @@ class SetUserPasswordPlugin(base.BasePlugin): user_name = shared_data.get(constants.SHARED_DATA_USERNAME, CONF.username) - if service.can_post_password and service.is_password_set: - LOG.debug('User\'s password already set in the instance metadata') - else: - osutils = osutils_factory.get_os_utils() - if osutils.user_exists(user_name): - password = self._set_password(service, osutils, user_name) - # TODO(alexpilotti): encrypt with DPAPI - shared_data[constants.SHARED_DATA_PASSWORD] = password + osutils = osutils_factory.get_os_utils() + if osutils.user_exists(user_name): + password = self._set_password(service, osutils, user_name) + LOG.info('Password succesfully updated for user %s' % user_name) + # TODO(alexpilotti): encrypt with DPAPI + shared_data[constants.SHARED_DATA_PASSWORD] = password - if not service.can_post_password: - LOG.info('Cannot set the password in the metadata as it ' - 'is not supported by this service') - return (base.PLUGIN_EXECUTION_DONE, False) - else: - self._set_metadata_password(password, service) + if not service.can_post_password: + LOG.info('Cannot set the password in the metadata as it is ' + 'not supported by this service') + else: + self._set_metadata_password(password, service) - return (base.PLUGIN_EXECUTE_ON_NEXT_BOOT, False) + return (base.PLUGIN_EXECUTION_DONE, False) diff --git a/cloudbaseinit/tests/plugins/windows/test_setuserpassword.py b/cloudbaseinit/tests/plugins/windows/test_setuserpassword.py index 4ccfad7b..3e421a3e 100644 --- a/cloudbaseinit/tests/plugins/windows/test_setuserpassword.py +++ b/cloudbaseinit/tests/plugins/windows/test_setuserpassword.py @@ -100,6 +100,8 @@ class SetUserPasswordPluginTests(unittest.TestCase): mock_get_key.return_value = ssh_pub_key mock_encrypt_password.return_value = 'encrypted password' mock_service.post_password.return_value = 'value' + mock_service.can_post_password = True + mock_service.is_password_set = False response = self._setpassword_plugin._set_metadata_password( fake_passw0rd, mock_service) if ssh_pub_key is None: @@ -159,4 +161,4 @@ class SetUserPasswordPluginTests(unittest.TestCase): 'fake username') mock_set_metadata_password.assert_called_once_with('fake password', mock_service) - self.assertEqual((2, False), response) + self.assertEqual((1, False), response)