From 19aa6f7dd5850771025d63dd46068a5ba38fcf38 Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Tue, 3 Mar 2015 15:48:34 -0500 Subject: [PATCH] Make sure that the configured user profile registry key exists If the user set to be configured by cloudbase-init is already added, but no logon session has been created for that user, the profile registry key does not exist. As a consequence, the SetUserSSHPublicKeysPlugin fails, as it cannot retrieve the home directory from the registry key. Change-Id: I4226a1c08e940717709e65ba932ce15c8ce37aed Closes-Bug: #1415198 --- cloudbaseinit/plugins/common/createuser.py | 10 +++++++ cloudbaseinit/plugins/windows/createuser.py | 12 ++++---- .../tests/plugins/common/test_createuser.py | 14 +++++++--- .../tests/plugins/windows/test_createuser.py | 28 ++++++++++++------- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/cloudbaseinit/plugins/common/createuser.py b/cloudbaseinit/plugins/common/createuser.py index ed99742a..b0945895 100644 --- a/cloudbaseinit/plugins/common/createuser.py +++ b/cloudbaseinit/plugins/common/createuser.py @@ -48,6 +48,14 @@ class BaseCreateUserPlugin(base.BasePlugin): a new user must be created. """ + @abc.abstractmethod + def post_create_user(self, user_name, password, osutils): + """Executes post user creation logic. + + This will be called after by :meth:`~execute`, after + the user is created or the user password is updated. + """ + @staticmethod def _get_password(osutils): # Generate a temporary random password to be replaced @@ -72,6 +80,8 @@ class BaseCreateUserPlugin(base.BasePlugin): # TODO(alexpilotti): encrypt with DPAPI shared_data[constants.SHARED_DATA_PASSWORD] = password + self.post_create_user(user_name, password, osutils) + for group_name in CONF.groups: try: osutils.add_user_to_local_group(user_name, group_name) diff --git a/cloudbaseinit/plugins/windows/createuser.py b/cloudbaseinit/plugins/windows/createuser.py index 9e885a45..dc32221d 100644 --- a/cloudbaseinit/plugins/windows/createuser.py +++ b/cloudbaseinit/plugins/windows/createuser.py @@ -20,12 +20,8 @@ LOG = logging.getLogger(__name__) class CreateUserPlugin(createuser.BaseCreateUserPlugin): - def create_user(self, username, password, osutils): - osutils.create_user(username, password) - self._create_user_logon(osutils, username, password) - @staticmethod - def _create_user_logon(osutils, user_name, password): + def _create_user_logon(user_name, password, osutils): try: # Create a user profile in order for other plugins # to access the user home, etc @@ -36,3 +32,9 @@ class CreateUserPlugin(createuser.BaseCreateUserPlugin): except Exception: LOG.exception('Cannot create a user logon session for user: "%s"', user_name) + + def create_user(self, username, password, osutils): + osutils.create_user(username, password) + + def post_create_user(self, user_name, password, osutils): + self._create_user_logon(user_name, password, osutils) diff --git a/cloudbaseinit/tests/plugins/common/test_createuser.py b/cloudbaseinit/tests/plugins/common/test_createuser.py index 5003f017..ee758c66 100644 --- a/cloudbaseinit/tests/plugins/common/test_createuser.py +++ b/cloudbaseinit/tests/plugins/common/test_createuser.py @@ -32,6 +32,9 @@ class CreateUserPlugin(createuser.BaseCreateUserPlugin): def create_user(self, username, password, osutils): pass + def post_create_user(self, username, password, osutils): + pass + class CreateUserPluginTests(unittest.TestCase): @@ -52,18 +55,17 @@ class CreateUserPluginTests(unittest.TestCase): @mock.patch('cloudbaseinit.plugins.common.createuser.' 'BaseCreateUserPlugin._get_password') @mock.patch.object(CreateUserPlugin, 'create_user') - def _test_execute(self, mock_create_user, mock_get_password, - mock_get_os_utils, + @mock.patch.object(CreateUserPlugin, 'post_create_user') + def _test_execute(self, mock_post_create_user, mock_create_user, + mock_get_password, mock_get_os_utils, user_exists=True, group_adding_works=True): shared_data = {} - mock_token = mock.MagicMock() mock_osutils = mock.MagicMock() mock_service = mock.MagicMock() mock_get_password.return_value = 'password' mock_get_os_utils.return_value = mock_osutils mock_osutils.user_exists.return_value = user_exists - mock_osutils.create_user_logon_session.return_value = mock_token if not group_adding_works: mock_osutils.add_user_to_local_group.side_effect = Exception @@ -86,6 +88,10 @@ class CreateUserPluginTests(unittest.TestCase): expected_logging = ["Creating user \"%s\" and setting password" % CONF.username] + mock_post_create_user.assert_called_once_with( + CONF.username, 'password', + mock_osutils) + self.assertEqual(expected_logging, snatcher.output[:1]) if not group_adding_works: failed = snatcher.output[1].startswith( diff --git a/cloudbaseinit/tests/plugins/windows/test_createuser.py b/cloudbaseinit/tests/plugins/windows/test_createuser.py index 6d4a58ba..13f2fc4b 100644 --- a/cloudbaseinit/tests/plugins/windows/test_createuser.py +++ b/cloudbaseinit/tests/plugins/windows/test_createuser.py @@ -28,9 +28,7 @@ class CreateUserPluginTests(unittest.TestCase): def setUp(self): self._create_user = createuser.CreateUserPlugin() - @mock.patch('cloudbaseinit.plugins.windows.createuser.CreateUserPlugin.' - '_create_user_logon') - def test_create_user(self, mock_create_user_logon): + def test_create_user(self): mock_osutils = mock.Mock() self._create_user.create_user( mock.sentinel.username, @@ -40,10 +38,20 @@ class CreateUserPluginTests(unittest.TestCase): mock_osutils.create_user.assert_called_once_with( mock.sentinel.username, mock.sentinel.password) - mock_create_user_logon.assert_called_once_with( - mock_osutils, + + @mock.patch('cloudbaseinit.plugins.windows.createuser.CreateUserPlugin.' + '_create_user_logon') + def test_post_create_user(self, mock_create_user_logon): + mock_osutils = mock.Mock() + self._create_user.post_create_user( mock.sentinel.username, - mock.sentinel.password) + mock.sentinel.password, + mock_osutils) + + mock_create_user_logon.assert_called_once_with( + mock.sentinel.username, + mock.sentinel.password, + mock_osutils) def test__create_user_logon(self): mock_osutils = mock.Mock() @@ -51,9 +59,9 @@ class CreateUserPluginTests(unittest.TestCase): mock_osutils.create_user_logon_session.return_value = mock_token self._create_user._create_user_logon( - mock_osutils, mock.sentinel.user_name, - mock.sentinel.password) + mock.sentinel.password, + mock_osutils) mock_osutils.create_user_logon_session.assert_called_once_with( mock.sentinel.user_name, @@ -69,9 +77,9 @@ class CreateUserPluginTests(unittest.TestCase): with testutils.LogSnatcher('cloudbaseinit.plugins.windows.' 'createuser') as snatcher: self._create_user._create_user_logon( - mock_osutils, mock.sentinel.user_name, - mock.sentinel.password) + mock.sentinel.password, + mock_osutils) mock_osutils.create_user_logon_session.assert_called_once_with( mock.sentinel.user_name,