diff --git a/cloudbaseinit/plugins/windows/winrmcertificateauth.py b/cloudbaseinit/plugins/windows/winrmcertificateauth.py index 9211abc6..2a4050ae 100644 --- a/cloudbaseinit/plugins/windows/winrmcertificateauth.py +++ b/cloudbaseinit/plugins/windows/winrmcertificateauth.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo.config import cfg + from cloudbaseinit import exception from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.osutils import factory as osutils_factory @@ -22,23 +24,30 @@ from cloudbaseinit.utils.windows import winrmconfig from cloudbaseinit.utils.windows import x509 +CONF = cfg.CONF +CONF.import_opt('username', 'cloudbaseinit.plugins.common.createuser') LOG = logging.getLogger(__name__) class ConfigWinRMCertificateAuthPlugin(base.BasePlugin): - def _get_credentials(self, shared_data): - user_name = shared_data.get(constants.SHARED_DATA_USERNAME) + @staticmethod + def _get_credentials(service, shared_data): + user_name = shared_data.get(constants.SHARED_DATA_USERNAME, + CONF.username) if not user_name: raise exception.CloudbaseInitException( "Cannot execute plugin as the username has not been set in " - "the plugins shared data") + "the plugins shared data, nor it was found in config file.") password = shared_data.get(constants.SHARED_DATA_PASSWORD) if not password: - raise exception.CloudbaseInitException( - "Cannot execute plugin as the password has not been set in the" - " plugins shared data") + password = service.get_admin_password() + if not password: + raise exception.CloudbaseInitException( + "Cannot execute plugin as the password has not been set " + "in the plugins shared data, nor it was retrieved " + "from the metadata service.") # For security reasons unset the password in the shared_data # as it is currently not needed by other plugins @@ -47,7 +56,7 @@ class ConfigWinRMCertificateAuthPlugin(base.BasePlugin): return (user_name, password) def execute(self, service, shared_data): - user_name, password = self._get_credentials(shared_data) + user_name, password = self._get_credentials(service, shared_data) certs_data = service.get_client_auth_certs() if not certs_data: diff --git a/cloudbaseinit/tests/plugins/windows/test_winrmcertificateauth.py b/cloudbaseinit/tests/plugins/windows/test_winrmcertificateauth.py index a4d2ca59..5a796efe 100644 --- a/cloudbaseinit/tests/plugins/windows/test_winrmcertificateauth.py +++ b/cloudbaseinit/tests/plugins/windows/test_winrmcertificateauth.py @@ -23,6 +23,7 @@ except ImportError: from cloudbaseinit import exception from cloudbaseinit.plugins.common import base from cloudbaseinit.plugins.common import constants +from cloudbaseinit.tests import testutils class ConfigWinRMCertificateAuthPluginTests(unittest.TestCase): @@ -51,35 +52,41 @@ class ConfigWinRMCertificateAuthPluginTests(unittest.TestCase): def tearDown(self): self._module_patcher.stop() - def _test_get_credentials(self, fake_user, fake_password): - mock_shared_data = mock.MagicMock() - mock_shared_data.get.side_effect = [fake_user, fake_password] - if fake_user is None or fake_password is None: - self.assertRaises(exception.CloudbaseInitException, - self._certif_auth._get_credentials, - mock_shared_data) - else: - response = self._certif_auth._get_credentials(mock_shared_data) - expected = [mock.call(constants.SHARED_DATA_USERNAME), - mock.call(constants.SHARED_DATA_PASSWORD)] - self.assertEqual(expected, mock_shared_data.get.call_args_list) + @testutils.ConfPatcher('username', '') + def test_get_credentials_no_username(self): + with self.assertRaises(exception.CloudbaseInitException) as cm: + self._certif_auth._get_credentials(mock.sentinel.service, {}) - mock_shared_data.__setitem__.assert_called_once_with( - 'admin_password', None) + expected_message = ( + "Cannot execute plugin as the username has not been set in " + "the plugins shared data, nor it was found in config file.") + self.assertEqual(expected_message, str(cm.exception)) - self.assertEqual((fake_user, fake_password), response) + def test_get_credentials_no_password(self): + mock_service = mock.Mock() + mock_service.get_admin_password.return_value = None - def test_test_get_credentials(self): - self._test_get_credentials(fake_user='fake user', - fake_password='fake password') + with self.assertRaises(exception.CloudbaseInitException) as cm: + self._certif_auth._get_credentials(mock_service, {}) - def test_test_get_credentials_no_user(self): - self._test_get_credentials(fake_user=None, - fake_password='fake password') + expected_message = ( + "Cannot execute plugin as the password has not been set " + "in the plugins shared data, nor it was retrieved " + "from the metadata service.") + self.assertEqual(expected_message, str(cm.exception)) + mock_service.get_admin_password.assert_called_once_with() - def test_test_get_credentials_no_password(self): - self._test_get_credentials(fake_user='fake user', - fake_password=None) + def test_get_credentials_get_admin_password(self): + mock_service = mock.Mock() + mock_service.get_admin_password.return_value = mock.sentinel.password + shared_data = {constants.SHARED_DATA_USERNAME: mock.sentinel.username} + + result = self._certif_auth._get_credentials(mock_service, shared_data) + + self.assertIsNone(shared_data[constants.SHARED_DATA_PASSWORD]) + self.assertEqual((mock.sentinel.username, mock.sentinel.password), + result) + mock_service.get_admin_password.assert_called_once_with() @mock.patch('cloudbaseinit.plugins.windows.winrmcertificateauth' '.ConfigWinRMCertificateAuthPlugin._get_credentials') @@ -127,7 +134,8 @@ class ConfigWinRMCertificateAuthPluginTests(unittest.TestCase): self.assertEqual(expected_set_token_calls, set_uac_rs.call_args_list) - mock_get_credentials.assert_called_once_with('fake data') + mock_get_credentials.assert_called_once_with( + mock_service, 'fake data') mock_import_cert.assert_called_once_with( cert_data, store_name=self.winrmcert.x509.STORE_NAME_ROOT)