ansible-core 2.19.0b1__py3-none-any.whl → 2.19.0b3__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/_ansiballz.py +1 -4
- 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/_datatag.py +3 -4
- ansible/_internal/_templating/_engine.py +6 -1
- ansible/_internal/_templating/_jinja_bits.py +4 -4
- ansible/_internal/_templating/_jinja_plugins.py +7 -17
- ansible/cli/__init__.py +12 -5
- ansible/cli/arguments/option_helpers.py +4 -1
- ansible/cli/doc.py +14 -8
- ansible/config/base.yml +17 -20
- ansible/config/manager.py +2 -2
- ansible/constants.py +0 -62
- ansible/errors/__init__.py +6 -2
- ansible/executor/module_common.py +11 -7
- ansible/executor/process/worker.py +31 -26
- ansible/executor/task_executor.py +38 -31
- ansible/executor/task_queue_manager.py +62 -52
- ansible/executor/task_result.py +168 -72
- ansible/galaxy/api.py +1 -1
- ansible/galaxy/collection/__init__.py +3 -3
- ansible/inventory/manager.py +2 -1
- ansible/module_utils/_internal/_ansiballz.py +4 -30
- ansible/module_utils/_internal/_datatag/_tags.py +3 -25
- ansible/module_utils/_internal/_deprecator.py +134 -0
- ansible/module_utils/_internal/_plugin_info.py +25 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +1 -1
- ansible/module_utils/basic.py +68 -23
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/messages.py +40 -23
- ansible/module_utils/common/process.py +0 -1
- ansible/module_utils/common/respawn.py +0 -7
- ansible/module_utils/common/warnings.py +13 -13
- ansible/module_utils/datatag.py +13 -13
- ansible/modules/async_status.py +1 -1
- ansible/modules/dnf5.py +1 -1
- ansible/modules/get_url.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/playbook/task.py +0 -2
- ansible/plugins/__init__.py +18 -8
- ansible/plugins/action/__init__.py +6 -14
- ansible/plugins/action/gather_facts.py +2 -4
- 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 +23 -16
- ansible/plugins/callback/tree.py +13 -6
- ansible/plugins/connection/local.py +1 -1
- ansible/plugins/connection/paramiko_ssh.py +9 -2
- ansible/plugins/doc_fragments/action_core.py +1 -1
- ansible/plugins/filter/core.py +12 -2
- ansible/plugins/inventory/__init__.py +2 -2
- ansible/plugins/loader.py +194 -130
- ansible/plugins/lookup/url.py +2 -2
- ansible/plugins/strategy/__init__.py +76 -82
- 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 +8 -6
- ansible/utils/collection_loader/_collection_meta.py +5 -3
- ansible/utils/display.py +141 -79
- ansible/utils/py3compat.py +1 -7
- ansible/utils/ssh_functions.py +4 -1
- ansible/utils/vars.py +23 -0
- ansible/vars/clean.py +1 -1
- ansible/vars/manager.py +18 -27
- ansible/vars/plugins.py +4 -4
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/METADATA +1 -1
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/RECORD +89 -85
- ansible_test/_internal/commands/sanity/pylint.py +1 -0
- ansible_test/_internal/docker_util.py +4 -3
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +475 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +0 -64
- ansible/module_utils/_internal/_plugin_exec_context.py +0 -49
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -399
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/BSD-3-Clause.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/COPYING +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/WHEEL +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.19.0b1.dist-info → ansible_core-2.19.0b3.dist-info}/top_level.txt +0 -0
@@ -24,15 +24,14 @@ import re
|
|
24
24
|
import sys
|
25
25
|
import textwrap
|
26
26
|
import typing as t
|
27
|
+
import collections.abc as _c
|
27
28
|
|
28
29
|
from typing import TYPE_CHECKING
|
29
30
|
|
30
|
-
from collections.abc import MutableMapping
|
31
31
|
from copy import deepcopy
|
32
32
|
|
33
33
|
from ansible import constants as C
|
34
34
|
from ansible.module_utils._internal import _datatag
|
35
|
-
from ansible.module_utils.common.messages import ErrorSummary
|
36
35
|
from ansible._internal._yaml import _dumper
|
37
36
|
from ansible.plugins import AnsiblePlugin
|
38
37
|
from ansible.utils.color import stringc
|
@@ -44,7 +43,7 @@ from ansible._internal._templating import _engine
|
|
44
43
|
import yaml
|
45
44
|
|
46
45
|
if TYPE_CHECKING:
|
47
|
-
from ansible.executor.task_result import
|
46
|
+
from ansible.executor.task_result import CallbackTaskResult
|
48
47
|
|
49
48
|
global_display = Display()
|
50
49
|
|
@@ -59,6 +58,19 @@ _YAML_BREAK_CHARS = '\n\x85\u2028\u2029' # NL, NEL, LS, PS
|
|
59
58
|
_SPACE_BREAK_RE = re.compile(fr' +([{_YAML_BREAK_CHARS}])')
|
60
59
|
|
61
60
|
|
61
|
+
_T_callable = t.TypeVar("_T_callable", bound=t.Callable)
|
62
|
+
|
63
|
+
|
64
|
+
def _callback_base_impl(wrapped: _T_callable) -> _T_callable:
|
65
|
+
"""
|
66
|
+
Decorator for the no-op methods on the `CallbackBase` base class.
|
67
|
+
Used to avoid unnecessary dispatch overhead to no-op base callback methods.
|
68
|
+
"""
|
69
|
+
wrapped._base_impl = True
|
70
|
+
|
71
|
+
return wrapped
|
72
|
+
|
73
|
+
|
62
74
|
class _AnsibleCallbackDumper(_dumper.AnsibleDumper):
|
63
75
|
def __init__(self, *args, lossy: bool = False, **kwargs):
|
64
76
|
super().__init__(*args, **kwargs)
|
@@ -87,6 +99,8 @@ class _AnsibleCallbackDumper(_dumper.AnsibleDumper):
|
|
87
99
|
def _register_representers(cls) -> None:
|
88
100
|
super()._register_representers()
|
89
101
|
|
102
|
+
# exact type checks occur first against representers, then subclasses against multi-representers
|
103
|
+
cls.add_representer(str, cls._pretty_represent_str)
|
90
104
|
cls.add_multi_representer(str, cls._pretty_represent_str)
|
91
105
|
|
92
106
|
|
@@ -140,12 +154,17 @@ class CallbackBase(AnsiblePlugin):
|
|
140
154
|
custom actions.
|
141
155
|
"""
|
142
156
|
|
143
|
-
def __init__(self, display=None, options=None):
|
157
|
+
def __init__(self, display: Display | None = None, options: dict[str, t.Any] | None = None) -> None:
|
158
|
+
super().__init__()
|
159
|
+
|
144
160
|
if display:
|
145
161
|
self._display = display
|
146
162
|
else:
|
147
163
|
self._display = global_display
|
148
164
|
|
165
|
+
# FUTURE: fix double-loading of non-collection stdout callback plugins that don't set CALLBACK_NEEDS_ENABLED
|
166
|
+
|
167
|
+
# FUTURE: this code is jacked for 2.x- it should just use the type names and always assume 2.0+ for normal cases
|
149
168
|
if self._display.verbosity >= 4:
|
150
169
|
name = getattr(self, 'CALLBACK_NAME', 'unnamed')
|
151
170
|
ctype = getattr(self, 'CALLBACK_TYPE', 'old')
|
@@ -155,7 +174,8 @@ class CallbackBase(AnsiblePlugin):
|
|
155
174
|
self.disabled = False
|
156
175
|
self.wants_implicit_tasks = False
|
157
176
|
|
158
|
-
self._plugin_options = {}
|
177
|
+
self._plugin_options: dict[str, t.Any] = {}
|
178
|
+
|
159
179
|
if options is not None:
|
160
180
|
self.set_options(options)
|
161
181
|
|
@@ -164,6 +184,8 @@ class CallbackBase(AnsiblePlugin):
|
|
164
184
|
'ansible_loop_var', 'ansible_index_var', 'ansible_loop',
|
165
185
|
)
|
166
186
|
|
187
|
+
self._current_task_result: CallbackTaskResult | None = None
|
188
|
+
|
167
189
|
# helper for callbacks, so they don't all have to include deepcopy
|
168
190
|
_copy_result = deepcopy
|
169
191
|
|
@@ -185,25 +207,30 @@ class CallbackBase(AnsiblePlugin):
|
|
185
207
|
self._plugin_options = C.config.get_plugin_options(self.plugin_type, self._load_name, keys=task_keys, variables=var_options, direct=direct)
|
186
208
|
|
187
209
|
@staticmethod
|
188
|
-
def host_label(result):
|
189
|
-
"""Return label for the hostname (& delegated hostname) of a task
|
190
|
-
result.
|
191
|
-
|
192
|
-
label = "%s" % result._host.get_name()
|
193
|
-
if result._task.delegate_to and result._task.delegate_to != result._host.get_name():
|
210
|
+
def host_label(result: CallbackTaskResult) -> str:
|
211
|
+
"""Return label for the hostname (& delegated hostname) of a task result."""
|
212
|
+
label = result.host.get_name()
|
213
|
+
if result.task.delegate_to and result.task.delegate_to != result.host.get_name():
|
194
214
|
# show delegated host
|
195
|
-
label += " -> %s" % result.
|
215
|
+
label += " -> %s" % result.task.delegate_to
|
196
216
|
# in case we have 'extra resolution'
|
197
|
-
ahost = result.
|
198
|
-
if result.
|
217
|
+
ahost = result.result.get('_ansible_delegated_vars', {}).get('ansible_host', result.task.delegate_to)
|
218
|
+
if result.task.delegate_to != ahost:
|
199
219
|
label += "(%s)" % ahost
|
200
220
|
return label
|
201
221
|
|
202
|
-
def _run_is_verbose(self, result, verbosity=0):
|
203
|
-
return ((self._display.verbosity > verbosity or result.
|
204
|
-
and result.
|
205
|
-
|
206
|
-
def _dump_results(
|
222
|
+
def _run_is_verbose(self, result: CallbackTaskResult, verbosity: int = 0) -> bool:
|
223
|
+
return ((self._display.verbosity > verbosity or result.result.get('_ansible_verbose_always', False) is True)
|
224
|
+
and result.result.get('_ansible_verbose_override', False) is False)
|
225
|
+
|
226
|
+
def _dump_results(
|
227
|
+
self,
|
228
|
+
result: _c.Mapping[str, t.Any],
|
229
|
+
indent: int | None = None,
|
230
|
+
sort_keys: bool = True,
|
231
|
+
keep_invocation: bool = False,
|
232
|
+
serialize: bool = True,
|
233
|
+
) -> str:
|
207
234
|
try:
|
208
235
|
result_format = self.get_option('result_format')
|
209
236
|
except KeyError:
|
@@ -253,10 +280,12 @@ class CallbackBase(AnsiblePlugin):
|
|
253
280
|
# that want to further modify the result, or use custom serialization
|
254
281
|
return abridged_result
|
255
282
|
|
283
|
+
# DTFIX-RELEASE: Switch to stock json/yaml serializers here? We should always have a transformed plain-types result.
|
284
|
+
|
256
285
|
if result_format == 'json':
|
257
286
|
return json.dumps(abridged_result, cls=_fallback_to_str.Encoder, indent=indent, ensure_ascii=False, sort_keys=sort_keys)
|
258
287
|
|
259
|
-
|
288
|
+
if result_format == 'yaml':
|
260
289
|
# None is a sentinel in this case that indicates default behavior
|
261
290
|
# default behavior for yaml is to prettify results
|
262
291
|
lossy = pretty_results in (None, True)
|
@@ -281,22 +310,28 @@ class CallbackBase(AnsiblePlugin):
|
|
281
310
|
' ' * (indent or 4)
|
282
311
|
)
|
283
312
|
|
284
|
-
|
285
|
-
|
286
|
-
for warning in res.pop('warnings', []):
|
287
|
-
# DTFIX-RELEASE: what to do about propagating wrap_text from the original display.warning call?
|
288
|
-
self._display._warning(warning, wrap_text=False)
|
289
|
-
|
290
|
-
for warning in res.pop('deprecations', []):
|
291
|
-
self._display._deprecated(warning)
|
313
|
+
# DTFIX-RELEASE: add test to exercise this case
|
314
|
+
raise ValueError(f'Unsupported result_format {result_format!r}.')
|
292
315
|
|
293
|
-
def
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
316
|
+
def _handle_warnings(self, res: _c.MutableMapping[str, t.Any]) -> None:
|
317
|
+
"""Display warnings and deprecation warnings sourced by task execution."""
|
318
|
+
if res.pop('warnings', None) and self._current_task_result and (warnings := self._current_task_result.warnings):
|
319
|
+
# display warnings from the current task result if `warnings` was not removed from `result` (or made falsey)
|
320
|
+
for warning in warnings:
|
321
|
+
# DTFIX-RELEASE: what to do about propagating wrap_text from the original display.warning call?
|
322
|
+
self._display._warning(warning, wrap_text=False)
|
323
|
+
|
324
|
+
if res.pop('deprecations', None) and self._current_task_result and (deprecations := self._current_task_result.deprecations):
|
325
|
+
# display deprecations from the current task result if `deprecations` was not removed from `result` (or made falsey)
|
326
|
+
for deprecation in deprecations:
|
327
|
+
self._display._deprecated(deprecation)
|
328
|
+
|
329
|
+
def _handle_exception(self, result: _c.MutableMapping[str, t.Any], use_stderr: bool = False) -> None:
|
330
|
+
if result.pop('exception', None) and self._current_task_result and (exception := self._current_task_result.exception):
|
331
|
+
# display exception from the current task result if `exception` was not removed from `result` (or made falsey)
|
332
|
+
self._display._error(exception, wrap_text=False, stderr=use_stderr)
|
333
|
+
|
334
|
+
def _handle_warnings_and_exception(self, result: CallbackTaskResult) -> None:
|
300
335
|
"""Standardized handling of warnings/deprecations and exceptions from a task/item result."""
|
301
336
|
# DTFIX-RELEASE: make/doc/porting-guide a public version of this method?
|
302
337
|
try:
|
@@ -304,8 +339,8 @@ class CallbackBase(AnsiblePlugin):
|
|
304
339
|
except KeyError:
|
305
340
|
use_stderr = False
|
306
341
|
|
307
|
-
self._handle_warnings(result.
|
308
|
-
self._handle_exception(result.
|
342
|
+
self._handle_warnings(result.result)
|
343
|
+
self._handle_exception(result.result, use_stderr=use_stderr)
|
309
344
|
|
310
345
|
def _serialize_diff(self, diff):
|
311
346
|
try:
|
@@ -322,7 +357,8 @@ class CallbackBase(AnsiblePlugin):
|
|
322
357
|
|
323
358
|
if result_format == 'json':
|
324
359
|
return json.dumps(diff, sort_keys=True, indent=4, separators=(u',', u': ')) + u'\n'
|
325
|
-
|
360
|
+
|
361
|
+
if result_format == 'yaml':
|
326
362
|
# None is a sentinel in this case that indicates default behavior
|
327
363
|
# default behavior for yaml is to prettify results
|
328
364
|
lossy = pretty_results in (None, True)
|
@@ -338,6 +374,9 @@ class CallbackBase(AnsiblePlugin):
|
|
338
374
|
' '
|
339
375
|
)
|
340
376
|
|
377
|
+
# DTFIX-RELEASE: add test to exercise this case
|
378
|
+
raise ValueError(f'Unsupported result_format {result_format!r}.')
|
379
|
+
|
341
380
|
def _get_diff(self, difflist):
|
342
381
|
|
343
382
|
if not isinstance(difflist, list):
|
@@ -356,7 +395,7 @@ class CallbackBase(AnsiblePlugin):
|
|
356
395
|
if 'before' in diff and 'after' in diff:
|
357
396
|
# format complex structures into 'files'
|
358
397
|
for x in ['before', 'after']:
|
359
|
-
if isinstance(diff[x],
|
398
|
+
if isinstance(diff[x], _c.Mapping):
|
360
399
|
diff[x] = self._serialize_diff(diff[x])
|
361
400
|
elif diff[x] is None:
|
362
401
|
diff[x] = ''
|
@@ -398,7 +437,7 @@ class CallbackBase(AnsiblePlugin):
|
|
398
437
|
ret.append(diff['prepared'])
|
399
438
|
return u''.join(ret)
|
400
439
|
|
401
|
-
def _get_item_label(self, result):
|
440
|
+
def _get_item_label(self, result: _c.Mapping[str, t.Any]) -> t.Any:
|
402
441
|
""" retrieves the value to be displayed as a label for an item entry from a result object"""
|
403
442
|
if result.get('_ansible_no_log', False):
|
404
443
|
item = "(censored due to no_log)"
|
@@ -406,9 +445,9 @@ class CallbackBase(AnsiblePlugin):
|
|
406
445
|
item = result.get('_ansible_item_label', result.get('item'))
|
407
446
|
return item
|
408
447
|
|
409
|
-
def _process_items(self, result):
|
448
|
+
def _process_items(self, result: CallbackTaskResult) -> None:
|
410
449
|
# just remove them as now they get handled by individual callbacks
|
411
|
-
del result.
|
450
|
+
del result.result['results']
|
412
451
|
|
413
452
|
def _clean_results(self, result, task_name):
|
414
453
|
""" removes data from results for display """
|
@@ -434,74 +473,97 @@ class CallbackBase(AnsiblePlugin):
|
|
434
473
|
def set_play_context(self, play_context):
|
435
474
|
pass
|
436
475
|
|
476
|
+
@_callback_base_impl
|
437
477
|
def on_any(self, *args, **kwargs):
|
438
478
|
pass
|
439
479
|
|
480
|
+
@_callback_base_impl
|
440
481
|
def runner_on_failed(self, host, res, ignore_errors=False):
|
441
482
|
pass
|
442
483
|
|
484
|
+
@_callback_base_impl
|
443
485
|
def runner_on_ok(self, host, res):
|
444
486
|
pass
|
445
487
|
|
488
|
+
@_callback_base_impl
|
446
489
|
def runner_on_skipped(self, host, item=None):
|
447
490
|
pass
|
448
491
|
|
492
|
+
@_callback_base_impl
|
449
493
|
def runner_on_unreachable(self, host, res):
|
450
494
|
pass
|
451
495
|
|
496
|
+
@_callback_base_impl
|
452
497
|
def runner_on_no_hosts(self):
|
453
498
|
pass
|
454
499
|
|
500
|
+
@_callback_base_impl
|
455
501
|
def runner_on_async_poll(self, host, res, jid, clock):
|
456
502
|
pass
|
457
503
|
|
504
|
+
@_callback_base_impl
|
458
505
|
def runner_on_async_ok(self, host, res, jid):
|
459
506
|
pass
|
460
507
|
|
508
|
+
@_callback_base_impl
|
461
509
|
def runner_on_async_failed(self, host, res, jid):
|
462
510
|
pass
|
463
511
|
|
512
|
+
@_callback_base_impl
|
464
513
|
def playbook_on_start(self):
|
465
514
|
pass
|
466
515
|
|
516
|
+
@_callback_base_impl
|
467
517
|
def playbook_on_notify(self, host, handler):
|
468
518
|
pass
|
469
519
|
|
520
|
+
@_callback_base_impl
|
470
521
|
def playbook_on_no_hosts_matched(self):
|
471
522
|
pass
|
472
523
|
|
524
|
+
@_callback_base_impl
|
473
525
|
def playbook_on_no_hosts_remaining(self):
|
474
526
|
pass
|
475
527
|
|
528
|
+
@_callback_base_impl
|
476
529
|
def playbook_on_task_start(self, name, is_conditional):
|
477
530
|
pass
|
478
531
|
|
532
|
+
@_callback_base_impl
|
479
533
|
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
|
480
534
|
pass
|
481
535
|
|
536
|
+
@_callback_base_impl
|
482
537
|
def playbook_on_setup(self):
|
483
538
|
pass
|
484
539
|
|
540
|
+
@_callback_base_impl
|
485
541
|
def playbook_on_import_for_host(self, host, imported_file):
|
486
542
|
pass
|
487
543
|
|
544
|
+
@_callback_base_impl
|
488
545
|
def playbook_on_not_import_for_host(self, host, missing_file):
|
489
546
|
pass
|
490
547
|
|
548
|
+
@_callback_base_impl
|
491
549
|
def playbook_on_play_start(self, name):
|
492
550
|
pass
|
493
551
|
|
552
|
+
@_callback_base_impl
|
494
553
|
def playbook_on_stats(self, stats):
|
495
554
|
pass
|
496
555
|
|
556
|
+
@_callback_base_impl
|
497
557
|
def on_file_diff(self, host, diff):
|
498
558
|
pass
|
499
559
|
|
500
560
|
# V2 METHODS, by default they call v1 counterparts if possible
|
561
|
+
@_callback_base_impl
|
501
562
|
def v2_on_any(self, *args, **kwargs):
|
502
563
|
self.on_any(args, kwargs)
|
503
564
|
|
504
|
-
|
565
|
+
@_callback_base_impl
|
566
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
505
567
|
"""Process results of a failed task.
|
506
568
|
|
507
569
|
Note: The value of 'ignore_errors' tells Ansible whether to
|
@@ -512,7 +574,7 @@ class CallbackBase(AnsiblePlugin):
|
|
512
574
|
issues (for example, missing packages), or syntax errors.
|
513
575
|
|
514
576
|
:param result: The parameters of the task and its results.
|
515
|
-
:type result:
|
577
|
+
:type result: CallbackTaskResult
|
516
578
|
:param ignore_errors: Whether Ansible should continue \
|
517
579
|
running tasks on the host where the task failed.
|
518
580
|
:type ignore_errors: bool
|
@@ -520,147 +582,172 @@ class CallbackBase(AnsiblePlugin):
|
|
520
582
|
:return: None
|
521
583
|
:rtype: None
|
522
584
|
"""
|
523
|
-
host = result.
|
524
|
-
self.runner_on_failed(host, result.
|
585
|
+
host = result.host.get_name()
|
586
|
+
self.runner_on_failed(host, result.result, ignore_errors)
|
525
587
|
|
526
|
-
|
588
|
+
@_callback_base_impl
|
589
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
527
590
|
"""Process results of a successful task.
|
528
591
|
|
529
592
|
:param result: The parameters of the task and its results.
|
530
|
-
:type result:
|
593
|
+
:type result: CallbackTaskResult
|
531
594
|
|
532
595
|
:return: None
|
533
596
|
:rtype: None
|
534
597
|
"""
|
535
|
-
host = result.
|
536
|
-
self.runner_on_ok(host, result.
|
598
|
+
host = result.host.get_name()
|
599
|
+
self.runner_on_ok(host, result.result)
|
537
600
|
|
538
|
-
|
601
|
+
@_callback_base_impl
|
602
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
539
603
|
"""Process results of a skipped task.
|
540
604
|
|
541
605
|
:param result: The parameters of the task and its results.
|
542
|
-
:type result:
|
606
|
+
:type result: CallbackTaskResult
|
543
607
|
|
544
608
|
:return: None
|
545
609
|
:rtype: None
|
546
610
|
"""
|
547
611
|
if C.DISPLAY_SKIPPED_HOSTS:
|
548
|
-
host = result.
|
549
|
-
self.runner_on_skipped(host, self._get_item_label(getattr(result.
|
612
|
+
host = result.host.get_name()
|
613
|
+
self.runner_on_skipped(host, self._get_item_label(getattr(result.result, 'results', {})))
|
550
614
|
|
551
|
-
|
615
|
+
@_callback_base_impl
|
616
|
+
def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
|
552
617
|
"""Process results of a task if a target node is unreachable.
|
553
618
|
|
554
619
|
:param result: The parameters of the task and its results.
|
555
|
-
:type result:
|
620
|
+
:type result: CallbackTaskResult
|
556
621
|
|
557
622
|
:return: None
|
558
623
|
:rtype: None
|
559
624
|
"""
|
560
|
-
host = result.
|
561
|
-
self.runner_on_unreachable(host, result.
|
625
|
+
host = result.host.get_name()
|
626
|
+
self.runner_on_unreachable(host, result.result)
|
562
627
|
|
563
|
-
|
628
|
+
@_callback_base_impl
|
629
|
+
def v2_runner_on_async_poll(self, result: CallbackTaskResult) -> None:
|
564
630
|
"""Get details about an unfinished task running in async mode.
|
565
631
|
|
566
632
|
Note: The value of the `poll` keyword in the task determines
|
567
633
|
the interval at which polling occurs and this method is run.
|
568
634
|
|
569
635
|
:param result: The parameters of the task and its status.
|
570
|
-
:type result:
|
636
|
+
:type result: CallbackTaskResult
|
571
637
|
|
572
638
|
:rtype: None
|
573
639
|
:rtype: None
|
574
640
|
"""
|
575
|
-
host = result.
|
576
|
-
jid = result.
|
641
|
+
host = result.host.get_name()
|
642
|
+
jid = result.result.get('ansible_job_id')
|
577
643
|
# FIXME, get real clock
|
578
644
|
clock = 0
|
579
|
-
self.runner_on_async_poll(host, result.
|
645
|
+
self.runner_on_async_poll(host, result.result, jid, clock)
|
580
646
|
|
581
|
-
|
647
|
+
@_callback_base_impl
|
648
|
+
def v2_runner_on_async_ok(self, result: CallbackTaskResult) -> None:
|
582
649
|
"""Process results of a successful task that ran in async mode.
|
583
650
|
|
584
651
|
:param result: The parameters of the task and its results.
|
585
|
-
:type result:
|
652
|
+
:type result: CallbackTaskResult
|
586
653
|
|
587
654
|
:return: None
|
588
655
|
:rtype: None
|
589
656
|
"""
|
590
|
-
host = result.
|
591
|
-
jid = result.
|
592
|
-
self.runner_on_async_ok(host, result.
|
657
|
+
host = result.host.get_name()
|
658
|
+
jid = result.result.get('ansible_job_id')
|
659
|
+
self.runner_on_async_ok(host, result.result, jid)
|
593
660
|
|
594
|
-
|
595
|
-
|
661
|
+
@_callback_base_impl
|
662
|
+
def v2_runner_on_async_failed(self, result: CallbackTaskResult) -> None:
|
663
|
+
host = result.host.get_name()
|
596
664
|
# Attempt to get the async job ID. If the job does not finish before the
|
597
665
|
# async timeout value, the ID may be within the unparsed 'async_result' dict.
|
598
|
-
jid = result.
|
599
|
-
if not jid and 'async_result' in result.
|
600
|
-
jid = result.
|
601
|
-
self.runner_on_async_failed(host, result.
|
666
|
+
jid = result.result.get('ansible_job_id')
|
667
|
+
if not jid and 'async_result' in result.result:
|
668
|
+
jid = result.result['async_result'].get('ansible_job_id')
|
669
|
+
self.runner_on_async_failed(host, result.result, jid)
|
602
670
|
|
671
|
+
@_callback_base_impl
|
603
672
|
def v2_playbook_on_start(self, playbook):
|
604
673
|
self.playbook_on_start()
|
605
674
|
|
675
|
+
@_callback_base_impl
|
606
676
|
def v2_playbook_on_notify(self, handler, host):
|
607
677
|
self.playbook_on_notify(host, handler)
|
608
678
|
|
679
|
+
@_callback_base_impl
|
609
680
|
def v2_playbook_on_no_hosts_matched(self):
|
610
681
|
self.playbook_on_no_hosts_matched()
|
611
682
|
|
683
|
+
@_callback_base_impl
|
612
684
|
def v2_playbook_on_no_hosts_remaining(self):
|
613
685
|
self.playbook_on_no_hosts_remaining()
|
614
686
|
|
687
|
+
@_callback_base_impl
|
615
688
|
def v2_playbook_on_task_start(self, task, is_conditional):
|
616
689
|
self.playbook_on_task_start(task.name, is_conditional)
|
617
690
|
|
618
691
|
# FIXME: not called
|
692
|
+
@_callback_base_impl
|
619
693
|
def v2_playbook_on_cleanup_task_start(self, task):
|
620
694
|
pass # no v1 correspondence
|
621
695
|
|
696
|
+
@_callback_base_impl
|
622
697
|
def v2_playbook_on_handler_task_start(self, task):
|
623
698
|
pass # no v1 correspondence
|
624
699
|
|
700
|
+
@_callback_base_impl
|
625
701
|
def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
|
626
702
|
self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default, unsafe)
|
627
703
|
|
628
704
|
# FIXME: not called
|
629
|
-
|
630
|
-
|
705
|
+
@_callback_base_impl
|
706
|
+
def v2_playbook_on_import_for_host(self, result: CallbackTaskResult, imported_file) -> None:
|
707
|
+
host = result.host.get_name()
|
631
708
|
self.playbook_on_import_for_host(host, imported_file)
|
632
709
|
|
633
710
|
# FIXME: not called
|
634
|
-
|
635
|
-
|
711
|
+
@_callback_base_impl
|
712
|
+
def v2_playbook_on_not_import_for_host(self, result: CallbackTaskResult, missing_file) -> None:
|
713
|
+
host = result.host.get_name()
|
636
714
|
self.playbook_on_not_import_for_host(host, missing_file)
|
637
715
|
|
716
|
+
@_callback_base_impl
|
638
717
|
def v2_playbook_on_play_start(self, play):
|
639
718
|
self.playbook_on_play_start(play.name)
|
640
719
|
|
720
|
+
@_callback_base_impl
|
641
721
|
def v2_playbook_on_stats(self, stats):
|
642
722
|
self.playbook_on_stats(stats)
|
643
723
|
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
724
|
+
@_callback_base_impl
|
725
|
+
def v2_on_file_diff(self, result: CallbackTaskResult) -> None:
|
726
|
+
if 'diff' in result.result:
|
727
|
+
host = result.host.get_name()
|
728
|
+
self.on_file_diff(host, result.result['diff'])
|
648
729
|
|
730
|
+
@_callback_base_impl
|
649
731
|
def v2_playbook_on_include(self, included_file):
|
650
732
|
pass # no v1 correspondence
|
651
733
|
|
652
|
-
|
734
|
+
@_callback_base_impl
|
735
|
+
def v2_runner_item_on_ok(self, result: CallbackTaskResult) -> None:
|
653
736
|
pass
|
654
737
|
|
655
|
-
|
738
|
+
@_callback_base_impl
|
739
|
+
def v2_runner_item_on_failed(self, result: CallbackTaskResult) -> None:
|
656
740
|
pass
|
657
741
|
|
658
|
-
|
742
|
+
@_callback_base_impl
|
743
|
+
def v2_runner_item_on_skipped(self, result: CallbackTaskResult) -> None:
|
659
744
|
pass
|
660
745
|
|
661
|
-
|
746
|
+
@_callback_base_impl
|
747
|
+
def v2_runner_retry(self, result: CallbackTaskResult) -> None:
|
662
748
|
pass
|
663
749
|
|
750
|
+
@_callback_base_impl
|
664
751
|
def v2_runner_on_start(self, host, task):
|
665
752
|
"""Event used when host begins execution of a task
|
666
753
|
|