Ensure single vaulted values aren't counted as sequences. Fixes #70784 (#70786)

This commit is contained in:
Matt Martz 2020-07-21 16:48:35 -05:00 committed by GitHub
parent 2a7df5e07b
commit 96b74d3e0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 2 deletions

View file

@ -0,0 +1,3 @@
bugfixes:
- JSON Encoder - Ensure we treat single vault encrypted values as strings
(https://github.com/ansible/ansible/issues/70784)

View file

@ -15,15 +15,23 @@ from ansible.module_utils.common._collections_compat import Mapping
from ansible.module_utils.common.collections import is_sequence from ansible.module_utils.common.collections import is_sequence
def _is_unsafe(value):
return getattr(value, '__UNSAFE__', False) and not getattr(value, '__ENCRYPTED__', False)
def _is_vault(value):
return getattr(value, '__ENCRYPTED__', False)
def _preprocess_unsafe_encode(value): def _preprocess_unsafe_encode(value):
"""Recursively preprocess a data structure converting instances of ``AnsibleUnsafe`` """Recursively preprocess a data structure converting instances of ``AnsibleUnsafe``
into their JSON dict representations into their JSON dict representations
Used in ``AnsibleJSONEncoder.iterencode`` Used in ``AnsibleJSONEncoder.iterencode``
""" """
if getattr(value, '__UNSAFE__', False) and not getattr(value, '__ENCRYPTED__', False): if _is_unsafe(value):
value = {'__ansible_unsafe': to_text(value, errors='surrogate_or_strict', nonstring='strict')} value = {'__ansible_unsafe': to_text(value, errors='surrogate_or_strict', nonstring='strict')}
elif is_sequence(value): elif is_sequence(value) and not _is_vault(value):
value = [_preprocess_unsafe_encode(v) for v in value] value = [_preprocess_unsafe_encode(v) for v in value]
elif isinstance(value, Mapping): elif isinstance(value, Mapping):
value = dict((k, _preprocess_unsafe_encode(v)) for k, v in value.items()) value = dict((k, _preprocess_unsafe_encode(v)) for k, v in value.items())

View file

@ -158,6 +158,7 @@ class TestAnsibleJSONEncoder:
Test for passing AnsibleVaultEncryptedUnicode to AnsibleJSONEncoder.default(). Test for passing AnsibleVaultEncryptedUnicode to AnsibleJSONEncoder.default().
""" """
assert ansible_json_encoder.default(test_input) == {'__ansible_vault': expected} assert ansible_json_encoder.default(test_input) == {'__ansible_vault': expected}
assert json.dumps(test_input, cls=AnsibleJSONEncoder, preprocess_unsafe=True) == '{"__ansible_vault": "%s"}' % expected.replace('\n', '\\n')
@pytest.mark.parametrize( @pytest.mark.parametrize(
'test_input,expected', 'test_input,expected',