diff --git a/cloudbaseinit/osutils/base.py b/cloudbaseinit/osutils/base.py index 46af54ad..2b206ee1 100644 --- a/cloudbaseinit/osutils/base.py +++ b/cloudbaseinit/osutils/base.py @@ -106,3 +106,7 @@ class BaseOSUtils(object): def firewall_remove_rule(self, name, port, protocol, allow=True): raise NotImplementedError() + + def get_maximum_password_length(self): + """Obtain the maximum password length tailored for each OS.""" + raise NotImplementedError() diff --git a/cloudbaseinit/osutils/windows.py b/cloudbaseinit/osutils/windows.py index 7280bdd8..5716d02a 100644 --- a/cloudbaseinit/osutils/windows.py +++ b/cloudbaseinit/osutils/windows.py @@ -991,3 +991,7 @@ class WindowsUtils(base.BaseOSUtils): process_path = os.path.join(base_dir, args[0]) return self.execute_process([process_path] + args[1:], decode_output=decode_output, shell=shell) + + def get_maximum_password_length(self): + # TODO(cpopa): Limit to 14 chars for compatibility with NT? + return 14 diff --git a/cloudbaseinit/plugins/common/createuser.py b/cloudbaseinit/plugins/common/createuser.py index 6432f318..3fb61fa6 100644 --- a/cloudbaseinit/plugins/common/createuser.py +++ b/cloudbaseinit/plugins/common/createuser.py @@ -35,10 +35,12 @@ LOG = logging.getLogger(__name__) class CreateUserPlugin(base.BasePlugin): - def _get_password(self, osutils): + @staticmethod + def _get_password(osutils): # Generate a temporary random password to be replaced # by SetUserPasswordPlugin (starting from Grizzly) - return osutils.generate_random_password(14) + maximum_length = osutils.get_maximum_password_length() + return osutils.generate_random_password(maximum_length) def execute(self, service, shared_data): user_name = CONF.username diff --git a/cloudbaseinit/plugins/common/setuserpassword.py b/cloudbaseinit/plugins/common/setuserpassword.py index 4490dd0c..73baf452 100644 --- a/cloudbaseinit/plugins/common/setuserpassword.py +++ b/cloudbaseinit/plugins/common/setuserpassword.py @@ -63,8 +63,8 @@ class SetUserPasswordPlugin(base.BasePlugin): if not password: LOG.debug('Generating a random user password') # Generate a random password - # Limit to 14 chars for compatibility with NT - password = osutils.generate_random_password(14) + maximum_length = osutils.get_maximum_password_length() + password = osutils.generate_random_password(maximum_length) return password diff --git a/cloudbaseinit/tests/osutils/test_windows.py b/cloudbaseinit/tests/osutils/test_windows.py index 8b0f53a2..22533542 100644 --- a/cloudbaseinit/tests/osutils/test_windows.py +++ b/cloudbaseinit/tests/osutils/test_windows.py @@ -1357,3 +1357,6 @@ class TestWindowsUtils(unittest.TestCase): decode_output=False, shell=True) self.assertEqual(mock.sentinel.execute_process, result) + + def test_get_password_maximum_length(self): + self.assertEqual(14, self._winutils.get_maximum_password_length()) diff --git a/cloudbaseinit/tests/plugins/common/test_createuser.py b/cloudbaseinit/tests/plugins/common/test_createuser.py index 1924536a..c59b19fe 100644 --- a/cloudbaseinit/tests/plugins/common/test_createuser.py +++ b/cloudbaseinit/tests/plugins/common/test_createuser.py @@ -36,7 +36,9 @@ class CreateUserPluginTests(unittest.TestCase): mock_osutils = mock.MagicMock() mock_osutils.generate_random_password.return_value = 'fake password' response = self._create_user._get_password(mock_osutils) - mock_osutils.generate_random_password.assert_called_once_with(14) + mock_osutils.get_maximum_password_length.assert_called_once_with() + length = mock_osutils.get_maximum_password_length() + mock_osutils.generate_random_password.assert_called_once_with(length) self.assertEqual('fake password', response) @testutils.ConfPatcher('groups', ['Admins']) diff --git a/cloudbaseinit/tests/plugins/common/test_setuserpassword.py b/cloudbaseinit/tests/plugins/common/test_setuserpassword.py index 21783dad..157e7841 100644 --- a/cloudbaseinit/tests/plugins/common/test_setuserpassword.py +++ b/cloudbaseinit/tests/plugins/common/test_setuserpassword.py @@ -97,8 +97,9 @@ class SetUserPasswordPluginTests(unittest.TestCase): self.assertFalse(mock_osutils.generate_random_password.called) expected_password = mock.sentinel.create_user_password else: - mock_osutils.generate_random_password.assert_called_once_with(14) - + mock_osutils.get_maximum_password_length.assert_called_once_with() + mock_osutils.generate_random_password.assert_called_once_with( + mock_osutils.get_maximum_password_length()) self.assertEqual(expected_password, response) def test_get_password_inject_true(self):