ansible-core 2.19.0b1__py3-none-any.whl → 2.19.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_errors/_handler.py +4 -4
- ansible/_internal/_json/__init__.py +47 -4
- ansible/_internal/_json/_profiles/_legacy.py +2 -3
- ansible/_internal/_templating/_jinja_bits.py +4 -4
- ansible/_internal/_templating/_jinja_plugins.py +5 -11
- ansible/cli/__init__.py +9 -3
- ansible/cli/doc.py +14 -7
- ansible/config/base.yml +17 -20
- ansible/executor/process/worker.py +31 -26
- ansible/executor/task_executor.py +32 -23
- ansible/executor/task_queue_manager.py +62 -52
- ansible/executor/task_result.py +168 -72
- ansible/inventory/manager.py +2 -1
- ansible/module_utils/ansible_release.py +1 -1
- ansible/module_utils/basic.py +4 -6
- ansible/module_utils/common/warnings.py +1 -1
- ansible/parsing/utils/jsonify.py +40 -0
- ansible/parsing/yaml/objects.py +16 -5
- ansible/playbook/included_file.py +25 -12
- ansible/plugins/callback/__init__.py +173 -86
- ansible/plugins/callback/default.py +79 -79
- ansible/plugins/callback/junit.py +20 -19
- ansible/plugins/callback/minimal.py +17 -17
- ansible/plugins/callback/oneline.py +16 -15
- ansible/plugins/callback/tree.py +6 -5
- ansible/plugins/filter/core.py +8 -1
- ansible/plugins/strategy/__init__.py +70 -76
- ansible/plugins/strategy/free.py +4 -4
- ansible/plugins/strategy/linear.py +11 -9
- ansible/plugins/test/core.py +1 -1
- ansible/release.py +1 -1
- ansible/template/__init__.py +7 -5
- ansible/utils/display.py +10 -10
- ansible/utils/vars.py +23 -0
- ansible/vars/clean.py +1 -1
- ansible/vars/manager.py +2 -19
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +1 -1
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/RECORD +48 -46
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/BSD-3-Clause.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/WHEEL +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
@@ -21,7 +21,7 @@ DOCUMENTATION = """
|
|
21
21
|
|
22
22
|
from ansible import constants as C
|
23
23
|
from ansible import context
|
24
|
-
from ansible.executor.task_result import
|
24
|
+
from ansible.executor.task_result import CallbackTaskResult
|
25
25
|
from ansible.playbook.task_include import TaskInclude
|
26
26
|
from ansible.plugins.callback import CallbackBase
|
27
27
|
from ansible.utils.color import colorize, hostcolor
|
@@ -47,39 +47,39 @@ class CallbackModule(CallbackBase):
|
|
47
47
|
self._task_type_cache = {}
|
48
48
|
super(CallbackModule, self).__init__()
|
49
49
|
|
50
|
-
def v2_runner_on_failed(self, result:
|
50
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
51
51
|
host_label = self.host_label(result)
|
52
52
|
|
53
|
-
if self._last_task_banner != result.
|
54
|
-
self._print_task_banner(result.
|
53
|
+
if self._last_task_banner != result.task._uuid:
|
54
|
+
self._print_task_banner(result.task)
|
55
55
|
|
56
56
|
self._handle_warnings_and_exception(result)
|
57
57
|
|
58
58
|
# FIXME: this method should not exist, delegate "suggested keys to display" to the plugin or something... As-is, the placement of this
|
59
59
|
# call obliterates `results`, which causes a task summary to be printed on loop failures, which we don't do anywhere else.
|
60
|
-
self._clean_results(result.
|
60
|
+
self._clean_results(result.result, result.task.action)
|
61
61
|
|
62
|
-
if result.
|
62
|
+
if result.task.loop and 'results' in result.result:
|
63
63
|
self._process_items(result)
|
64
64
|
else:
|
65
65
|
if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
|
66
|
-
self._print_task_path(result.
|
67
|
-
msg = "fatal: [%s]: FAILED! => %s" % (host_label, self._dump_results(result.
|
66
|
+
self._print_task_path(result.task)
|
67
|
+
msg = "fatal: [%s]: FAILED! => %s" % (host_label, self._dump_results(result.result))
|
68
68
|
self._display.display(msg, color=C.COLOR_ERROR, stderr=self.get_option('display_failed_stderr'))
|
69
69
|
|
70
70
|
if ignore_errors:
|
71
71
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
72
72
|
|
73
|
-
def v2_runner_on_ok(self, result:
|
73
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
74
74
|
host_label = self.host_label(result)
|
75
75
|
|
76
|
-
if isinstance(result.
|
77
|
-
if self._last_task_banner != result.
|
78
|
-
self._print_task_banner(result.
|
76
|
+
if isinstance(result.task, TaskInclude):
|
77
|
+
if self._last_task_banner != result.task._uuid:
|
78
|
+
self._print_task_banner(result.task)
|
79
79
|
return
|
80
|
-
elif result.
|
81
|
-
if self._last_task_banner != result.
|
82
|
-
self._print_task_banner(result.
|
80
|
+
elif result.result.get('changed', False):
|
81
|
+
if self._last_task_banner != result.task._uuid:
|
82
|
+
self._print_task_banner(result.task)
|
83
83
|
|
84
84
|
msg = "changed: [%s]" % (host_label,)
|
85
85
|
color = C.COLOR_CHANGED
|
@@ -87,52 +87,52 @@ class CallbackModule(CallbackBase):
|
|
87
87
|
if not self.get_option('display_ok_hosts'):
|
88
88
|
return
|
89
89
|
|
90
|
-
if self._last_task_banner != result.
|
91
|
-
self._print_task_banner(result.
|
90
|
+
if self._last_task_banner != result.task._uuid:
|
91
|
+
self._print_task_banner(result.task)
|
92
92
|
|
93
93
|
msg = "ok: [%s]" % (host_label,)
|
94
94
|
color = C.COLOR_OK
|
95
95
|
|
96
96
|
self._handle_warnings_and_exception(result)
|
97
97
|
|
98
|
-
if result.
|
98
|
+
if result.task.loop and 'results' in result.result:
|
99
99
|
self._process_items(result)
|
100
100
|
else:
|
101
|
-
self._clean_results(result.
|
101
|
+
self._clean_results(result.result, result.task.action)
|
102
102
|
|
103
103
|
if self._run_is_verbose(result):
|
104
|
-
msg += " => %s" % (self._dump_results(result.
|
104
|
+
msg += " => %s" % (self._dump_results(result.result),)
|
105
105
|
self._display.display(msg, color=color)
|
106
106
|
|
107
|
-
def v2_runner_on_skipped(self, result:
|
107
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
108
108
|
if self.get_option('display_skipped_hosts'):
|
109
109
|
|
110
|
-
self._clean_results(result.
|
110
|
+
self._clean_results(result.result, result.task.action)
|
111
111
|
|
112
|
-
if self._last_task_banner != result.
|
113
|
-
self._print_task_banner(result.
|
112
|
+
if self._last_task_banner != result.task._uuid:
|
113
|
+
self._print_task_banner(result.task)
|
114
114
|
|
115
115
|
self._handle_warnings_and_exception(result)
|
116
116
|
|
117
|
-
if result.
|
117
|
+
if result.task.loop is not None and 'results' in result.result:
|
118
118
|
self._process_items(result)
|
119
119
|
|
120
|
-
msg = "skipping: [%s]" % result.
|
120
|
+
msg = "skipping: [%s]" % result.host.get_name()
|
121
121
|
if self._run_is_verbose(result):
|
122
|
-
msg += " => %s" % self._dump_results(result.
|
122
|
+
msg += " => %s" % self._dump_results(result.result)
|
123
123
|
self._display.display(msg, color=C.COLOR_SKIP)
|
124
124
|
|
125
|
-
def v2_runner_on_unreachable(self, result:
|
126
|
-
if self._last_task_banner != result.
|
127
|
-
self._print_task_banner(result.
|
125
|
+
def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
|
126
|
+
if self._last_task_banner != result.task._uuid:
|
127
|
+
self._print_task_banner(result.task)
|
128
128
|
|
129
129
|
self._handle_warnings_and_exception(result)
|
130
130
|
|
131
131
|
host_label = self.host_label(result)
|
132
|
-
msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result.
|
132
|
+
msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result.result))
|
133
133
|
self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.get_option('display_failed_stderr'))
|
134
134
|
|
135
|
-
if result.
|
135
|
+
if result.task.ignore_unreachable:
|
136
136
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
137
137
|
|
138
138
|
def v2_playbook_on_no_hosts_matched(self):
|
@@ -222,29 +222,29 @@ class CallbackModule(CallbackBase):
|
|
222
222
|
|
223
223
|
self._display.banner(msg)
|
224
224
|
|
225
|
-
def v2_on_file_diff(self, result):
|
226
|
-
if result.
|
227
|
-
for res in result.
|
225
|
+
def v2_on_file_diff(self, result: CallbackTaskResult) -> None:
|
226
|
+
if result.task.loop and 'results' in result.result:
|
227
|
+
for res in result.result['results']:
|
228
228
|
if 'diff' in res and res['diff'] and res.get('changed', False):
|
229
229
|
diff = self._get_diff(res['diff'])
|
230
230
|
if diff:
|
231
|
-
if self._last_task_banner != result.
|
232
|
-
self._print_task_banner(result.
|
231
|
+
if self._last_task_banner != result.task._uuid:
|
232
|
+
self._print_task_banner(result.task)
|
233
233
|
self._display.display(diff)
|
234
|
-
elif 'diff' in result.
|
235
|
-
diff = self._get_diff(result.
|
234
|
+
elif 'diff' in result.result and result.result['diff'] and result.result.get('changed', False):
|
235
|
+
diff = self._get_diff(result.result['diff'])
|
236
236
|
if diff:
|
237
|
-
if self._last_task_banner != result.
|
238
|
-
self._print_task_banner(result.
|
237
|
+
if self._last_task_banner != result.task._uuid:
|
238
|
+
self._print_task_banner(result.task)
|
239
239
|
self._display.display(diff)
|
240
240
|
|
241
|
-
def v2_runner_item_on_ok(self, result:
|
241
|
+
def v2_runner_item_on_ok(self, result: CallbackTaskResult) -> None:
|
242
242
|
host_label = self.host_label(result)
|
243
|
-
if isinstance(result.
|
243
|
+
if isinstance(result.task, TaskInclude):
|
244
244
|
return
|
245
|
-
elif result.
|
246
|
-
if self._last_task_banner != result.
|
247
|
-
self._print_task_banner(result.
|
245
|
+
elif result.result.get('changed', False):
|
246
|
+
if self._last_task_banner != result.task._uuid:
|
247
|
+
self._print_task_banner(result.task)
|
248
248
|
|
249
249
|
msg = 'changed'
|
250
250
|
color = C.COLOR_CHANGED
|
@@ -252,47 +252,47 @@ class CallbackModule(CallbackBase):
|
|
252
252
|
if not self.get_option('display_ok_hosts'):
|
253
253
|
return
|
254
254
|
|
255
|
-
if self._last_task_banner != result.
|
256
|
-
self._print_task_banner(result.
|
255
|
+
if self._last_task_banner != result.task._uuid:
|
256
|
+
self._print_task_banner(result.task)
|
257
257
|
|
258
258
|
msg = 'ok'
|
259
259
|
color = C.COLOR_OK
|
260
260
|
|
261
261
|
self._handle_warnings_and_exception(result)
|
262
262
|
|
263
|
-
msg = "%s: [%s] => (item=%s)" % (msg, host_label, self._get_item_label(result.
|
264
|
-
self._clean_results(result.
|
263
|
+
msg = "%s: [%s] => (item=%s)" % (msg, host_label, self._get_item_label(result.result))
|
264
|
+
self._clean_results(result.result, result.task.action)
|
265
265
|
if self._run_is_verbose(result):
|
266
|
-
msg += " => %s" % self._dump_results(result.
|
266
|
+
msg += " => %s" % self._dump_results(result.result)
|
267
267
|
self._display.display(msg, color=color)
|
268
268
|
|
269
|
-
def v2_runner_item_on_failed(self, result:
|
270
|
-
if self._last_task_banner != result.
|
271
|
-
self._print_task_banner(result.
|
269
|
+
def v2_runner_item_on_failed(self, result: CallbackTaskResult) -> None:
|
270
|
+
if self._last_task_banner != result.task._uuid:
|
271
|
+
self._print_task_banner(result.task)
|
272
272
|
|
273
273
|
self._handle_warnings_and_exception(result)
|
274
274
|
|
275
275
|
host_label = self.host_label(result)
|
276
276
|
|
277
277
|
msg = "failed: [%s]" % (host_label,)
|
278
|
-
self._clean_results(result.
|
278
|
+
self._clean_results(result.result, result.task.action)
|
279
279
|
self._display.display(
|
280
|
-
msg + " (item=%s) => %s" % (self._get_item_label(result.
|
280
|
+
msg + " (item=%s) => %s" % (self._get_item_label(result.result), self._dump_results(result.result)),
|
281
281
|
color=C.COLOR_ERROR,
|
282
282
|
stderr=self.get_option('display_failed_stderr')
|
283
283
|
)
|
284
284
|
|
285
|
-
def v2_runner_item_on_skipped(self, result:
|
285
|
+
def v2_runner_item_on_skipped(self, result: CallbackTaskResult) -> None:
|
286
286
|
if self.get_option('display_skipped_hosts'):
|
287
|
-
if self._last_task_banner != result.
|
288
|
-
self._print_task_banner(result.
|
287
|
+
if self._last_task_banner != result.task._uuid:
|
288
|
+
self._print_task_banner(result.task)
|
289
289
|
|
290
290
|
self._handle_warnings_and_exception(result)
|
291
291
|
|
292
|
-
self._clean_results(result.
|
293
|
-
msg = "skipping: [%s] => (item=%s) " % (result.
|
292
|
+
self._clean_results(result.result, result.task.action)
|
293
|
+
msg = "skipping: [%s] => (item=%s) " % (result.host.get_name(), self._get_item_label(result.result))
|
294
294
|
if self._run_is_verbose(result):
|
295
|
-
msg += " => %s" % self._dump_results(result.
|
295
|
+
msg += " => %s" % self._dump_results(result.result)
|
296
296
|
self._display.display(msg, color=C.COLOR_SKIP)
|
297
297
|
|
298
298
|
def v2_playbook_on_include(self, included_file):
|
@@ -377,37 +377,37 @@ class CallbackModule(CallbackBase):
|
|
377
377
|
if context.CLIARGS['check'] and self.get_option('check_mode_markers'):
|
378
378
|
self._display.banner("DRY RUN")
|
379
379
|
|
380
|
-
def v2_runner_retry(self, result):
|
381
|
-
task_name = result.task_name or result.
|
380
|
+
def v2_runner_retry(self, result: CallbackTaskResult) -> None:
|
381
|
+
task_name = result.task_name or result.task
|
382
382
|
host_label = self.host_label(result)
|
383
|
-
msg = "FAILED - RETRYING: [%s]: %s (%d retries left)." % (host_label, task_name, result.
|
383
|
+
msg = "FAILED - RETRYING: [%s]: %s (%d retries left)." % (host_label, task_name, result.result['retries'] - result.result['attempts'])
|
384
384
|
if self._run_is_verbose(result, verbosity=2):
|
385
|
-
msg += "Result was: %s" % self._dump_results(result.
|
385
|
+
msg += "Result was: %s" % self._dump_results(result.result)
|
386
386
|
self._display.display(msg, color=C.COLOR_DEBUG)
|
387
387
|
|
388
|
-
def v2_runner_on_async_poll(self, result):
|
389
|
-
host = result.
|
390
|
-
jid = result.
|
391
|
-
started = result.
|
392
|
-
finished = result.
|
388
|
+
def v2_runner_on_async_poll(self, result: CallbackTaskResult) -> None:
|
389
|
+
host = result.host.get_name()
|
390
|
+
jid = result.result.get('ansible_job_id')
|
391
|
+
started = result.result.get('started')
|
392
|
+
finished = result.result.get('finished')
|
393
393
|
self._display.display(
|
394
394
|
'ASYNC POLL on %s: jid=%s started=%s finished=%s' % (host, jid, started, finished),
|
395
395
|
color=C.COLOR_DEBUG
|
396
396
|
)
|
397
397
|
|
398
|
-
def v2_runner_on_async_ok(self, result):
|
399
|
-
host = result.
|
400
|
-
jid = result.
|
398
|
+
def v2_runner_on_async_ok(self, result: CallbackTaskResult) -> None:
|
399
|
+
host = result.host.get_name()
|
400
|
+
jid = result.result.get('ansible_job_id')
|
401
401
|
self._display.display("ASYNC OK on %s: jid=%s" % (host, jid), color=C.COLOR_DEBUG)
|
402
402
|
|
403
|
-
def v2_runner_on_async_failed(self, result):
|
404
|
-
host = result.
|
403
|
+
def v2_runner_on_async_failed(self, result: CallbackTaskResult) -> None:
|
404
|
+
host = result.host.get_name()
|
405
405
|
|
406
406
|
# Attempt to get the async job ID. If the job does not finish before the
|
407
407
|
# async timeout value, the ID may be within the unparsed 'async_result' dict.
|
408
|
-
jid = result.
|
409
|
-
if not jid and 'async_result' in result.
|
410
|
-
jid = result.
|
408
|
+
jid = result.result.get('ansible_job_id')
|
409
|
+
if not jid and 'async_result' in result.result:
|
410
|
+
jid = result.result['async_result'].get('ansible_job_id')
|
411
411
|
self._display.display("ASYNC FAILED on %s: jid=%s" % (host, jid), color=C.COLOR_DEBUG)
|
412
412
|
|
413
413
|
def v2_playbook_on_notify(self, handler, host):
|
@@ -86,12 +86,14 @@ import decimal
|
|
86
86
|
import os
|
87
87
|
import time
|
88
88
|
import re
|
89
|
+
import typing as t
|
89
90
|
|
90
91
|
from ansible import constants
|
91
|
-
from ansible.module_utils.common.messages import ErrorSummary
|
92
92
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
93
93
|
from ansible.playbook.task import Task
|
94
94
|
from ansible.plugins.callback import CallbackBase
|
95
|
+
from ansible.executor.task_result import CallbackTaskResult
|
96
|
+
from ansible.playbook.included_file import IncludedFile
|
95
97
|
from ansible.utils._junit_xml import (
|
96
98
|
TestCase,
|
97
99
|
TestError,
|
@@ -184,23 +186,23 @@ class CallbackModule(CallbackBase):
|
|
184
186
|
|
185
187
|
self._task_data[uuid] = TaskData(uuid, name, path, play, action)
|
186
188
|
|
187
|
-
def _finish_task(self, status, result):
|
189
|
+
def _finish_task(self, status: str, result: IncludedFile | CallbackTaskResult) -> None:
|
188
190
|
""" record the results of a task for a single host """
|
189
191
|
|
190
|
-
|
192
|
+
if isinstance(result, CallbackTaskResult):
|
193
|
+
task_uuid = result.task._uuid
|
194
|
+
host_uuid = result.host._uuid
|
195
|
+
host_name = result.host.name
|
191
196
|
|
192
|
-
|
193
|
-
|
194
|
-
host_name = result._host.name
|
197
|
+
if self._fail_on_change == 'true' and status == 'ok' and result.result.get('changed', False):
|
198
|
+
status = 'failed'
|
195
199
|
else:
|
200
|
+
task_uuid = result._task._uuid
|
196
201
|
host_uuid = 'include'
|
197
202
|
host_name = 'include'
|
198
203
|
|
199
204
|
task_data = self._task_data[task_uuid]
|
200
205
|
|
201
|
-
if self._fail_on_change == 'true' and status == 'ok' and result._result.get('changed', False):
|
202
|
-
status = 'failed'
|
203
|
-
|
204
206
|
# ignore failure if expected and toggle result if asked for
|
205
207
|
if status == 'failed' and 'EXPECTED FAILURE' in task_data.name:
|
206
208
|
status = 'ok'
|
@@ -233,7 +235,8 @@ class CallbackModule(CallbackBase):
|
|
233
235
|
if host_data.status == 'included':
|
234
236
|
return TestCase(name=name, classname=junit_classname, time=duration, system_out=str(host_data.result))
|
235
237
|
|
236
|
-
|
238
|
+
task_result = t.cast(CallbackTaskResult, host_data.result)
|
239
|
+
res = task_result.result
|
237
240
|
rc = res.get('rc', 0)
|
238
241
|
dump = self._dump_results(res, indent=0)
|
239
242
|
dump = self._cleanse_string(dump)
|
@@ -243,10 +246,8 @@ class CallbackModule(CallbackBase):
|
|
243
246
|
|
244
247
|
test_case = TestCase(name=name, classname=junit_classname, time=duration)
|
245
248
|
|
246
|
-
error_summary: ErrorSummary
|
247
|
-
|
248
249
|
if host_data.status == 'failed':
|
249
|
-
if error_summary :=
|
250
|
+
if error_summary := task_result.exception:
|
250
251
|
message = error_summary._format()
|
251
252
|
output = error_summary.formatted_traceback
|
252
253
|
test_case.errors.append(TestError(message=message, output=output))
|
@@ -309,19 +310,19 @@ class CallbackModule(CallbackBase):
|
|
309
310
|
def v2_playbook_on_handler_task_start(self, task: Task) -> None:
|
310
311
|
self._start_task(task)
|
311
312
|
|
312
|
-
def v2_runner_on_failed(self, result, ignore_errors=False):
|
313
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors=False) -> None:
|
313
314
|
if ignore_errors and self._fail_on_ignore != 'true':
|
314
315
|
self._finish_task('ok', result)
|
315
316
|
else:
|
316
317
|
self._finish_task('failed', result)
|
317
318
|
|
318
|
-
def v2_runner_on_ok(self, result):
|
319
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
319
320
|
self._finish_task('ok', result)
|
320
321
|
|
321
|
-
def v2_runner_on_skipped(self, result):
|
322
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
322
323
|
self._finish_task('skipped', result)
|
323
324
|
|
324
|
-
def v2_playbook_on_include(self, included_file):
|
325
|
+
def v2_playbook_on_include(self, included_file: IncludedFile) -> None:
|
325
326
|
self._finish_task('included', included_file)
|
326
327
|
|
327
328
|
def v2_playbook_on_stats(self, stats):
|
@@ -347,7 +348,7 @@ class TaskData:
|
|
347
348
|
if host.uuid in self.host_data:
|
348
349
|
if host.status == 'included':
|
349
350
|
# concatenate task include output from multiple items
|
350
|
-
host.result = '
|
351
|
+
host.result = f'{self.host_data[host.uuid].result}\n{host.result}'
|
351
352
|
else:
|
352
353
|
raise Exception('%s: %s: %s: duplicate host callback: %s' % (self.path, self.play, self.name, host.name))
|
353
354
|
|
@@ -359,7 +360,7 @@ class HostData:
|
|
359
360
|
Data about an individual host.
|
360
361
|
"""
|
361
362
|
|
362
|
-
def __init__(self, uuid, name, status, result):
|
363
|
+
def __init__(self, uuid: str, name: str, status: str, result: IncludedFile | CallbackTaskResult | str) -> None:
|
363
364
|
self.uuid = uuid
|
364
365
|
self.name = name
|
365
366
|
self.status = status
|
@@ -15,7 +15,7 @@ DOCUMENTATION = """
|
|
15
15
|
- result_format_callback
|
16
16
|
"""
|
17
17
|
|
18
|
-
from ansible.executor.task_result import
|
18
|
+
from ansible.executor.task_result import CallbackTaskResult
|
19
19
|
from ansible.plugins.callback import CallbackBase
|
20
20
|
from ansible import constants as C
|
21
21
|
|
@@ -41,41 +41,41 @@ class CallbackModule(CallbackBase):
|
|
41
41
|
|
42
42
|
return buf + "\n"
|
43
43
|
|
44
|
-
def v2_runner_on_failed(self, result:
|
44
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
45
45
|
self._handle_warnings_and_exception(result)
|
46
46
|
|
47
|
-
if result.
|
48
|
-
self._display.display(self._command_generic_msg(result.
|
47
|
+
if result.task.action in C.MODULE_NO_JSON and 'module_stderr' not in result.result:
|
48
|
+
self._display.display(self._command_generic_msg(result.host.get_name(), result.result, "FAILED"), color=C.COLOR_ERROR)
|
49
49
|
else:
|
50
|
-
self._display.display("%s | FAILED! => %s" % (result.
|
50
|
+
self._display.display("%s | FAILED! => %s" % (result.host.get_name(), self._dump_results(result.result, indent=4)), color=C.COLOR_ERROR)
|
51
51
|
|
52
|
-
def v2_runner_on_ok(self, result:
|
52
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
53
53
|
self._handle_warnings_and_exception(result)
|
54
54
|
|
55
|
-
self._clean_results(result.
|
55
|
+
self._clean_results(result.result, result.task.action)
|
56
56
|
|
57
|
-
if result.
|
57
|
+
if result.result.get('changed', False):
|
58
58
|
color = C.COLOR_CHANGED
|
59
59
|
state = 'CHANGED'
|
60
60
|
else:
|
61
61
|
color = C.COLOR_OK
|
62
62
|
state = 'SUCCESS'
|
63
63
|
|
64
|
-
if result.
|
65
|
-
self._display.display(self._command_generic_msg(result.
|
64
|
+
if result.task.action in C.MODULE_NO_JSON and 'ansible_job_id' not in result.result:
|
65
|
+
self._display.display(self._command_generic_msg(result.host.get_name(), result.result, state), color=color)
|
66
66
|
else:
|
67
|
-
self._display.display("%s | %s => %s" % (result.
|
67
|
+
self._display.display("%s | %s => %s" % (result.host.get_name(), state, self._dump_results(result.result, indent=4)), color=color)
|
68
68
|
|
69
|
-
def v2_runner_on_skipped(self, result:
|
69
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
70
70
|
self._handle_warnings_and_exception(result)
|
71
71
|
|
72
|
-
self._display.display("%s | SKIPPED" % (result.
|
72
|
+
self._display.display("%s | SKIPPED" % (result.host.get_name()), color=C.COLOR_SKIP)
|
73
73
|
|
74
|
-
def v2_runner_on_unreachable(self, result:
|
74
|
+
def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
|
75
75
|
self._handle_warnings_and_exception(result)
|
76
76
|
|
77
|
-
self._display.display("%s | UNREACHABLE! => %s" % (result.
|
77
|
+
self._display.display("%s | UNREACHABLE! => %s" % (result.host.get_name(), self._dump_results(result.result, indent=4)), color=C.COLOR_UNREACHABLE)
|
78
78
|
|
79
79
|
def v2_on_file_diff(self, result):
|
80
|
-
if 'diff' in result.
|
81
|
-
self._display.display(self._get_diff(result.
|
80
|
+
if 'diff' in result.result and result.result['diff']:
|
81
|
+
self._display.display(self._get_diff(result.result['diff']))
|
@@ -16,6 +16,7 @@ DOCUMENTATION = """
|
|
16
16
|
from ansible import constants as C
|
17
17
|
from ansible.plugins.callback import CallbackBase
|
18
18
|
from ansible.template import Templar
|
19
|
+
from ansible.executor.task_result import CallbackTaskResult
|
19
20
|
|
20
21
|
|
21
22
|
class CallbackModule(CallbackBase):
|
@@ -41,9 +42,9 @@ class CallbackModule(CallbackBase):
|
|
41
42
|
else:
|
42
43
|
return "%s | %s | rc=%s | (stdout) %s" % (hostname, caption, result.get('rc', -1), stdout)
|
43
44
|
|
44
|
-
def v2_runner_on_failed(self, result, ignore_errors=False):
|
45
|
-
if 'exception' in result.
|
46
|
-
error_text = Templar().template(result.
|
45
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
46
|
+
if 'exception' in result.result:
|
47
|
+
error_text = Templar().template(result.result['exception']) # transform to a string
|
47
48
|
if self._display.verbosity < 3:
|
48
49
|
# extract just the actual error message from the exception text
|
49
50
|
error = error_text.strip().split('\n')[-1]
|
@@ -51,31 +52,31 @@ class CallbackModule(CallbackBase):
|
|
51
52
|
else:
|
52
53
|
msg = "An exception occurred during task execution. The full traceback is:\n" + error_text.replace('\n', '')
|
53
54
|
|
54
|
-
if result.
|
55
|
-
self._display.display(self._command_generic_msg(result.
|
55
|
+
if result.task.action in C.MODULE_NO_JSON and 'module_stderr' not in result.result:
|
56
|
+
self._display.display(self._command_generic_msg(result.host.get_name(), result.result, 'FAILED'), color=C.COLOR_ERROR)
|
56
57
|
else:
|
57
58
|
self._display.display(msg, color=C.COLOR_ERROR)
|
58
59
|
|
59
|
-
self._display.display("%s | FAILED! => %s" % (result.
|
60
|
+
self._display.display("%s | FAILED! => %s" % (result.host.get_name(), self._dump_results(result.result, indent=0).replace('\n', '')),
|
60
61
|
color=C.COLOR_ERROR)
|
61
62
|
|
62
|
-
def v2_runner_on_ok(self, result):
|
63
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
63
64
|
|
64
|
-
if result.
|
65
|
+
if result.result.get('changed', False):
|
65
66
|
color = C.COLOR_CHANGED
|
66
67
|
state = 'CHANGED'
|
67
68
|
else:
|
68
69
|
color = C.COLOR_OK
|
69
70
|
state = 'SUCCESS'
|
70
71
|
|
71
|
-
if result.
|
72
|
-
self._display.display(self._command_generic_msg(result.
|
72
|
+
if result.task.action in C.MODULE_NO_JSON and 'ansible_job_id' not in result.result:
|
73
|
+
self._display.display(self._command_generic_msg(result.host.get_name(), result.result, state), color=color)
|
73
74
|
else:
|
74
|
-
self._display.display("%s | %s => %s" % (result.
|
75
|
+
self._display.display("%s | %s => %s" % (result.host.get_name(), state, self._dump_results(result.result, indent=0).replace('\n', '')),
|
75
76
|
color=color)
|
76
77
|
|
77
|
-
def v2_runner_on_unreachable(self, result):
|
78
|
-
self._display.display("%s | UNREACHABLE!: %s" % (result.
|
78
|
+
def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
|
79
|
+
self._display.display("%s | UNREACHABLE!: %s" % (result.host.get_name(), result.result.get('msg', '')), color=C.COLOR_UNREACHABLE)
|
79
80
|
|
80
|
-
def v2_runner_on_skipped(self, result):
|
81
|
-
self._display.display("%s | SKIPPED" % (result.
|
81
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
82
|
+
self._display.display("%s | SKIPPED" % (result.host.get_name()), color=C.COLOR_SKIP)
|
ansible/plugins/callback/tree.py
CHANGED
@@ -30,6 +30,7 @@ DOCUMENTATION = """
|
|
30
30
|
import os
|
31
31
|
|
32
32
|
from ansible.constants import TREE_DIR
|
33
|
+
from ansible.executor.task_result import CallbackTaskResult
|
33
34
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
34
35
|
from ansible.plugins.callback import CallbackBase
|
35
36
|
from ansible.utils.path import makedirs_safe, unfrackpath
|
@@ -76,14 +77,14 @@ class CallbackModule(CallbackBase):
|
|
76
77
|
except (OSError, IOError) as e:
|
77
78
|
self._display.warning(u"Unable to write to %s's file: %s" % (hostname, to_text(e)))
|
78
79
|
|
79
|
-
def result_to_tree(self, result):
|
80
|
-
self.write_tree_file(result.
|
80
|
+
def result_to_tree(self, result: CallbackTaskResult) -> None:
|
81
|
+
self.write_tree_file(result.host.get_name(), self._dump_results(result.result))
|
81
82
|
|
82
|
-
def v2_runner_on_ok(self, result):
|
83
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
83
84
|
self.result_to_tree(result)
|
84
85
|
|
85
|
-
def v2_runner_on_failed(self, result, ignore_errors=False):
|
86
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
86
87
|
self.result_to_tree(result)
|
87
88
|
|
88
|
-
def v2_runner_on_unreachable(self, result):
|
89
|
+
def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
|
89
90
|
self.result_to_tree(result)
|
ansible/plugins/filter/core.py
CHANGED
@@ -26,7 +26,7 @@ from jinja2.filters import do_map, do_select, do_selectattr, do_reject, do_rejec
|
|
26
26
|
from jinja2.environment import Environment
|
27
27
|
|
28
28
|
from ansible._internal._templating import _lazy_containers
|
29
|
-
from ansible.errors import AnsibleFilterError, AnsibleTypeError
|
29
|
+
from ansible.errors import AnsibleFilterError, AnsibleTypeError, AnsibleTemplatePluginError
|
30
30
|
from ansible.module_utils.datatag import native_type_name
|
31
31
|
from ansible.module_utils.common.json import get_encoder, get_decoder
|
32
32
|
from ansible.module_utils.six import string_types, integer_types, text_type
|
@@ -405,6 +405,13 @@ def comment(text, style='plain', **kw):
|
|
405
405
|
}
|
406
406
|
}
|
407
407
|
|
408
|
+
if style not in comment_styles:
|
409
|
+
raise AnsibleTemplatePluginError(
|
410
|
+
message=f"Invalid style {style!r}.",
|
411
|
+
help_text=f"Available styles: {', '.join(comment_styles)}",
|
412
|
+
obj=style,
|
413
|
+
)
|
414
|
+
|
408
415
|
# Pointer to the right comment type
|
409
416
|
style_params = comment_styles[style]
|
410
417
|
|