diff --git a/salt/modules/hosts.py b/salt/modules/hosts.py index 3f8fdd8b65..a538fa348a 100644 --- a/salt/modules/hosts.py +++ b/salt/modules/hosts.py @@ -173,7 +173,7 @@ def set_host(ip, alias): if tmpline.startswith(b'#'): continue comps = tmpline.split() - if comps[0] == ip: + if comps[0] == salt.utils.stringutils.to_bytes(ip): if not ovr: lines[ind] = line_to_add ovr = True diff --git a/salt/modules/shadow.py b/salt/modules/shadow.py index cf06c3bf33..ce01d51781 100644 --- a/salt/modules/shadow.py +++ b/salt/modules/shadow.py @@ -211,7 +211,7 @@ def lock_password(name): ''' .. versionadded:: 2016.11.0 - Lock the password from name user + Lock the password from specified user CLI Example: diff --git a/salt/modules/tls.py b/salt/modules/tls.py index ef7e1ff5f5..9a556fa9c9 100644 --- a/salt/modules/tls.py +++ b/salt/modules/tls.py @@ -112,6 +112,7 @@ import binascii from datetime import datetime # Import Salt libs +import salt.utils.data import salt.utils.files import salt.utils.stringutils from salt.utils.versions import LooseVersion as _LooseVersion @@ -1041,7 +1042,7 @@ def create_csr(ca_name, OpenSSL.crypto.X509Extension( b'subjectAltName', False, - salt.utils.stringutils.to_str(b', '.join(subjectAltName)) + b', '.join(salt.utils.data.encode(subjectAltName)) ) ) else: @@ -1560,8 +1561,8 @@ def create_pkcs12(ca_name, CN, passphrase='', cacert_path=None, replace=False): ca_name, CN), 'wb') as ofile: ofile.write( - salt.utils.stringutils.to_bytes( - pkcs12.export(passphrase=passphrase) + pkcs12.export( + passphrase=salt.utils.stringutils.to_bytes(passphrase) ) ) diff --git a/salt/utils/jinja.py b/salt/utils/jinja.py index d473d86aa0..5a0bacfcc5 100644 --- a/salt/utils/jinja.py +++ b/salt/utils/jinja.py @@ -30,6 +30,7 @@ import salt.fileclient import salt.utils.data import salt.utils.files import salt.utils.json +import salt.utils.stringutils import salt.utils.url import salt.utils.yaml from salt.utils.decorators.jinja import jinja_filter, jinja_test, jinja_global @@ -396,7 +397,7 @@ def uuid_(val): return six.text_type( uuid.uuid5( GLOBAL_UUID, - salt.utils.data.encode(val) + salt.utils.stringutils.to_str(val) ) ) diff --git a/salt/utils/pycrypto.py b/salt/utils/pycrypto.py index 3d9c6a73d6..bc2dddc181 100644 --- a/salt/utils/pycrypto.py +++ b/salt/utils/pycrypto.py @@ -5,6 +5,7 @@ Use pycrypto to generate random passwords on the fly. # Import python libraries from __future__ import absolute_import, print_function, unicode_literals +import logging import re import string import random @@ -31,25 +32,38 @@ except ImportError: # Import salt libs import salt.utils.stringutils -from salt.exceptions import SaltInvocationError +from salt.exceptions import CommandExecutionError, SaltInvocationError +from salt.ext import six + +log = logging.getLogger(__name__) def secure_password(length=20, use_random=True): ''' Generate a secure password. ''' - length = int(length) - pw = '' - while len(pw) < length: - if HAS_RANDOM and use_random: - pw += re.sub( - r'\W', - '', - salt.utils.stringutils.to_str(get_random_bytes(1)) - ) - else: - pw += random.SystemRandom().choice(string.ascii_letters + string.digits) - return pw + try: + length = int(length) + pw = '' + while len(pw) < length: + if HAS_RANDOM and use_random: + while True: + try: + char = salt.utils.stringutils.to_str(get_random_bytes(1)) + break + except UnicodeDecodeError: + continue + pw += re.sub( + salt.utils.stringutils.to_str(r'\W'), + str(), # future lint: disable=blacklisted-function + char + ) + else: + pw += random.SystemRandom().choice(string.ascii_letters + string.digits) + return pw + except Exception as exc: + log.exception('Failed to generate secure passsword') + raise CommandExecutionError(six.text_type(exc)) def gen_hash(crypt_salt=None, password=None, algorithm='sha512'): diff --git a/tests/integration/modules/test_shadow.py b/tests/integration/modules/test_shadow.py index 7887047730..e57513aea5 100644 --- a/tests/integration/modules/test_shadow.py +++ b/tests/integration/modules/test_shadow.py @@ -37,6 +37,8 @@ class ShadowModuleTest(ModuleCase): ''' Get current settings ''' + if 'ERROR' in self._password: + self.fail('Failed to generate password: {0}'.format(self._password)) super(ShadowModuleTest, self).setUp() os_grain = self.run_function('grains.item', ['kernel']) if os_grain['kernel'] not in 'Linux': diff --git a/tests/unit/modules/test_hosts.py b/tests/unit/modules/test_hosts.py index 82afd7893a..7ddec9824e 100644 --- a/tests/unit/modules/test_hosts.py +++ b/tests/unit/modules/test_hosts.py @@ -16,8 +16,11 @@ from tests.support.mock import ( ) # Import Salt Libs import salt.modules.hosts as hosts +import salt.utils.data import salt.utils.platform +import salt.utils.stringutils from salt.ext.six.moves import StringIO +from salt.ext import six class HostsTestCase(TestCase, LoaderModuleMockMixin): @@ -130,12 +133,13 @@ class HostsTestCase(TestCase, LoaderModuleMockMixin): '1.1.1.1 foofoo.foofoo foofoo', ))] - class TmpStringIO(StringIO): + class TmpStringIO(StringIO, object): def __init__(self, fn, mode='r'): + self.mode = mode initial_value = data[0] - if 'w' in mode: + if 'w' in self.mode: initial_value = '' - StringIO.__init__(self, initial_value) + super(TmpStringIO, self).__init__(initial_value) def __enter__(self): return self @@ -156,6 +160,40 @@ class HostsTestCase(TestCase, LoaderModuleMockMixin): data[0] = self.getvalue() StringIO.close(self) + def read(self, *args): + ret = super(TmpStringIO, self).read(*args) + if six.PY3 and 'b' in self.mode: + return salt.utils.stringutils.to_bytes(ret) + else: + return ret + + def write(self, s, *args): + if six.PY3: + if 'b' in self.mode: + if not isinstance(s, bytes): + # Make this act like a binary filehandle + raise TypeError("a bytes-like object is required, not 'str'") + # The StringIO wants a str type, it won't take + # bytes. Convert before writing to it. + return super(TmpStringIO, self).write( + salt.utils.stringutils.to_str(s), *args) + else: + if not isinstance(s, str): + # Make this act like a non-binary filehandle + raise TypeError("write() argument must be str, not bytes") + return super(TmpStringIO, self).write(s, *args) + + def readlines(self): + ret = super(TmpStringIO, self).readlines() + if six.PY3 and 'b' in self.mode: + return salt.utils.data.encode(ret) + else: + return ret + + def writelines(self, lines): + for line in lines: + self.write(line) + expected = '\n'.join(( '2.2.2.2 bar.barbar bar', '3.3.3.3 asdf.asdfadsf asdf', diff --git a/tests/unit/modules/test_inspect_fsdb.py b/tests/unit/modules/test_inspect_fsdb.py index d330db4e3b..dcbc82a493 100644 --- a/tests/unit/modules/test_inspect_fsdb.py +++ b/tests/unit/modules/test_inspect_fsdb.py @@ -140,12 +140,12 @@ class InspectorFSDBTestCase(TestCase): else: # Order in PY3 is not the same for every run writable_data = writable.data[0].strip() - assert_order_options = ['bar:unicode,foo:int,spam:float', - 'bar:unicode,spam:float,foo:int', - 'foo:int,spam:float,bar:unicode', - 'foo:int,bar:unicode,spam:float', - 'spam:float,foo:int,bar:unicode', - 'spam:float,bar:unicode,foo:int'] + assert_order_options = ['bar:str,foo:int,spam:float', + 'bar:str,spam:float,foo:int', + 'foo:int,spam:float,bar:str', + 'foo:int,bar:str,spam:float', + 'spam:float,foo:int,bar:str', + 'spam:float,bar:str,foo:int'] while assert_order_options: assert_option = assert_order_options.pop() try: