1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
from __future__ import unicode_literals
import io
import os
from ansible import constants as C
from ansible.module_utils import six
try:
from ansible.plugins import callback_loader
except ImportError:
from ansible.plugins.loader import callback_loader
try:
pprint = __import__(os.environ['NICE_STDOUT_PPRINT'])
except KeyError:
pprint = None
DefaultModule = callback_loader.get('default', class_only=True)
DOCUMENTATION = '''
callback: nice_stdout
type: stdout
extends_documentation_fragment:
- default_callback
options:
check_mode_markers:
name: Show markers when running in check mode
description:
- "Toggle to control displaying markers when running in check mode. The markers are C(DRY RUN)
at the beggining and ending of playbook execution (when calling C(ansible-playbook --check))
and C(CHECK MODE) as a suffix at every play and task that is run in check mode."
type: bool
default: no
version_added: 2.9
env:
- name: ANSIBLE_CHECK_MODE_MARKERS
ini:
- key: check_mode_markers
section: defaults
'''
def printi(tio, obj, key=None, indent=0):
def write(s, *args):
if args:
s %= args
tio.write(' ' * indent)
if key is not None:
tio.write('%s: ' % (key,))
tio.write(s)
tio.write('\n')
if isinstance(obj, (list, tuple)):
write('[')
for i, obj2 in enumerate(obj):
printi(tio, obj2, key=i, indent=indent+1)
key = None
write(']')
elif isinstance(obj, dict):
write('{')
for key2, obj2 in sorted(six.iteritems(obj)):
if not (key2.startswith('_ansible_') or
key2.endswith('_lines')):
printi(tio, obj2, key=key2, indent=indent+1)
key = None
write('}')
elif isinstance(obj, six.text_type):
for line in obj.splitlines():
write('%s', line.rstrip('\r\n'))
elif isinstance(obj, six.binary_type):
obj = obj.decode('utf-8', 'replace')
for line in obj.splitlines():
write('%s', line.rstrip('\r\n'))
else:
write('%r', obj)
class CallbackModule(DefaultModule):
CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'stdout'
CALLBACK_NAME = 'nice_stdout'
def _dump_results(self, result, *args, **kwargs):
try:
tio = io.StringIO()
if pprint:
pprint.pprint(result, stream=tio)
else:
printi(tio, result)
return tio.getvalue() #.encode('ascii', 'replace')
except:
import traceback
traceback.print_exc()
raise
def v2_runner_on_failed(self, result, ignore_errors=False):
delegated_vars = result._result.get('_ansible_delegated_vars')
self._clean_results(result._result, result._task.action)
if self._play.strategy == 'free' and self._last_task_banner != result._task._uuid:
self._print_task_banner(result._task)
self._handle_exception(result._result)
self._handle_warnings(result._result)
if result._task.loop and 'results' in result._result:
return
if delegated_vars:
msg = "[%s -> %s]: FAILED! => %s" % (
result._host.get_name(),
delegated_vars['ansible_host'],
self._dump_results(result._result),
)
else:
msg = "[%s]: FAILED! => %s" % (
result._host.get_name(),
self._dump_results(result._result),
)
s = "fatal: %s: %s" % (
result._task.get_path() or '(dynamic task)',
msg,
)
self._display.display(s, color=C.COLOR_ERROR)
|