mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
* Prevent yaml callback from modifying PyYAML.
* Fix changelog fragment.
* Update changelogs/fragments/3478-yaml-callback.yml
Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>
Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>
(cherry picked from commit 5895e50185
)
Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
59af80235b
commit
2917389779
3 changed files with 63 additions and 24 deletions
2
changelogs/fragments/3478-yaml-callback.yml
Normal file
2
changelogs/fragments/3478-yaml-callback.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- "yaml callback plugin - avoid modifying PyYAML so that other plugins using it on the controller, like the ``to_yaml`` filter, do not produce different output (https://github.com/ansible-collections/community.general/issues/3471, https://github.com/ansible-collections/community.general/pull/3478)."
|
|
@ -42,28 +42,29 @@ def should_use_block(value):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def my_represent_scalar(self, tag, value, style=None):
|
class MyDumper(AnsibleDumper):
|
||||||
"""Uses block style for multi-line strings"""
|
def represent_scalar(self, tag, value, style=None):
|
||||||
if style is None:
|
"""Uses block style for multi-line strings"""
|
||||||
if should_use_block(value):
|
if style is None:
|
||||||
style = '|'
|
if should_use_block(value):
|
||||||
# we care more about readable than accuracy, so...
|
style = '|'
|
||||||
# ...no trailing space
|
# we care more about readable than accuracy, so...
|
||||||
value = value.rstrip()
|
# ...no trailing space
|
||||||
# ...and non-printable characters
|
value = value.rstrip()
|
||||||
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
|
# ...and non-printable characters
|
||||||
# ...tabs prevent blocks from expanding
|
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
|
||||||
value = value.expandtabs()
|
# ...tabs prevent blocks from expanding
|
||||||
# ...and odd bits of whitespace
|
value = value.expandtabs()
|
||||||
value = re.sub(r'[\x0b\x0c\r]', '', value)
|
# ...and odd bits of whitespace
|
||||||
# ...as does trailing space
|
value = re.sub(r'[\x0b\x0c\r]', '', value)
|
||||||
value = re.sub(r' +\n', '\n', value)
|
# ...as does trailing space
|
||||||
else:
|
value = re.sub(r' +\n', '\n', value)
|
||||||
style = self.default_style
|
else:
|
||||||
node = yaml.representer.ScalarNode(tag, value, style=style)
|
style = self.default_style
|
||||||
if self.alias_key is not None:
|
node = yaml.representer.ScalarNode(tag, value, style=style)
|
||||||
self.represented_objects[self.alias_key] = node
|
if self.alias_key is not None:
|
||||||
return node
|
self.represented_objects[self.alias_key] = node
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
class CallbackModule(Default):
|
class CallbackModule(Default):
|
||||||
|
@ -79,7 +80,6 @@ class CallbackModule(Default):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CallbackModule, self).__init__()
|
super(CallbackModule, self).__init__()
|
||||||
yaml.representer.BaseRepresenter.represent_scalar = my_represent_scalar
|
|
||||||
|
|
||||||
def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
|
def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
|
||||||
if result.get('_ansible_no_log', False):
|
if result.get('_ansible_no_log', False):
|
||||||
|
@ -121,7 +121,7 @@ class CallbackModule(Default):
|
||||||
|
|
||||||
if abridged_result:
|
if abridged_result:
|
||||||
dumped += '\n'
|
dumped += '\n'
|
||||||
dumped += to_text(yaml.dump(abridged_result, allow_unicode=True, width=1000, Dumper=AnsibleDumper, default_flow_style=False))
|
dumped += to_text(yaml.dump(abridged_result, allow_unicode=True, width=1000, Dumper=MyDumper, default_flow_style=False))
|
||||||
|
|
||||||
# indent by a couple of spaces
|
# indent by a couple of spaces
|
||||||
dumped = '\n '.join(dumped.split('\n')).rstrip()
|
dumped = '\n '.join(dumped.split('\n')).rstrip()
|
||||||
|
|
|
@ -58,3 +58,40 @@
|
||||||
"PLAY RECAP *********************************************************************",
|
"PLAY RECAP *********************************************************************",
|
||||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||||
]
|
]
|
||||||
|
- name: Test to_yaml
|
||||||
|
environment:
|
||||||
|
ANSIBLE_NOCOLOR: 'true'
|
||||||
|
ANSIBLE_FORCE_COLOR: 'false'
|
||||||
|
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
||||||
|
playbook: |
|
||||||
|
- hosts: testhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
data: |
|
||||||
|
line 1
|
||||||
|
line 2
|
||||||
|
line 3
|
||||||
|
tasks:
|
||||||
|
- name: Test to_yaml
|
||||||
|
debug:
|
||||||
|
msg: "{{ '{{' }}'{{ '{{' }}'{{ '}}' }} data | to_yaml {{ '{{' }}'{{ '}}' }}'{{ '}}' }}"
|
||||||
|
# The above should be: msg: "{{ data | to_yaml }}"
|
||||||
|
# Unfortunately, the way Ansible handles templating, we need to do some funny 'escaping' tricks...
|
||||||
|
expected_output: [
|
||||||
|
"",
|
||||||
|
"PLAY [testhost] ****************************************************************",
|
||||||
|
"",
|
||||||
|
"TASK [Test to_yaml] ************************************************************",
|
||||||
|
"ok: [testhost] => ",
|
||||||
|
" msg: |-",
|
||||||
|
" 'line 1",
|
||||||
|
" ",
|
||||||
|
" line 2",
|
||||||
|
" ",
|
||||||
|
" line 3",
|
||||||
|
" ",
|
||||||
|
" '",
|
||||||
|
"",
|
||||||
|
"PLAY RECAP *********************************************************************",
|
||||||
|
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in a new issue