ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__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.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz/__init__.py +0 -0
- ansible/_internal/_ansiballz/_builder.py +101 -0
- ansible/_internal/_ansiballz/_wrapper.py +262 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_alarm_timeout.py +66 -0
- ansible/_internal/_errors/_captured.py +123 -0
- ansible/_internal/_errors/_error_factory.py +89 -0
- ansible/_internal/_errors/_error_utils.py +240 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_task_timeout.py +28 -0
- ansible/_internal/_event_formatting.py +127 -0
- ansible/_internal/_json/__init__.py +214 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +189 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_ssh/__init__.py +0 -0
- ansible/_internal/_ssh/_agent_launch.py +91 -0
- ansible/_internal/_ssh/_ssh_agent.py +619 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +12 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +592 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1106 -0
- ansible/_internal/_templating/_jinja_common.py +323 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +375 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_template_vars.py +72 -0
- ansible/_internal/_templating/_transform.py +70 -0
- ansible/_internal/_templating/_utils.py +108 -0
- ansible/_internal/_testing.py +26 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +70 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +93 -104
- ansible/cli/_ssh_askpass.py +54 -0
- ansible/cli/adhoc.py +20 -10
- ansible/cli/arguments/option_helpers.py +163 -10
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +13 -11
- ansible/cli/doc.py +134 -77
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -28
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +6 -3
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/compat/importlib_resources.py +9 -12
- ansible/config/base.yml +218 -133
- ansible/config/manager.py +220 -159
- ansible/constants.py +2 -65
- ansible/errors/__init__.py +350 -256
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +480 -514
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +204 -153
- ansible/executor/powershell/become_wrapper.ps1 +107 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
- ansible/executor/powershell/exec_wrapper.ps1 +675 -196
- ansible/executor/powershell/module_manifest.py +469 -265
- ansible/executor/powershell/module_wrapper.ps1 +195 -186
- ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
- ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +139 -149
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +270 -297
- ansible/executor/task_queue_manager.py +135 -137
- ansible/executor/task_result.py +182 -79
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +26 -25
- ansible/galaxy/collection/__init__.py +6 -14
- ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +4 -4
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +6 -10
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +50 -73
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +37 -54
- ansible/inventory/manager.py +79 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
- ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
- ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
- ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +961 -0
- ansible/module_utils/_internal/_datatag/_tags.py +16 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_deprecator.py +157 -0
- ansible/module_utils/_internal/_errors.py +101 -0
- ansible/module_utils/_internal/_event_utils.py +61 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
- ansible/module_utils/_internal/_messages.py +130 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_info.py +38 -0
- ansible/module_utils/_internal/_stack.py +22 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_text_utils.py +6 -0
- ansible/module_utils/_internal/_traceback.py +92 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +303 -202
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/collections.py +7 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -3
- ansible/module_utils/common/respawn.py +11 -33
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +143 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +10 -13
- ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +49 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +2 -2
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +5 -5
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +2 -3
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/sysctl.py +4 -6
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +3 -3
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +27 -13
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +2 -3
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/linux.py +3 -3
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +7 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/service.py +21 -31
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +64 -35
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +69 -49
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +32 -51
- ansible/modules/assemble.py +16 -14
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +24 -24
- ansible/modules/async_wrapper.py +20 -25
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +13 -20
- ansible/modules/copy.py +60 -147
- ansible/modules/cron.py +24 -21
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +13 -15
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +184 -144
- ansible/modules/find.py +22 -20
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +77 -54
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +38 -38
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +15 -32
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +22 -24
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +10 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +21 -26
- ansible/modules/raw.py +6 -6
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +10 -14
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +10 -17
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +16 -19
- ansible/modules/stat.py +15 -31
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +7 -7
- ansible/modules/systemd_service.py +7 -7
- ansible/modules/sysvinit.py +9 -9
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +38 -17
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +45 -32
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +70 -60
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +10 -9
- ansible/parsing/ajson.py +17 -37
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +62 -60
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +327 -99
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +187 -134
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +32 -26
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +14 -17
- ansible/playbook/playbook_include.py +27 -62
- ansible/playbook/role/__init__.py +64 -49
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +28 -12
- ansible/playbook/task.py +192 -121
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +58 -26
- ansible/plugins/action/__init__.py +188 -186
- ansible/plugins/action/add_host.py +2 -2
- ansible/plugins/action/assemble.py +11 -18
- ansible/plugins/action/assert.py +55 -67
- ansible/plugins/action/async_status.py +7 -2
- ansible/plugins/action/copy.py +14 -17
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +7 -8
- ansible/plugins/action/gather_facts.py +13 -14
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +8 -14
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +27 -38
- ansible/plugins/action/service.py +9 -18
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +47 -67
- ansible/plugins/action/unarchive.py +6 -16
- ansible/plugins/action/uri.py +9 -20
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +52 -63
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +294 -201
- ansible/plugins/callback/default.py +99 -95
- ansible/plugins/callback/junit.py +44 -43
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +34 -21
- ansible/plugins/callback/tree.py +27 -16
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +156 -60
- ansible/plugins/connection/paramiko_ssh.py +34 -24
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +326 -86
- ansible/plugins/connection/winrm.py +62 -141
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +8 -4
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +245 -120
- ansible/plugins/filter/encryption.py +42 -34
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/pow.yml +1 -1
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/strftime.yml +3 -3
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +107 -86
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +190 -120
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +72 -19
- ansible/plugins/loader.py +383 -198
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +19 -73
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +87 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +47 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +4 -10
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +58 -4
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +106 -31
- ansible/plugins/shell/sh.py +13 -7
- ansible/plugins/strategy/__init__.py +168 -193
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +75 -35
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/finished.yml +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +5 -8
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +353 -943
- ansible/utils/__init__.py +0 -18
- ansible/utils/collection_loader/__init__.py +54 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +82 -96
- ansible/utils/collection_loader/_collection_meta.py +15 -8
- ansible/utils/display.py +485 -73
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/galaxy.py +2 -2
- ansible/utils/hashing.py +8 -10
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +10 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +10 -12
- ansible/utils/plugin_docs.py +16 -14
- ansible/utils/py3compat.py +2 -7
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +6 -2
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +55 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +220 -285
- ansible/vars/plugins.py +4 -4
- ansible/vars/reserved.py +13 -12
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
- ansible_core-2.19.0.dist-info/RECORD +1097 -0
- ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +6 -0
- ansible_test/_internal/ansible_util.py +3 -1
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -5
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +52 -5
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +3 -2
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +22 -5
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +8 -2
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +19 -2
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +25 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +44 -4
- ansible_test/_internal/commands/units/__init__.py +5 -1
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +23 -13
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/debugging.py +166 -0
- ansible_test/_internal/delegation.py +22 -13
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +260 -16
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +39 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +95 -4
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/processes.py +80 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +11 -4
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +28 -0
- ansible_test/_internal/ssh.py +2 -5
- ansible_test/_internal/target.py +9 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +3 -1
- ansible_test/_internal/timeout.py +2 -1
- ansible_test/_internal/util.py +41 -12
- ansible_test/_internal/util_common.py +18 -5
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/injector/python.py +8 -0
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +38 -36
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
DOCUMENTATION =
|
|
7
|
+
DOCUMENTATION = """
|
|
8
8
|
name: default
|
|
9
9
|
type: stdout
|
|
10
10
|
short_description: default Ansible screen output
|
|
@@ -16,11 +16,12 @@ DOCUMENTATION = '''
|
|
|
16
16
|
- result_format_callback
|
|
17
17
|
requirements:
|
|
18
18
|
- set as stdout in configuration
|
|
19
|
-
|
|
19
|
+
"""
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
from ansible import constants as C
|
|
23
23
|
from ansible import context
|
|
24
|
+
from ansible.executor.task_result import CallbackTaskResult
|
|
24
25
|
from ansible.playbook.task_include import TaskInclude
|
|
25
26
|
from ansible.plugins.callback import CallbackBase
|
|
26
27
|
from ansible.utils.color import colorize, hostcolor
|
|
@@ -29,10 +30,10 @@ from ansible.utils.fqcn import add_internal_fqcns
|
|
|
29
30
|
|
|
30
31
|
class CallbackModule(CallbackBase):
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
"""
|
|
33
34
|
This is the default callback interface, which simply prints messages
|
|
34
35
|
to stdout when new callback events are received.
|
|
35
|
-
|
|
36
|
+
"""
|
|
36
37
|
|
|
37
38
|
CALLBACK_VERSION = 2.0
|
|
38
39
|
CALLBACK_TYPE = 'stdout'
|
|
@@ -46,40 +47,39 @@ class CallbackModule(CallbackBase):
|
|
|
46
47
|
self._task_type_cache = {}
|
|
47
48
|
super(CallbackModule, self).__init__()
|
|
48
49
|
|
|
49
|
-
def v2_runner_on_failed(self, result, ignore_errors=False):
|
|
50
|
-
|
|
50
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
|
51
51
|
host_label = self.host_label(result)
|
|
52
|
-
self._clean_results(result._result, result._task.action)
|
|
53
52
|
|
|
54
|
-
if self._last_task_banner != result.
|
|
55
|
-
self._print_task_banner(result.
|
|
53
|
+
if self._last_task_banner != result.task._uuid:
|
|
54
|
+
self._print_task_banner(result.task)
|
|
56
55
|
|
|
57
|
-
self.
|
|
58
|
-
self._handle_warnings(result._result)
|
|
56
|
+
self._handle_warnings_and_exception(result)
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
# FIXME: this method should not exist, delegate "suggested keys to display" to the plugin or something... As-is, the placement of this
|
|
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.result, result.task.action)
|
|
62
61
|
|
|
62
|
+
if result.task.loop and 'results' in result.result:
|
|
63
|
+
self._process_items(result)
|
|
63
64
|
else:
|
|
64
65
|
if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
|
|
65
|
-
self._print_task_path(result.
|
|
66
|
-
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))
|
|
67
68
|
self._display.display(msg, color=C.COLOR_ERROR, stderr=self.get_option('display_failed_stderr'))
|
|
68
69
|
|
|
69
70
|
if ignore_errors:
|
|
70
71
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
|
71
72
|
|
|
72
|
-
def v2_runner_on_ok(self, result):
|
|
73
|
-
|
|
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,49 +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
|
-
self.
|
|
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):
|
|
108
|
-
|
|
107
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
|
109
108
|
if self.get_option('display_skipped_hosts'):
|
|
110
109
|
|
|
111
|
-
self._clean_results(result.
|
|
110
|
+
self._clean_results(result.result, result.task.action)
|
|
111
|
+
|
|
112
|
+
if self._last_task_banner != result.task._uuid:
|
|
113
|
+
self._print_task_banner(result.task)
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
self._print_task_banner(result._task)
|
|
115
|
+
self._handle_warnings_and_exception(result)
|
|
115
116
|
|
|
116
|
-
if result.
|
|
117
|
+
if result.task.loop is not None and 'results' in result.result:
|
|
117
118
|
self._process_items(result)
|
|
118
119
|
|
|
119
|
-
msg = "skipping: [%s]" % result.
|
|
120
|
+
msg = "skipping: [%s]" % result.host.get_name()
|
|
120
121
|
if self._run_is_verbose(result):
|
|
121
|
-
msg += " => %s" % self._dump_results(result.
|
|
122
|
+
msg += " => %s" % self._dump_results(result.result)
|
|
122
123
|
self._display.display(msg, color=C.COLOR_SKIP)
|
|
123
124
|
|
|
124
|
-
def v2_runner_on_unreachable(self, result):
|
|
125
|
-
if self._last_task_banner != result.
|
|
126
|
-
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
|
+
|
|
129
|
+
self._handle_warnings_and_exception(result)
|
|
127
130
|
|
|
128
131
|
host_label = self.host_label(result)
|
|
129
|
-
msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result.
|
|
132
|
+
msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result.result))
|
|
130
133
|
self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.get_option('display_failed_stderr'))
|
|
131
134
|
|
|
132
|
-
if result.
|
|
135
|
+
if result.task.ignore_unreachable:
|
|
133
136
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
|
134
137
|
|
|
135
138
|
def v2_playbook_on_no_hosts_matched(self):
|
|
@@ -171,6 +174,7 @@ class CallbackModule(CallbackBase):
|
|
|
171
174
|
# that they can secure this if they feel that their stdout is insecure
|
|
172
175
|
# (shoulder surfing, logging stdout straight to a file, etc).
|
|
173
176
|
args = ''
|
|
177
|
+
# FIXME: the no_log value is not templated at this point, so any template will be considered truthy
|
|
174
178
|
if not task.no_log and C.DISPLAY_ARGS_TO_STDOUT:
|
|
175
179
|
args = u', '.join(u'%s=%s' % a for a in task.args.items())
|
|
176
180
|
args = u' %s' % args
|
|
@@ -193,9 +197,6 @@ class CallbackModule(CallbackBase):
|
|
|
193
197
|
|
|
194
198
|
self._last_task_banner = task._uuid
|
|
195
199
|
|
|
196
|
-
def v2_playbook_on_cleanup_task_start(self, task):
|
|
197
|
-
self._task_start(task, prefix='CLEANUP TASK')
|
|
198
|
-
|
|
199
200
|
def v2_playbook_on_handler_task_start(self, task):
|
|
200
201
|
self._task_start(task, prefix='RUNNING HANDLER')
|
|
201
202
|
|
|
@@ -218,30 +219,29 @@ class CallbackModule(CallbackBase):
|
|
|
218
219
|
|
|
219
220
|
self._display.banner(msg)
|
|
220
221
|
|
|
221
|
-
def v2_on_file_diff(self, result):
|
|
222
|
-
if result.
|
|
223
|
-
for res in result.
|
|
222
|
+
def v2_on_file_diff(self, result: CallbackTaskResult) -> None:
|
|
223
|
+
if result.task.loop and 'results' in result.result:
|
|
224
|
+
for res in result.result['results']:
|
|
224
225
|
if 'diff' in res and res['diff'] and res.get('changed', False):
|
|
225
226
|
diff = self._get_diff(res['diff'])
|
|
226
227
|
if diff:
|
|
227
|
-
if self._last_task_banner != result.
|
|
228
|
-
self._print_task_banner(result.
|
|
228
|
+
if self._last_task_banner != result.task._uuid:
|
|
229
|
+
self._print_task_banner(result.task)
|
|
229
230
|
self._display.display(diff)
|
|
230
|
-
elif 'diff' in result.
|
|
231
|
-
diff = self._get_diff(result.
|
|
231
|
+
elif 'diff' in result.result and result.result['diff'] and result.result.get('changed', False):
|
|
232
|
+
diff = self._get_diff(result.result['diff'])
|
|
232
233
|
if diff:
|
|
233
|
-
if self._last_task_banner != result.
|
|
234
|
-
self._print_task_banner(result.
|
|
234
|
+
if self._last_task_banner != result.task._uuid:
|
|
235
|
+
self._print_task_banner(result.task)
|
|
235
236
|
self._display.display(diff)
|
|
236
237
|
|
|
237
|
-
def v2_runner_item_on_ok(self, result):
|
|
238
|
-
|
|
238
|
+
def v2_runner_item_on_ok(self, result: CallbackTaskResult) -> None:
|
|
239
239
|
host_label = self.host_label(result)
|
|
240
|
-
if isinstance(result.
|
|
240
|
+
if isinstance(result.task, TaskInclude):
|
|
241
241
|
return
|
|
242
|
-
elif result.
|
|
243
|
-
if self._last_task_banner != result.
|
|
244
|
-
self._print_task_banner(result.
|
|
242
|
+
elif result.result.get('changed', False):
|
|
243
|
+
if self._last_task_banner != result.task._uuid:
|
|
244
|
+
self._print_task_banner(result.task)
|
|
245
245
|
|
|
246
246
|
msg = 'changed'
|
|
247
247
|
color = C.COLOR_CHANGED
|
|
@@ -249,43 +249,47 @@ class CallbackModule(CallbackBase):
|
|
|
249
249
|
if not self.get_option('display_ok_hosts'):
|
|
250
250
|
return
|
|
251
251
|
|
|
252
|
-
if self._last_task_banner != result.
|
|
253
|
-
self._print_task_banner(result.
|
|
252
|
+
if self._last_task_banner != result.task._uuid:
|
|
253
|
+
self._print_task_banner(result.task)
|
|
254
254
|
|
|
255
255
|
msg = 'ok'
|
|
256
256
|
color = C.COLOR_OK
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
self._handle_warnings_and_exception(result)
|
|
259
|
+
|
|
260
|
+
msg = "%s: [%s] => (item=%s)" % (msg, host_label, self._get_item_label(result.result))
|
|
261
|
+
self._clean_results(result.result, result.task.action)
|
|
260
262
|
if self._run_is_verbose(result):
|
|
261
|
-
msg += " => %s" % self._dump_results(result.
|
|
263
|
+
msg += " => %s" % self._dump_results(result.result)
|
|
262
264
|
self._display.display(msg, color=color)
|
|
263
265
|
|
|
264
|
-
def v2_runner_item_on_failed(self, result):
|
|
265
|
-
if self._last_task_banner != result.
|
|
266
|
-
self._print_task_banner(result.
|
|
266
|
+
def v2_runner_item_on_failed(self, result: CallbackTaskResult) -> None:
|
|
267
|
+
if self._last_task_banner != result.task._uuid:
|
|
268
|
+
self._print_task_banner(result.task)
|
|
269
|
+
|
|
270
|
+
self._handle_warnings_and_exception(result)
|
|
267
271
|
|
|
268
272
|
host_label = self.host_label(result)
|
|
269
|
-
self._clean_results(result._result, result._task.action)
|
|
270
|
-
self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr'))
|
|
271
273
|
|
|
272
274
|
msg = "failed: [%s]" % (host_label,)
|
|
273
|
-
self.
|
|
275
|
+
self._clean_results(result.result, result.task.action)
|
|
274
276
|
self._display.display(
|
|
275
|
-
msg + " (item=%s) => %s" % (self._get_item_label(result.
|
|
277
|
+
msg + " (item=%s) => %s" % (self._get_item_label(result.result), self._dump_results(result.result)),
|
|
276
278
|
color=C.COLOR_ERROR,
|
|
277
279
|
stderr=self.get_option('display_failed_stderr')
|
|
278
280
|
)
|
|
279
281
|
|
|
280
|
-
def v2_runner_item_on_skipped(self, result):
|
|
282
|
+
def v2_runner_item_on_skipped(self, result: CallbackTaskResult) -> None:
|
|
281
283
|
if self.get_option('display_skipped_hosts'):
|
|
282
|
-
if self._last_task_banner != result.
|
|
283
|
-
self._print_task_banner(result.
|
|
284
|
+
if self._last_task_banner != result.task._uuid:
|
|
285
|
+
self._print_task_banner(result.task)
|
|
286
|
+
|
|
287
|
+
self._handle_warnings_and_exception(result)
|
|
284
288
|
|
|
285
|
-
self._clean_results(result.
|
|
286
|
-
msg = "skipping: [%s] => (item=%s) " % (result.
|
|
289
|
+
self._clean_results(result.result, result.task.action)
|
|
290
|
+
msg = "skipping: [%s] => (item=%s) " % (result.host.get_name(), self._get_item_label(result.result))
|
|
287
291
|
if self._run_is_verbose(result):
|
|
288
|
-
msg += " => %s" % self._dump_results(result.
|
|
292
|
+
msg += " => %s" % self._dump_results(result.result)
|
|
289
293
|
self._display.display(msg, color=C.COLOR_SKIP)
|
|
290
294
|
|
|
291
295
|
def v2_playbook_on_include(self, included_file):
|
|
@@ -370,37 +374,37 @@ class CallbackModule(CallbackBase):
|
|
|
370
374
|
if context.CLIARGS['check'] and self.get_option('check_mode_markers'):
|
|
371
375
|
self._display.banner("DRY RUN")
|
|
372
376
|
|
|
373
|
-
def v2_runner_retry(self, result):
|
|
374
|
-
task_name = result.task_name or result.
|
|
377
|
+
def v2_runner_retry(self, result: CallbackTaskResult) -> None:
|
|
378
|
+
task_name = result.task_name or result.task
|
|
375
379
|
host_label = self.host_label(result)
|
|
376
|
-
msg = "FAILED - RETRYING: [%s]: %s (%d retries left)." % (host_label, task_name, result.
|
|
380
|
+
msg = "FAILED - RETRYING: [%s]: %s (%d retries left)." % (host_label, task_name, result.result['retries'] - result.result['attempts'])
|
|
377
381
|
if self._run_is_verbose(result, verbosity=2):
|
|
378
|
-
msg += "Result was: %s" % self._dump_results(result.
|
|
382
|
+
msg += "Result was: %s" % self._dump_results(result.result)
|
|
379
383
|
self._display.display(msg, color=C.COLOR_DEBUG)
|
|
380
384
|
|
|
381
|
-
def v2_runner_on_async_poll(self, result):
|
|
382
|
-
host = result.
|
|
383
|
-
jid = result.
|
|
384
|
-
started = result.
|
|
385
|
-
finished = result.
|
|
385
|
+
def v2_runner_on_async_poll(self, result: CallbackTaskResult) -> None:
|
|
386
|
+
host = result.host.get_name()
|
|
387
|
+
jid = result.result.get('ansible_job_id')
|
|
388
|
+
started = result.result.get('started')
|
|
389
|
+
finished = result.result.get('finished')
|
|
386
390
|
self._display.display(
|
|
387
391
|
'ASYNC POLL on %s: jid=%s started=%s finished=%s' % (host, jid, started, finished),
|
|
388
392
|
color=C.COLOR_DEBUG
|
|
389
393
|
)
|
|
390
394
|
|
|
391
|
-
def v2_runner_on_async_ok(self, result):
|
|
392
|
-
host = result.
|
|
393
|
-
jid = result.
|
|
395
|
+
def v2_runner_on_async_ok(self, result: CallbackTaskResult) -> None:
|
|
396
|
+
host = result.host.get_name()
|
|
397
|
+
jid = result.result.get('ansible_job_id')
|
|
394
398
|
self._display.display("ASYNC OK on %s: jid=%s" % (host, jid), color=C.COLOR_DEBUG)
|
|
395
399
|
|
|
396
|
-
def v2_runner_on_async_failed(self, result):
|
|
397
|
-
host = result.
|
|
400
|
+
def v2_runner_on_async_failed(self, result: CallbackTaskResult) -> None:
|
|
401
|
+
host = result.host.get_name()
|
|
398
402
|
|
|
399
403
|
# Attempt to get the async job ID. If the job does not finish before the
|
|
400
404
|
# async timeout value, the ID may be within the unparsed 'async_result' dict.
|
|
401
|
-
jid = result.
|
|
402
|
-
if not jid and 'async_result' in result.
|
|
403
|
-
jid = result.
|
|
405
|
+
jid = result.result.get('ansible_job_id')
|
|
406
|
+
if not jid and 'async_result' in result.result:
|
|
407
|
+
jid = result.result['async_result'].get('ansible_job_id')
|
|
404
408
|
self._display.display("ASYNC FAILED on %s: jid=%s" % (host, jid), color=C.COLOR_DEBUG)
|
|
405
409
|
|
|
406
410
|
def v2_playbook_on_notify(self, handler, host):
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
DOCUMENTATION =
|
|
7
|
+
DOCUMENTATION = """
|
|
8
8
|
name: junit
|
|
9
9
|
type: aggregate
|
|
10
10
|
short_description: write playbook output to a JUnit file.
|
|
@@ -80,15 +80,22 @@ DOCUMENTATION = '''
|
|
|
80
80
|
- name: JUNIT_TEST_CASE_PREFIX
|
|
81
81
|
requirements:
|
|
82
82
|
- enable in configuration
|
|
83
|
-
|
|
83
|
+
"""
|
|
84
84
|
|
|
85
|
+
import decimal
|
|
85
86
|
import os
|
|
86
87
|
import time
|
|
87
88
|
import re
|
|
89
|
+
import typing as t
|
|
88
90
|
|
|
89
|
-
from ansible import constants
|
|
91
|
+
from ansible import constants
|
|
90
92
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
93
|
+
from ansible.module_utils._internal import _event_utils
|
|
94
|
+
from ansible._internal import _event_formatting
|
|
95
|
+
from ansible.playbook.task import Task
|
|
91
96
|
from ansible.plugins.callback import CallbackBase
|
|
97
|
+
from ansible.executor.task_result import CallbackTaskResult
|
|
98
|
+
from ansible.playbook.included_file import IncludedFile
|
|
92
99
|
from ansible.utils._junit_xml import (
|
|
93
100
|
TestCase,
|
|
94
101
|
TestError,
|
|
@@ -126,7 +133,7 @@ class CallbackModule(CallbackBase):
|
|
|
126
133
|
Default: True
|
|
127
134
|
JUNIT_HIDE_TASK_ARGUMENTS (optional): Hide the arguments for a task
|
|
128
135
|
Default: False
|
|
129
|
-
JUNIT_TEST_CASE_PREFIX (optional): Consider a task only as test case if it has this value as prefix. Additionally failing tasks are recorded as failed
|
|
136
|
+
JUNIT_TEST_CASE_PREFIX (optional): Consider a task only as test case if it has this value as prefix. Additionally, failing tasks are recorded as failed
|
|
130
137
|
test cases.
|
|
131
138
|
Default: <empty>
|
|
132
139
|
"""
|
|
@@ -136,7 +143,7 @@ class CallbackModule(CallbackBase):
|
|
|
136
143
|
CALLBACK_NAME = 'junit'
|
|
137
144
|
CALLBACK_NEEDS_ENABLED = True
|
|
138
145
|
|
|
139
|
-
def __init__(self):
|
|
146
|
+
def __init__(self) -> None:
|
|
140
147
|
super(CallbackModule, self).__init__()
|
|
141
148
|
|
|
142
149
|
self._output_dir = os.getenv('JUNIT_OUTPUT_DIR', os.path.expanduser('~/.ansible.log'))
|
|
@@ -150,20 +157,18 @@ class CallbackModule(CallbackBase):
|
|
|
150
157
|
self._replace_out_of_tree_path = os.getenv('JUNIT_REPLACE_OUT_OF_TREE_PATH', None)
|
|
151
158
|
self._playbook_path = None
|
|
152
159
|
self._playbook_name = None
|
|
153
|
-
self._play_name = None
|
|
154
|
-
self._task_data =
|
|
160
|
+
self._play_name: str | None = None
|
|
161
|
+
self._task_data: dict[str, TaskData] = {}
|
|
155
162
|
|
|
156
163
|
self.disabled = False
|
|
157
164
|
|
|
158
|
-
self._task_data = {}
|
|
159
|
-
|
|
160
165
|
if self._replace_out_of_tree_path is not None:
|
|
161
166
|
self._replace_out_of_tree_path = to_text(self._replace_out_of_tree_path)
|
|
162
167
|
|
|
163
168
|
if not os.path.exists(self._output_dir):
|
|
164
169
|
os.makedirs(self._output_dir)
|
|
165
170
|
|
|
166
|
-
def _start_task(self, task):
|
|
171
|
+
def _start_task(self, task: Task) -> None:
|
|
167
172
|
""" record the start of a task for one or more hosts """
|
|
168
173
|
|
|
169
174
|
uuid = task._uuid
|
|
@@ -183,23 +188,23 @@ class CallbackModule(CallbackBase):
|
|
|
183
188
|
|
|
184
189
|
self._task_data[uuid] = TaskData(uuid, name, path, play, action)
|
|
185
190
|
|
|
186
|
-
def _finish_task(self, status, result):
|
|
191
|
+
def _finish_task(self, status: str, result: IncludedFile | CallbackTaskResult) -> None:
|
|
187
192
|
""" record the results of a task for a single host """
|
|
188
193
|
|
|
189
|
-
|
|
194
|
+
if isinstance(result, CallbackTaskResult):
|
|
195
|
+
task_uuid = result.task._uuid
|
|
196
|
+
host_uuid = result.host._uuid
|
|
197
|
+
host_name = result.host.name
|
|
190
198
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
host_name = result._host.name
|
|
199
|
+
if self._fail_on_change == 'true' and status == 'ok' and result.result.get('changed', False):
|
|
200
|
+
status = 'failed'
|
|
194
201
|
else:
|
|
202
|
+
task_uuid = result._task._uuid
|
|
195
203
|
host_uuid = 'include'
|
|
196
204
|
host_name = 'include'
|
|
197
205
|
|
|
198
206
|
task_data = self._task_data[task_uuid]
|
|
199
207
|
|
|
200
|
-
if self._fail_on_change == 'true' and status == 'ok' and result._result.get('changed', False):
|
|
201
|
-
status = 'failed'
|
|
202
|
-
|
|
203
208
|
# ignore failure if expected and toggle result if asked for
|
|
204
209
|
if status == 'failed' and 'EXPECTED FAILURE' in task_data.name:
|
|
205
210
|
status = 'ok'
|
|
@@ -212,11 +217,11 @@ class CallbackModule(CallbackBase):
|
|
|
212
217
|
if task_data.name.startswith(self._test_case_prefix) or status == 'failed':
|
|
213
218
|
task_data.add_host(HostData(host_uuid, host_name, status, result))
|
|
214
219
|
|
|
215
|
-
def _build_test_case(self, task_data, host_data):
|
|
220
|
+
def _build_test_case(self, task_data: TaskData, host_data: HostData) -> TestCase:
|
|
216
221
|
""" build a TestCase from the given TaskData and HostData """
|
|
217
222
|
|
|
218
223
|
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
|
|
219
|
-
duration = host_data.finish - task_data.start
|
|
224
|
+
duration = decimal.Decimal(host_data.finish - task_data.start)
|
|
220
225
|
|
|
221
226
|
if self._task_relative_path and task_data.path:
|
|
222
227
|
junit_classname = to_text(os.path.relpath(to_bytes(task_data.path), to_bytes(self._task_relative_path)))
|
|
@@ -232,7 +237,8 @@ class CallbackModule(CallbackBase):
|
|
|
232
237
|
if host_data.status == 'included':
|
|
233
238
|
return TestCase(name=name, classname=junit_classname, time=duration, system_out=str(host_data.result))
|
|
234
239
|
|
|
235
|
-
|
|
240
|
+
task_result = t.cast(CallbackTaskResult, host_data.result)
|
|
241
|
+
res = task_result.result
|
|
236
242
|
rc = res.get('rc', 0)
|
|
237
243
|
dump = self._dump_results(res, indent=0)
|
|
238
244
|
dump = self._cleanse_string(dump)
|
|
@@ -243,9 +249,9 @@ class CallbackModule(CallbackBase):
|
|
|
243
249
|
test_case = TestCase(name=name, classname=junit_classname, time=duration)
|
|
244
250
|
|
|
245
251
|
if host_data.status == 'failed':
|
|
246
|
-
if
|
|
247
|
-
message =
|
|
248
|
-
output =
|
|
252
|
+
if error_summary := task_result.exception:
|
|
253
|
+
message = _event_utils.format_event_brief_message(error_summary.event)
|
|
254
|
+
output = _event_formatting.format_event_traceback(error_summary.event)
|
|
249
255
|
test_case.errors.append(TestError(message=message, output=output))
|
|
250
256
|
elif 'msg' in res:
|
|
251
257
|
message = res['msg']
|
|
@@ -261,7 +267,8 @@ class CallbackModule(CallbackBase):
|
|
|
261
267
|
|
|
262
268
|
return test_case
|
|
263
269
|
|
|
264
|
-
|
|
270
|
+
@staticmethod
|
|
271
|
+
def _cleanse_string(value):
|
|
265
272
|
""" convert surrogate escapes to the unicode replacement character to avoid XML encoding errors """
|
|
266
273
|
return to_text(to_bytes(value, errors='surrogateescape'), errors='replace')
|
|
267
274
|
|
|
@@ -271,7 +278,7 @@ class CallbackModule(CallbackBase):
|
|
|
271
278
|
test_cases = []
|
|
272
279
|
|
|
273
280
|
for task_uuid, task_data in self._task_data.items():
|
|
274
|
-
if task_data.action in
|
|
281
|
+
if task_data.action in constants._ACTION_SETUP and self._include_setup_tasks_in_report == 'false':
|
|
275
282
|
continue
|
|
276
283
|
|
|
277
284
|
for host_uuid, host_data in task_data.host_data.items():
|
|
@@ -293,31 +300,25 @@ class CallbackModule(CallbackBase):
|
|
|
293
300
|
def v2_playbook_on_play_start(self, play):
|
|
294
301
|
self._play_name = play.get_name()
|
|
295
302
|
|
|
296
|
-
def
|
|
297
|
-
self._start_task(task)
|
|
298
|
-
|
|
299
|
-
def v2_playbook_on_task_start(self, task, is_conditional):
|
|
300
|
-
self._start_task(task)
|
|
301
|
-
|
|
302
|
-
def v2_playbook_on_cleanup_task_start(self, task):
|
|
303
|
+
def v2_playbook_on_task_start(self, task: Task, is_conditional: bool) -> None:
|
|
303
304
|
self._start_task(task)
|
|
304
305
|
|
|
305
|
-
def v2_playbook_on_handler_task_start(self, task):
|
|
306
|
+
def v2_playbook_on_handler_task_start(self, task: Task) -> None:
|
|
306
307
|
self._start_task(task)
|
|
307
308
|
|
|
308
|
-
def v2_runner_on_failed(self, result, ignore_errors=False):
|
|
309
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors=False) -> None:
|
|
309
310
|
if ignore_errors and self._fail_on_ignore != 'true':
|
|
310
311
|
self._finish_task('ok', result)
|
|
311
312
|
else:
|
|
312
313
|
self._finish_task('failed', result)
|
|
313
314
|
|
|
314
|
-
def v2_runner_on_ok(self, result):
|
|
315
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
|
315
316
|
self._finish_task('ok', result)
|
|
316
317
|
|
|
317
|
-
def v2_runner_on_skipped(self, result):
|
|
318
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
|
318
319
|
self._finish_task('skipped', result)
|
|
319
320
|
|
|
320
|
-
def v2_playbook_on_include(self, included_file):
|
|
321
|
+
def v2_playbook_on_include(self, included_file: IncludedFile) -> None:
|
|
321
322
|
self._finish_task('included', included_file)
|
|
322
323
|
|
|
323
324
|
def v2_playbook_on_stats(self, stats):
|
|
@@ -329,21 +330,21 @@ class TaskData:
|
|
|
329
330
|
Data about an individual task.
|
|
330
331
|
"""
|
|
331
332
|
|
|
332
|
-
def __init__(self, uuid, name, path, play, action):
|
|
333
|
+
def __init__(self, uuid: str, name: str, path: str, play: str, action: str) -> None:
|
|
333
334
|
self.uuid = uuid
|
|
334
335
|
self.name = name
|
|
335
336
|
self.path = path
|
|
336
337
|
self.play = play
|
|
337
338
|
self.start = None
|
|
338
|
-
self.host_data = {}
|
|
339
|
+
self.host_data: dict[str, HostData] = {}
|
|
339
340
|
self.start = time.time()
|
|
340
341
|
self.action = action
|
|
341
342
|
|
|
342
|
-
def add_host(self, host):
|
|
343
|
+
def add_host(self, host: HostData) -> None:
|
|
343
344
|
if host.uuid in self.host_data:
|
|
344
345
|
if host.status == 'included':
|
|
345
346
|
# concatenate task include output from multiple items
|
|
346
|
-
host.result = '
|
|
347
|
+
host.result = f'{self.host_data[host.uuid].result}\n{host.result}'
|
|
347
348
|
else:
|
|
348
349
|
raise Exception('%s: %s: %s: duplicate host callback: %s' % (self.path, self.play, self.name, host.name))
|
|
349
350
|
|
|
@@ -355,7 +356,7 @@ class HostData:
|
|
|
355
356
|
Data about an individual host.
|
|
356
357
|
"""
|
|
357
358
|
|
|
358
|
-
def __init__(self, uuid, name, status, result):
|
|
359
|
+
def __init__(self, uuid: str, name: str, status: str, result: IncludedFile | CallbackTaskResult | str) -> None:
|
|
359
360
|
self.uuid = uuid
|
|
360
361
|
self.name = name
|
|
361
362
|
self.status = status
|