diff --git a/lib/ansible/callbacks.py b/lib/ansible/callbacks.py index 3c0a4fe52e..410248a303 100644 --- a/lib/ansible/callbacks.py +++ b/lib/ansible/callbacks.py @@ -458,11 +458,11 @@ class PlaybookRunnerCallbacks(DefaultRunnerCallbacks): if type(results) == dict: item = results.get('item', None) if isinstance(item, unicode): - item = utils.to_bytes(item) + item = utils.unicode.to_bytes(item) results = basic.json_dict_unicode_to_bytes(results) else: - results = utils.to_bytes(results) - host = utils.to_bytes(host) + results = utils.unicode.to_bytes(results) + host = utils.unicode.to_bytes(host) if item: msg = "fatal: [%s] => (item=%s) => %s" % (host, item, results) else: @@ -610,13 +610,13 @@ class PlaybookCallbacks(object): call_callback_module('playbook_on_no_hosts_remaining') def on_task_start(self, name, is_conditional): - name = utils.to_bytes(name) + name = utils.unicode.to_bytes(name) msg = "TASK: [%s]" % name if is_conditional: msg = "NOTIFIED: [%s]" % name if hasattr(self, 'start_at'): - self.start_at = utils.to_bytes(self.start_at) + self.start_at = utils.unicode.to_bytes(self.start_at) if name == self.start_at or fnmatch.fnmatch(name, self.start_at): # we found out match, we can get rid of this now del self.start_at @@ -630,7 +630,7 @@ class PlaybookCallbacks(object): self.skip_task = True elif hasattr(self, 'step') and self.step: if isinstance(name, str): - name = utils.to_unicode(name) + name = utils.unicode.to_unicode(name) msg = u'Perform task: %s (y/n/c): ' % name if sys.stdout.encoding: msg = msg.encode(sys.stdout.encoding, errors='replace') diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 8394a8f4f9..76214bee97 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -33,6 +33,7 @@ from ansible.utils.hashing import secure_hash, secure_hash_s, checksum, checksum from ansible.callbacks import display from ansible.module_utils.splitter import split_args, unquote from ansible.module_utils.basic import heuristic_log_sanitize +from ansible.utils.unicode import to_bytes, to_unicode import ansible.constants as C import ast import time @@ -1088,9 +1089,9 @@ def ask_vault_passwords(ask_vault_pass=False, ask_new_vault_pass=False, confirm_ # enforce no newline chars at the end of passwords if vault_pass: - vault_pass = vault_pass.strip() + vault_pass = to_bytes(vault_pass, errors='strict', nonstring='simplerepr').strip() if new_vault_pass: - new_vault_pass = new_vault_pass.strip() + new_vault_pass = to_bytes(new_vault_pass, errors='strict', nonstring='simplerepr').strip() return vault_pass, new_vault_pass @@ -1104,20 +1105,31 @@ def ask_passwords(ask_pass=False, ask_sudo_pass=False, ask_su_pass=False, ask_va if ask_pass: sshpass = getpass.getpass(prompt="SSH password: ") + if sshpass: + sshpass = to_bytes(sshpass, errors='strict', nonstring='simplerepr') sudo_prompt = "sudo password [defaults to SSH password]: " + su_prompt = "su password [defaults to SSH password]: " if ask_sudo_pass: sudopass = getpass.getpass(prompt=sudo_prompt) if ask_pass and sudopass == '': sudopass = sshpass + if sudopass: + sudopass = to_bytes(sudopass, errors='strict', nonstring='simplerepr') if ask_su_pass: - su_pass = getpass.getpass(prompt=su_prompt) + supass = getpass.getpass(prompt=su_prompt) + if ask_pass and supass == '': + supass = sshpass + if supass: + supass = to_bytes(supass, errors='strict', nonstring='simplerepr') if ask_vault_pass: - vault_pass = getpass.getpass(prompt="Vault password: ") + vaultpass = getpass.getpass(prompt="Vault password: ") + if vaultpass: + vaultpass = to_bytes(vault_pass, errors='strict', nonstring='simplerepr').strip() - return (sshpass, sudopass, su_pass, vault_pass) + return (sshpass, sudopass, supass, vaultpass) def do_encrypt(result, encrypt, salt_size=None, salt=None): if PASSLIB_AVAILABLE: @@ -1204,25 +1216,6 @@ def make_su_cmd(su_user, executable, cmd): ) return ('/bin/sh -c ' + pipes.quote(sudocmd), None, success_key) -# For v2, consider either using kitchen or copying my code from there for -# to_unicode and to_bytes handling (TEK) -_TO_UNICODE_TYPES = (unicode, type(None)) - -def to_unicode(value): - # Use with caution -- this function is not encoding safe (non-utf-8 values - # will cause tracebacks if they contain bytes from 0x80-0xff inclusive) - if isinstance(value, _TO_UNICODE_TYPES): - return value - return value.decode("utf-8") - -def to_bytes(value): - # Note: value is assumed to be a basestring to mirror to_unicode. Better - # implementations (like kitchen.text.converters.to_bytes) bring that check - # into the function - if isinstance(value, str): - return value - return value.encode('utf-8') - def get_diff(diff): # called by --diff usage in playbook and runner via callbacks # include names in diffs 'before' and 'after' and do diff -U 10 diff --git a/test/units/TestUtils.py b/test/units/TestUtils.py index 478cfebfd1..286542d5e4 100644 --- a/test/units/TestUtils.py +++ b/test/units/TestUtils.py @@ -512,15 +512,15 @@ class TestUtils(unittest.TestCase): self.assertTrue('echo SUDO-SUCCESS-' in cmd[0] and cmd[2].startswith('SUDO-SUCCESS-')) def test_to_unicode(self): - uni = ansible.utils.to_unicode(u'ansible') + uni = ansible.utils.unicode.to_unicode(u'ansible') self.assertTrue(isinstance(uni, unicode)) self.assertEqual(uni, u'ansible') - none = ansible.utils.to_unicode(None) + none = ansible.utils.unicode.to_unicode(None, nonstring='passthru') self.assertTrue(isinstance(none, type(None))) self.assertTrue(none is None) - utf8 = ansible.utils.to_unicode('ansible') + utf8 = ansible.utils.unicode.to_unicode('ansible') self.assertTrue(isinstance(utf8, unicode)) self.assertEqual(utf8, u'ansible')