Add support for unicode in ansible-inventory CLI (#74912)

* Add support for unicode in ansible-inventory CLI

Fixes #57378

* Add tests

* First test fix

* --output tests

* fix
This commit is contained in:
Martin Krizek 2021-06-10 21:07:55 +02:00 committed by GitHub
parent 0a5cc80ce2
commit 5ac1b04929
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 6 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Add unicode support to ``ansible-inventory`` CLI (https://github.com/ansible/ansible/issues/57378)

View file

@ -15,7 +15,7 @@ from ansible import context
from ansible.cli import CLI
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.module_utils._text import to_bytes, to_native
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.utils.vars import combine_vars
from ansible.utils.display import Display
from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_path
@ -158,8 +158,8 @@ class InventoryCLI(CLI):
display.display(results)
else:
try:
with open(to_bytes(outfile), 'wt') as f:
f.write(results)
with open(to_bytes(outfile), 'wb') as f:
f.write(to_bytes(results))
except (OSError, IOError) as e:
raise AnsibleError('Unable to write to destination file (%s): %s' % (to_native(outfile), to_native(e)))
sys.exit(0)
@ -172,7 +172,7 @@ class InventoryCLI(CLI):
if context.CLIARGS['yaml']:
import yaml
from ansible.parsing.yaml.dumper import AnsibleDumper
results = yaml.dump(stuff, Dumper=AnsibleDumper, default_flow_style=False)
results = to_text(yaml.dump(stuff, Dumper=AnsibleDumper, default_flow_style=False, allow_unicode=True))
elif context.CLIARGS['toml']:
from ansible.plugins.inventory.toml import toml_dumps, HAS_TOML
if not HAS_TOML:
@ -192,9 +192,9 @@ class InventoryCLI(CLI):
import json
from ansible.parsing.ajson import AnsibleJSONEncoder
try:
results = json.dumps(stuff, cls=AnsibleJSONEncoder, sort_keys=True, indent=4, preprocess_unsafe=True)
results = json.dumps(stuff, cls=AnsibleJSONEncoder, sort_keys=True, indent=4, preprocess_unsafe=True, ensure_ascii=False)
except TypeError as e:
results = json.dumps(stuff, cls=AnsibleJSONEncoder, sort_keys=False, indent=4, preprocess_unsafe=True)
results = json.dumps(stuff, cls=AnsibleJSONEncoder, sort_keys=False, indent=4, preprocess_unsafe=True, ensure_ascii=False)
display.warning("Could not sort JSON output due to issues while sorting keys: %s" % to_native(e))
return results

View file

@ -0,0 +1,3 @@
all:
hosts:
příbor:

View file

@ -105,3 +105,77 @@
that:
- result is failed
- '"ERROR! The source inventory contains a non-string key" in result.stderr'
- name: "test json output with unicode characters"
command: ansible-inventory --list -i {{ role_path }}/files/unicode.yml
register: result
- assert:
that:
- result is succeeded
- result.stdout is contains('příbor')
- block:
- name: "test json output file with unicode characters"
command: ansible-inventory --list --output unicode_inventory.json -i {{ role_path }}/files/unicode.yml
- set_fact:
json_inventory_file: "{{ lookup('file', 'unicode_inventory.json') | string }}"
- assert:
that:
- json_inventory_file is contains('příbor')
always:
- file:
name: unicode_inventory.json
state: absent
- name: "test yaml output with unicode characters"
command: ansible-inventory --list --yaml -i {{ role_path }}/files/unicode.yml
register: result
- assert:
that:
- result is succeeded
- result.stdout is contains('příbor')
- block:
- name: "test yaml output file with unicode characters"
command: ansible-inventory --list --yaml --output unicode_inventory.yaml -i {{ role_path }}/files/unicode.yml
- set_fact:
yaml_inventory_file: "{{ lookup('file', 'unicode_inventory.yaml') | string }}"
- assert:
that:
- yaml_inventory_file is contains('příbor')
always:
- file:
name: unicode_inventory.yaml
state: absent
- block:
- name: "test toml output with unicode characters"
command: ansible-inventory --list --toml -i {{ role_path }}/files/unicode.yml
register: result
- assert:
that:
- result is succeeded
- result.stdout is contains('příbor')
- block:
- name: "test toml output file with unicode characters"
command: ansible-inventory --list --toml --output unicode_inventory.toml -i {{ role_path }}/files/unicode.yml
- set_fact:
toml_inventory_file: "{{ lookup('file', 'unicode_inventory.toml') | string }}"
- assert:
that:
- toml_inventory_file is contains('příbor')
always:
- file:
name: unicode_inventory.toml
state: absent
when: ansible_python.version.major|int == 3