use ansible json encoder for results in callbacks (#46830)

* use ansible json encoder for results in callbacks

(cherry picked from commit 643ff29d2d)
This commit is contained in:
Brian Coca 2018-10-12 09:37:56 -04:00 committed by Toshio Kuratomi
parent 97a3e59ce8
commit e841e7b53d
7 changed files with 20 additions and 13 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Update callbacks to use Ansible's JSON encoder to avoid known serialization issues

View file

@ -35,7 +35,7 @@ import json
from functools import partial from functools import partial
from ansible.inventory.host import Host from ansible.inventory.host import Host
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase from ansible.plugins.callback import CallbackBase
@ -111,7 +111,7 @@ class CallbackModule(CallbackBase):
'custom_stats': custom_stats, 'custom_stats': custom_stats,
} }
self._display.display(json.dumps(output, indent=4, sort_keys=True)) self._display.display(json.dumps(output, cls=AnsibleJSONEncoder, indent=4, sort_keys=True))
def _record_task_result(self, on_info, result, **kwargs): def _record_task_result(self, on_info, result, **kwargs):
"""This function is used as a partial to add failed/skipped info in a single method""" """This function is used as a partial to add failed/skipped info in a single method"""

View file

@ -24,6 +24,7 @@ import json
from collections import MutableMapping from collections import MutableMapping
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase from ansible.plugins.callback import CallbackBase
@ -61,7 +62,7 @@ class CallbackModule(CallbackBase):
else: else:
data = data.copy() data = data.copy()
invocation = data.pop('invocation', None) invocation = data.pop('invocation', None)
data = json.dumps(data) data = json.dumps(data, cls=AnsibleJSONEncoder)
if invocation is not None: if invocation is not None:
data = json.dumps(invocation) + " => %s " % data data = json.dumps(invocation) + " => %s " % data

View file

@ -70,6 +70,7 @@ import smtplib
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase from ansible.plugins.callback import CallbackBase
@ -207,7 +208,7 @@ class CallbackModule(CallbackBase):
body += self.body_blob(result._result['deprecations'][i], 'exception %d' % (i + 1)) body += self.body_blob(result._result['deprecations'][i], 'exception %d' % (i + 1))
body += 'and a complete dump of the error:\n\n' body += 'and a complete dump of the error:\n\n'
body += self.indent('%s: %s' % (failtype, json.dumps(result._result, indent=4))) body += self.indent('%s: %s' % (failtype, json.dumps(result._result, cls=AnsibleJSONEncoder, indent=4)))
self.mail(subject=subject, body=body) self.mail(subject=subject, body=body)
@ -230,4 +231,4 @@ class CallbackModule(CallbackBase):
def v2_runner_item_on_failed(self, result): def v2_runner_item_on_failed(self, result):
# Pass item information to task failure # Pass item information to task failure
self.itemsubject = result._result['msg'] self.itemsubject = result._result['msg']
self.itembody += self.body_blob(json.dumps(result._result, indent=4), "failed item dump '%(item)s'" % result._result) self.itembody += self.body_blob(json.dumps(result._result, cls=AnsibleJSONEncoder, indent=4), "failed item dump '%(item)s'" % result._result)

View file

@ -70,8 +70,9 @@ import getpass
from datetime import datetime from datetime import datetime
from os.path import basename from os.path import basename
from ansible.plugins.callback import CallbackBase
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase
class SplunkHTTPCollectorSource(object): class SplunkHTTPCollectorSource(object):
@ -116,7 +117,7 @@ class SplunkHTTPCollectorSource(object):
data['ansible_result'] = result._result data['ansible_result'] = result._result
# This wraps the json payload in and outer json event needed by Splunk # This wraps the json payload in and outer json event needed by Splunk
jsondata = json.dumps(data, sort_keys=True) jsondata = json.dumps(data, cls=AnsibleJSONEncoder, sort_keys=True)
jsondata = '{"event":' + jsondata + "}" jsondata = '{"event":' + jsondata + "}"
open_url( open_url(

View file

@ -61,8 +61,9 @@ import getpass
from datetime import datetime from datetime import datetime
from os.path import basename from os.path import basename
from ansible.plugins.callback import CallbackBase
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase
class SumologicHTTPCollectorSource(object): class SumologicHTTPCollectorSource(object):
@ -108,7 +109,7 @@ class SumologicHTTPCollectorSource(object):
open_url( open_url(
url, url,
data=json.dumps(data, sort_keys=True), data=json.dumps(data, cls=AnsibleJSONEncoder, sort_keys=True),
headers={ headers={
'Content-type': 'application/json', 'Content-type': 'application/json',
'X-Sumo-Host': data['ansible_host'] 'X-Sumo-Host': data['ansible_host']

View file

@ -24,11 +24,12 @@ import json
import re import re
import string import string
import sys import sys
from ansible.module_utils._text import to_bytes, to_text
from ansible.module_utils.six import string_types
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.plugins.callback import CallbackBase, strip_internal_keys from ansible.plugins.callback import CallbackBase, strip_internal_keys
from ansible.plugins.callback.default import CallbackModule as Default from ansible.plugins.callback.default import CallbackModule as Default
from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_bytes, to_text
from ansible.parsing.yaml.dumper import AnsibleDumper
# from http://stackoverflow.com/a/15423007/115478 # from http://stackoverflow.com/a/15423007/115478
@ -81,7 +82,7 @@ class CallbackModule(Default):
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):
return json.dumps(dict(censored="the output has been hidden due to the fact that 'no_log: true' was specified for this result")) return json.dumps(dict(censored="The output has been hidden due to the fact that 'no_log: true' was specified for this result"))
# All result keys stating with _ansible_ are internal, so remove them from the result before we output anything. # All result keys stating with _ansible_ are internal, so remove them from the result before we output anything.
abridged_result = strip_internal_keys(result) abridged_result = strip_internal_keys(result)