From 915d232d5f948ea3a59f064a100c82f3e6d7cfdd Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Mon, 26 Jan 2015 20:37:20 -0800 Subject: [PATCH] jinja2 cannot handle byte strs with non-ascii. So we need to transform potential byte str into unicode type. This fix is for dynamic inventory. Fixes #10007 --- lib/ansible/callbacks.py | 2 ++ lib/ansible/inventory/script.py | 4 ++-- lib/ansible/module_utils/basic.py | 18 ++++++++++++++++++ v2/ansible/inventory/script.py | 4 ++-- v2/ansible/module_utils/basic.py | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/ansible/callbacks.py b/lib/ansible/callbacks.py index 21ca4a49c9..6a409b0a2f 100644 --- a/lib/ansible/callbacks.py +++ b/lib/ansible/callbacks.py @@ -456,6 +456,8 @@ class PlaybookRunnerCallbacks(DefaultRunnerCallbacks): item = None if type(results) == dict: item = results.get('item', None) + host = utils.to_bytes(host) + results = utils.to_bytes(results) if item: msg = "fatal: [%s] => (item=%s) => %s" % (host, item, results) else: diff --git a/lib/ansible/inventory/script.py b/lib/ansible/inventory/script.py index e0e8efb4a3..b3a9bbc570 100644 --- a/lib/ansible/inventory/script.py +++ b/lib/ansible/inventory/script.py @@ -22,7 +22,7 @@ import subprocess import ansible.constants as C from ansible.inventory.host import Host from ansible.inventory.group import Group -from ansible.module_utils.basic import json_dict_unicode_to_bytes +from ansible.module_utils.basic import json_dict_bytes_to_unicode from ansible import utils from ansible import errors import sys @@ -59,7 +59,7 @@ class InventoryScript(object): # not passing from_remote because data from CMDB is trusted self.raw = utils.parse_json(self.data) - self.raw = json_dict_unicode_to_bytes(self.raw) + self.raw = json_dict_bytes_to_unicode(self.raw) all = Group('all') groups = dict(all=all) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 1d5dfcdf31..8603976c5a 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -251,6 +251,24 @@ def json_dict_unicode_to_bytes(d): else: return d +def json_dict_bytes_to_unicode(d): + ''' Recursively convert dict keys and values to byte str + + Specialized for json return because this only handles, lists, tuples, + and dict container types (the containers that the json module returns) + ''' + + if isinstance(d, str): + return unicode(d, 'utf-8') + elif isinstance(d, dict): + return dict(map(json_dict_bytes_to_unicode, d.iteritems())) + elif isinstance(d, list): + return list(map(json_dict_bytes_to_unicode, d)) + elif isinstance(d, tuple): + return tuple(map(json_dict_bytes_to_unicode, d)) + else: + return d + class AnsibleModule(object): diff --git a/v2/ansible/inventory/script.py b/v2/ansible/inventory/script.py index e0e8efb4a3..b3a9bbc570 100644 --- a/v2/ansible/inventory/script.py +++ b/v2/ansible/inventory/script.py @@ -22,7 +22,7 @@ import subprocess import ansible.constants as C from ansible.inventory.host import Host from ansible.inventory.group import Group -from ansible.module_utils.basic import json_dict_unicode_to_bytes +from ansible.module_utils.basic import json_dict_bytes_to_unicode from ansible import utils from ansible import errors import sys @@ -59,7 +59,7 @@ class InventoryScript(object): # not passing from_remote because data from CMDB is trusted self.raw = utils.parse_json(self.data) - self.raw = json_dict_unicode_to_bytes(self.raw) + self.raw = json_dict_bytes_to_unicode(self.raw) all = Group('all') groups = dict(all=all) diff --git a/v2/ansible/module_utils/basic.py b/v2/ansible/module_utils/basic.py index b5b3cb1451..f772d6a706 100644 --- a/v2/ansible/module_utils/basic.py +++ b/v2/ansible/module_utils/basic.py @@ -251,6 +251,24 @@ def json_dict_unicode_to_bytes(d): else: return d +def json_dict_bytes_to_unicode(d): + ''' Recursively convert dict keys and values to byte str + + Specialized for json return because this only handles, lists, tuples, + and dict container types (the containers that the json module returns) + ''' + + if isinstance(d, str): + return unicode(d, 'utf-8') + elif isinstance(d, dict): + return dict(map(json_dict_bytes_to_unicode, d.iteritems())) + elif isinstance(d, list): + return list(map(json_dict_bytes_to_unicode, d)) + elif isinstance(d, tuple): + return tuple(map(json_dict_bytes_to_unicode, d)) + else: + return d + class AnsibleModule(object):