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:
parent
97a3e59ce8
commit
e841e7b53d
7 changed files with 20 additions and 13 deletions
2
changelogs/fragments/callback_fixes.yml
Normal file
2
changelogs/fragments/callback_fixes.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- Update callbacks to use Ansible's JSON encoder to avoid known serialization issues
|
|
@ -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"""
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue