yaml dumper: Add YAML respresenter for AnsibleUndefined (#75078)

Fixes: #75072

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
pull/75655/head
Abhijeet Kasurde 3 years ago committed by GitHub
parent de01db08d0
commit 12734fa21c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
---
minor_changes:
- yaml dumper - YAML representer for AnsibleUndefined (https://github.com/ansible/ansible/issues/75072).

@ -25,6 +25,7 @@ from ansible.module_utils.six import PY3, text_type, binary_type
from ansible.module_utils.common.yaml import SafeDumper from ansible.module_utils.common.yaml import SafeDumper
from ansible.parsing.yaml.objects import AnsibleUnicode, AnsibleSequence, AnsibleMapping, AnsibleVaultEncryptedUnicode from ansible.parsing.yaml.objects import AnsibleUnicode, AnsibleSequence, AnsibleMapping, AnsibleVaultEncryptedUnicode
from ansible.utils.unsafe_proxy import AnsibleUnsafeText, AnsibleUnsafeBytes from ansible.utils.unsafe_proxy import AnsibleUnsafeText, AnsibleUnsafeBytes
from ansible.template import AnsibleUndefined
from ansible.vars.hostvars import HostVars, HostVarsVars from ansible.vars.hostvars import HostVars, HostVarsVars
from ansible.vars.manager import VarsWithSources from ansible.vars.manager import VarsWithSources
@ -59,6 +60,13 @@ else:
return yaml.representer.SafeRepresenter.represent_str(self, binary_type(data)) return yaml.representer.SafeRepresenter.represent_str(self, binary_type(data))
def represent_undefined(self, data):
# Here bool will ensure _fail_with_undefined_error happens
# if the value is Undefined.
# This happens because Jinja sets __bool__ on StrictUndefined
return bool(data)
AnsibleDumper.add_representer( AnsibleDumper.add_representer(
AnsibleUnicode, AnsibleUnicode,
represent_unicode, represent_unicode,
@ -103,3 +111,8 @@ AnsibleDumper.add_representer(
AnsibleVaultEncryptedUnicode, AnsibleVaultEncryptedUnicode,
represent_vault_encrypted_unicode, represent_vault_encrypted_unicode,
) )
AnsibleDumper.add_representer(
AnsibleUndefined,
represent_undefined,
)

@ -47,13 +47,19 @@ UUID_NAMESPACE_ANSIBLE = uuid.UUID('361E6D51-FAEC-444A-9079-341386DA8E2E')
def to_yaml(a, *args, **kw): def to_yaml(a, *args, **kw):
'''Make verbose, human readable yaml''' '''Make verbose, human readable yaml'''
default_flow_style = kw.pop('default_flow_style', None) default_flow_style = kw.pop('default_flow_style', None)
try:
transformed = yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, default_flow_style=default_flow_style, **kw) transformed = yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, default_flow_style=default_flow_style, **kw)
except Exception as e:
raise AnsibleFilterError("to_yaml - %s" % to_native(e), orig_exc=e)
return to_text(transformed) return to_text(transformed)
def to_nice_yaml(a, indent=4, *args, **kw): def to_nice_yaml(a, indent=4, *args, **kw):
'''Make verbose, human readable yaml''' '''Make verbose, human readable yaml'''
try:
transformed = yaml.dump(a, Dumper=AnsibleDumper, indent=indent, allow_unicode=True, default_flow_style=False, **kw) transformed = yaml.dump(a, Dumper=AnsibleDumper, indent=indent, allow_unicode=True, default_flow_style=False, **kw)
except Exception as e:
raise AnsibleFilterError("to_nice_yaml - %s" % to_native(e), orig_exc=e)
return to_text(transformed) return to_text(transformed)

@ -21,11 +21,14 @@ __metaclass__ = type
import io import io
import yaml import yaml
from jinja2.exceptions import UndefinedError
from units.compat import unittest from units.compat import unittest
from ansible.parsing import vault from ansible.parsing import vault
from ansible.parsing.yaml import dumper, objects from ansible.parsing.yaml import dumper, objects
from ansible.parsing.yaml.loader import AnsibleLoader from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.module_utils.six import PY2 from ansible.module_utils.six import PY2
from ansible.template import AnsibleUndefined
from ansible.utils.unsafe_proxy import AnsibleUnsafeText, AnsibleUnsafeBytes from ansible.utils.unsafe_proxy import AnsibleUnsafeText, AnsibleUnsafeBytes
from units.mock.yaml_helper import YamlTestUtils from units.mock.yaml_helper import YamlTestUtils
@ -109,3 +112,12 @@ class TestAnsibleDumper(unittest.TestCase, YamlTestUtils):
self._dump_string(VarsWithSources(), dumper=self.dumper) self._dump_string(VarsWithSources(), dumper=self.dumper)
except yaml.representer.RepresenterError: except yaml.representer.RepresenterError:
self.fail("Dump VarsWithSources raised RepresenterError unexpectedly!") self.fail("Dump VarsWithSources raised RepresenterError unexpectedly!")
def test_undefined(self):
undefined_object = AnsibleUndefined()
try:
yaml_out = self._dump_string(undefined_object, dumper=self.dumper)
except UndefinedError:
yaml_out = None
self.assertIsNone(yaml_out)

Loading…
Cancel
Save