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
|
@@ -18,32 +18,34 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import difflib
|
|
21
|
+
import functools
|
|
22
|
+
import inspect
|
|
21
23
|
import json
|
|
22
24
|
import re
|
|
23
25
|
import sys
|
|
24
26
|
import textwrap
|
|
27
|
+
import typing as t
|
|
28
|
+
import collections.abc as _c
|
|
29
|
+
|
|
25
30
|
from typing import TYPE_CHECKING
|
|
26
31
|
|
|
27
|
-
from collections import OrderedDict
|
|
28
|
-
from collections.abc import MutableMapping
|
|
29
32
|
from copy import deepcopy
|
|
30
33
|
|
|
31
34
|
from ansible import constants as C
|
|
32
|
-
from ansible.module_utils.
|
|
33
|
-
from ansible.
|
|
34
|
-
from ansible.parsing.ajson import AnsibleJSONEncoder
|
|
35
|
-
from ansible.parsing.yaml.dumper import AnsibleDumper
|
|
36
|
-
from ansible.parsing.yaml.objects import AnsibleUnicode
|
|
35
|
+
from ansible.module_utils._internal import _datatag
|
|
36
|
+
from ansible._internal._yaml import _dumper
|
|
37
37
|
from ansible.plugins import AnsiblePlugin
|
|
38
38
|
from ansible.utils.color import stringc
|
|
39
39
|
from ansible.utils.display import Display
|
|
40
|
-
from ansible.utils.unsafe_proxy import AnsibleUnsafeText, NativeJinjaUnsafeText, _is_unsafe
|
|
41
40
|
from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
|
|
41
|
+
from ansible.module_utils._internal._json._profiles import _fallback_to_str
|
|
42
|
+
from ansible._internal._templating import _engine
|
|
43
|
+
from ansible.module_utils._internal import _deprecator
|
|
42
44
|
|
|
43
45
|
import yaml
|
|
44
46
|
|
|
45
47
|
if TYPE_CHECKING:
|
|
46
|
-
from ansible.executor.task_result import
|
|
48
|
+
from ansible.executor.task_result import CallbackTaskResult
|
|
47
49
|
|
|
48
50
|
global_display = Display()
|
|
49
51
|
|
|
@@ -52,23 +54,46 @@ __all__ = ["CallbackBase"]
|
|
|
52
54
|
|
|
53
55
|
|
|
54
56
|
_DEBUG_ALLOWED_KEYS = frozenset(('msg', 'exception', 'warnings', 'deprecations'))
|
|
55
|
-
_YAML_TEXT_TYPES = (text_type, AnsibleUnicode, AnsibleUnsafeText, NativeJinjaUnsafeText)
|
|
56
57
|
# Characters that libyaml/pyyaml consider breaks
|
|
57
58
|
_YAML_BREAK_CHARS = '\n\x85\u2028\u2029' # NL, NEL, LS, PS
|
|
58
59
|
# regex representation of libyaml/pyyaml of a space followed by a break character
|
|
59
60
|
_SPACE_BREAK_RE = re.compile(fr' +([{_YAML_BREAK_CHARS}])')
|
|
60
61
|
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
self._lossy = lossy
|
|
63
|
+
_T_callable = t.TypeVar("_T_callable", bound=t.Callable)
|
|
64
|
+
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# smuggle the ``lossy`` configuration, we do that in ``__init__`` and then
|
|
69
|
-
# define this ``__call__`` that will mimic the ability for pyyaml to instantiate class
|
|
66
|
+
class _AnsibleCallbackDumper(_dumper.AnsibleDumper):
|
|
67
|
+
def __init__(self, *args, lossy: bool = False, **kwargs):
|
|
70
68
|
super().__init__(*args, **kwargs)
|
|
71
|
-
|
|
69
|
+
|
|
70
|
+
self._lossy = lossy
|
|
71
|
+
|
|
72
|
+
def _pretty_represent_str(self, data):
|
|
73
|
+
"""Uses block style for multi-line strings"""
|
|
74
|
+
data = _datatag.AnsibleTagHelper.as_native_type(data)
|
|
75
|
+
|
|
76
|
+
if _should_use_block(data):
|
|
77
|
+
style = '|'
|
|
78
|
+
if self._lossy:
|
|
79
|
+
data = _munge_data_for_lossy_yaml(data)
|
|
80
|
+
else:
|
|
81
|
+
style = self.default_style
|
|
82
|
+
|
|
83
|
+
node = yaml.representer.ScalarNode('tag:yaml.org,2002:str', data, style=style)
|
|
84
|
+
|
|
85
|
+
if self.alias_key is not None:
|
|
86
|
+
self.represented_objects[self.alias_key] = node
|
|
87
|
+
|
|
88
|
+
return node
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def _register_representers(cls) -> None:
|
|
92
|
+
super()._register_representers()
|
|
93
|
+
|
|
94
|
+
# exact type checks occur first against representers, then subclasses against multi-representers
|
|
95
|
+
cls.add_representer(str, cls._pretty_represent_str)
|
|
96
|
+
cls.add_multi_representer(str, cls._pretty_represent_str)
|
|
72
97
|
|
|
73
98
|
|
|
74
99
|
def _should_use_block(scalar):
|
|
@@ -77,6 +102,7 @@ def _should_use_block(scalar):
|
|
|
77
102
|
for ch in _YAML_BREAK_CHARS:
|
|
78
103
|
if ch in scalar:
|
|
79
104
|
return True
|
|
105
|
+
|
|
80
106
|
return False
|
|
81
107
|
|
|
82
108
|
|
|
@@ -95,12 +121,12 @@ class _SpecialCharacterTranslator:
|
|
|
95
121
|
return None
|
|
96
122
|
|
|
97
123
|
|
|
98
|
-
def _filter_yaml_special(scalar):
|
|
124
|
+
def _filter_yaml_special(scalar: str) -> str:
|
|
99
125
|
"""Filter a string removing any character that libyaml/pyyaml declare as special"""
|
|
100
126
|
return scalar.translate(_SpecialCharacterTranslator())
|
|
101
127
|
|
|
102
128
|
|
|
103
|
-
def _munge_data_for_lossy_yaml(scalar):
|
|
129
|
+
def _munge_data_for_lossy_yaml(scalar: str) -> str:
|
|
104
130
|
"""Modify a string so that analyze_scalar in libyaml/pyyaml will allow block formatting"""
|
|
105
131
|
# we care more about readability than accuracy, so...
|
|
106
132
|
# ...libyaml/pyyaml does not permit trailing spaces for block scalars
|
|
@@ -113,45 +139,27 @@ def _munge_data_for_lossy_yaml(scalar):
|
|
|
113
139
|
return _SPACE_BREAK_RE.sub(r'\1', scalar)
|
|
114
140
|
|
|
115
141
|
|
|
116
|
-
def _pretty_represent_str(self, data):
|
|
117
|
-
"""Uses block style for multi-line strings"""
|
|
118
|
-
if _is_unsafe(data):
|
|
119
|
-
data = data._strip_unsafe()
|
|
120
|
-
data = text_type(data)
|
|
121
|
-
if _should_use_block(data):
|
|
122
|
-
style = '|'
|
|
123
|
-
if self._lossy:
|
|
124
|
-
data = _munge_data_for_lossy_yaml(data)
|
|
125
|
-
else:
|
|
126
|
-
style = self.default_style
|
|
127
|
-
|
|
128
|
-
node = yaml.representer.ScalarNode('tag:yaml.org,2002:str', data, style=style)
|
|
129
|
-
if self.alias_key is not None:
|
|
130
|
-
self.represented_objects[self.alias_key] = node
|
|
131
|
-
return node
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
for data_type in _YAML_TEXT_TYPES:
|
|
135
|
-
_AnsibleCallbackDumper.add_representer(
|
|
136
|
-
data_type,
|
|
137
|
-
_pretty_represent_str
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
|
|
141
142
|
class CallbackBase(AnsiblePlugin):
|
|
142
|
-
|
|
143
|
-
'''
|
|
143
|
+
"""
|
|
144
144
|
This is a base ansible callback class that does nothing. New callbacks should
|
|
145
145
|
use this class as a base and override any callback methods they wish to execute
|
|
146
146
|
custom actions.
|
|
147
|
-
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
_implemented_callback_methods: frozenset[str] = frozenset()
|
|
150
|
+
"""Set of callback methods overridden by each subclass; used by TQM to bypass callback dispatch on no-op methods."""
|
|
151
|
+
|
|
152
|
+
def __init__(self, display: Display | None = None, options: dict[str, t.Any] | None = None) -> None:
|
|
153
|
+
super().__init__()
|
|
148
154
|
|
|
149
|
-
def __init__(self, display=None, options=None):
|
|
150
155
|
if display:
|
|
151
156
|
self._display = display
|
|
152
157
|
else:
|
|
153
158
|
self._display = global_display
|
|
154
159
|
|
|
160
|
+
# FUTURE: fix double-loading of non-collection stdout callback plugins that don't set CALLBACK_NEEDS_ENABLED
|
|
161
|
+
|
|
162
|
+
# FUTURE: this code is jacked for 2.x- it should just use the type names and always assume 2.0+ for normal cases
|
|
155
163
|
if self._display.verbosity >= 4:
|
|
156
164
|
name = getattr(self, 'CALLBACK_NAME', 'unnamed')
|
|
157
165
|
ctype = getattr(self, 'CALLBACK_TYPE', 'old')
|
|
@@ -161,49 +169,105 @@ class CallbackBase(AnsiblePlugin):
|
|
|
161
169
|
self.disabled = False
|
|
162
170
|
self.wants_implicit_tasks = False
|
|
163
171
|
|
|
164
|
-
self._plugin_options = {}
|
|
172
|
+
self._plugin_options: dict[str, t.Any] = {}
|
|
173
|
+
|
|
165
174
|
if options is not None:
|
|
166
175
|
self.set_options(options)
|
|
167
176
|
|
|
168
|
-
self._hide_in_debug = (
|
|
177
|
+
self._hide_in_debug = (
|
|
178
|
+
'changed', 'failed', 'skipped', 'invocation', 'skip_reason',
|
|
179
|
+
'ansible_loop_var', 'ansible_index_var', 'ansible_loop',
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
self._current_task_result: CallbackTaskResult | None = None
|
|
169
183
|
|
|
170
184
|
# helper for callbacks, so they don't all have to include deepcopy
|
|
171
185
|
_copy_result = deepcopy
|
|
172
186
|
|
|
187
|
+
def _init_callback_methods(self) -> None:
|
|
188
|
+
"""Record analysis of callback methods on each callback instance for dispatch optimization and deprecation warnings."""
|
|
189
|
+
implemented_callback_methods: set[str] = set()
|
|
190
|
+
deprecated_v1_method_overrides: set[str] = set()
|
|
191
|
+
plugin_file = sys.modules[type(self).__module__].__file__
|
|
192
|
+
|
|
193
|
+
if plugin_info := _deprecator._path_as_plugininfo(plugin_file):
|
|
194
|
+
plugin_name = plugin_info.resolved_name
|
|
195
|
+
else:
|
|
196
|
+
plugin_name = plugin_file
|
|
197
|
+
|
|
198
|
+
for base_v2_method, base_v1_method in CallbackBase._v2_v1_method_map.items():
|
|
199
|
+
method_name = None
|
|
200
|
+
|
|
201
|
+
if not inspect.ismethod(method := getattr(self, (v2_method_name := base_v2_method.__name__))) or method.__func__ is not base_v2_method:
|
|
202
|
+
implemented_callback_methods.add(v2_method_name) # v2 method directly implemented by subclass
|
|
203
|
+
method_name = v2_method_name
|
|
204
|
+
elif base_v1_method is None:
|
|
205
|
+
pass # no corresponding v1 method
|
|
206
|
+
elif not inspect.ismethod(method := getattr(self, (v1_method_name := base_v1_method.__name__))) or method.__func__ is not base_v1_method:
|
|
207
|
+
implemented_callback_methods.add(v2_method_name) # v1 method directly implemented by subclass
|
|
208
|
+
deprecated_v1_method_overrides.add(v1_method_name)
|
|
209
|
+
method_name = v1_method_name
|
|
210
|
+
|
|
211
|
+
if method_name and v2_method_name == 'v2_on_any':
|
|
212
|
+
deprecated_v1_method_overrides.discard(method_name) # avoid including v1 on_any in the v1 deprecation below
|
|
213
|
+
|
|
214
|
+
global_display.deprecated(
|
|
215
|
+
msg=f'The {plugin_name!r} callback plugin implements deprecated method {method_name!r}.',
|
|
216
|
+
version='2.23',
|
|
217
|
+
help_text='Use event-specific callback methods instead.',
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
self._implemented_callback_methods = frozenset(implemented_callback_methods)
|
|
221
|
+
|
|
222
|
+
if deprecated_v1_method_overrides:
|
|
223
|
+
global_display.deprecated(
|
|
224
|
+
msg=f'The {plugin_name!r} callback plugin implements the following deprecated method(s): {", ".join(sorted(deprecated_v1_method_overrides))}',
|
|
225
|
+
version='2.23',
|
|
226
|
+
help_text='Implement the `v2_*` equivalent callback method(s) instead.',
|
|
227
|
+
)
|
|
228
|
+
|
|
173
229
|
def set_option(self, k, v):
|
|
174
230
|
self._plugin_options[k] = C.config.get_config_value(k, plugin_type=self.plugin_type, plugin_name=self._load_name, direct={k: v})
|
|
175
231
|
|
|
176
|
-
def get_option(self, k):
|
|
232
|
+
def get_option(self, k, hostvars=None):
|
|
177
233
|
return self._plugin_options[k]
|
|
178
234
|
|
|
235
|
+
def has_option(self, option):
|
|
236
|
+
return (option in self._plugin_options)
|
|
237
|
+
|
|
179
238
|
def set_options(self, task_keys=None, var_options=None, direct=None):
|
|
180
|
-
|
|
239
|
+
""" This is different than the normal plugin method as callbacks get called early and really don't accept keywords.
|
|
181
240
|
Also _options was already taken for CLI args and callbacks use _plugin_options instead.
|
|
182
|
-
|
|
241
|
+
"""
|
|
183
242
|
|
|
184
243
|
# load from config
|
|
185
244
|
self._plugin_options = C.config.get_plugin_options(self.plugin_type, self._load_name, keys=task_keys, variables=var_options, direct=direct)
|
|
186
245
|
|
|
187
246
|
@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():
|
|
247
|
+
def host_label(result: CallbackTaskResult) -> str:
|
|
248
|
+
"""Return label for the hostname (& delegated hostname) of a task result."""
|
|
249
|
+
label = result.host.get_name()
|
|
250
|
+
if result.task.delegate_to and result.task.delegate_to != result.host.get_name():
|
|
194
251
|
# show delegated host
|
|
195
|
-
label += " -> %s" % result.
|
|
252
|
+
label += " -> %s" % result.task.delegate_to
|
|
196
253
|
# in case we have 'extra resolution'
|
|
197
|
-
ahost = result.
|
|
198
|
-
if result.
|
|
254
|
+
ahost = result.result.get('_ansible_delegated_vars', {}).get('ansible_host', result.task.delegate_to)
|
|
255
|
+
if result.task.delegate_to != ahost:
|
|
199
256
|
label += "(%s)" % ahost
|
|
200
257
|
return label
|
|
201
258
|
|
|
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(
|
|
259
|
+
def _run_is_verbose(self, result: CallbackTaskResult, verbosity: int = 0) -> bool:
|
|
260
|
+
return ((self._display.verbosity > verbosity or result.result.get('_ansible_verbose_always', False) is True)
|
|
261
|
+
and result.result.get('_ansible_verbose_override', False) is False)
|
|
262
|
+
|
|
263
|
+
def _dump_results(
|
|
264
|
+
self,
|
|
265
|
+
result: _c.Mapping[str, t.Any],
|
|
266
|
+
indent: int | None = None,
|
|
267
|
+
sort_keys: bool = True,
|
|
268
|
+
keep_invocation: bool = False,
|
|
269
|
+
serialize: bool = True,
|
|
270
|
+
) -> str:
|
|
207
271
|
try:
|
|
208
272
|
result_format = self.get_option('result_format')
|
|
209
273
|
except KeyError:
|
|
@@ -240,9 +304,12 @@ class CallbackBase(AnsiblePlugin):
|
|
|
240
304
|
if self._display.verbosity < 3 and 'diff' in result:
|
|
241
305
|
del abridged_result['diff']
|
|
242
306
|
|
|
243
|
-
# remove
|
|
244
|
-
|
|
245
|
-
|
|
307
|
+
# remove error/warning values; the stdout callback should have already handled them
|
|
308
|
+
abridged_result.pop('exception', None)
|
|
309
|
+
abridged_result.pop('warnings', None)
|
|
310
|
+
abridged_result.pop('deprecations', None)
|
|
311
|
+
|
|
312
|
+
abridged_result = _engine.TemplateEngine().transform(abridged_result) # ensure the dumped view matches the transformed view a playbook sees
|
|
246
313
|
|
|
247
314
|
if not serialize:
|
|
248
315
|
# Just return ``abridged_result`` without going through serialization
|
|
@@ -251,18 +318,9 @@ class CallbackBase(AnsiblePlugin):
|
|
|
251
318
|
return abridged_result
|
|
252
319
|
|
|
253
320
|
if result_format == 'json':
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
# Python3 bug: throws an exception when keys are non-homogenous types:
|
|
258
|
-
# https://bugs.python.org/issue25457
|
|
259
|
-
# sort into an OrderedDict and then json.dumps() that instead
|
|
260
|
-
if not OrderedDict:
|
|
261
|
-
raise
|
|
262
|
-
return json.dumps(OrderedDict(sorted(abridged_result.items(), key=to_text)),
|
|
263
|
-
cls=AnsibleJSONEncoder, indent=indent,
|
|
264
|
-
ensure_ascii=False, sort_keys=False)
|
|
265
|
-
elif result_format == 'yaml':
|
|
321
|
+
return json.dumps(abridged_result, cls=_fallback_to_str.Encoder, indent=indent, ensure_ascii=False, sort_keys=sort_keys)
|
|
322
|
+
|
|
323
|
+
if result_format == 'yaml':
|
|
266
324
|
# None is a sentinel in this case that indicates default behavior
|
|
267
325
|
# default behavior for yaml is to prettify results
|
|
268
326
|
lossy = pretty_results in (None, True)
|
|
@@ -279,7 +337,7 @@ class CallbackBase(AnsiblePlugin):
|
|
|
279
337
|
yaml.dump(
|
|
280
338
|
abridged_result,
|
|
281
339
|
allow_unicode=True,
|
|
282
|
-
Dumper=_AnsibleCallbackDumper
|
|
340
|
+
Dumper=functools.partial(_AnsibleCallbackDumper, lossy=lossy),
|
|
283
341
|
default_flow_style=False,
|
|
284
342
|
indent=indent,
|
|
285
343
|
# sort_keys=sort_keys # This requires PyYAML>=5.1
|
|
@@ -287,32 +345,36 @@ class CallbackBase(AnsiblePlugin):
|
|
|
287
345
|
' ' * (indent or 4)
|
|
288
346
|
)
|
|
289
347
|
|
|
290
|
-
|
|
291
|
-
'
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
348
|
+
# DTFIX5: add test to exercise this case
|
|
349
|
+
raise ValueError(f'Unsupported result_format {result_format!r}.')
|
|
350
|
+
|
|
351
|
+
def _handle_warnings(self, res: _c.MutableMapping[str, t.Any]) -> None:
|
|
352
|
+
"""Display warnings and deprecation warnings sourced by task execution."""
|
|
353
|
+
if res.pop('warnings', None) and self._current_task_result and (warnings := self._current_task_result.warnings):
|
|
354
|
+
# display warnings from the current task result if `warnings` was not removed from `result` (or made falsey)
|
|
355
|
+
for warning in warnings:
|
|
356
|
+
self._display._warning(warning)
|
|
357
|
+
|
|
358
|
+
if res.pop('deprecations', None) and self._current_task_result and (deprecations := self._current_task_result.deprecations):
|
|
359
|
+
# display deprecations from the current task result if `deprecations` was not removed from `result` (or made falsey)
|
|
360
|
+
for deprecation in deprecations:
|
|
361
|
+
self._display._deprecated(deprecation)
|
|
362
|
+
|
|
363
|
+
def _handle_exception(self, result: _c.MutableMapping[str, t.Any], use_stderr: bool = False) -> None:
|
|
364
|
+
if result.pop('exception', None) and self._current_task_result and (exception := self._current_task_result.exception):
|
|
365
|
+
# display exception from the current task result if `exception` was not removed from `result` (or made falsey)
|
|
366
|
+
self._display._error(exception, stderr=use_stderr)
|
|
367
|
+
|
|
368
|
+
def _handle_warnings_and_exception(self, result: CallbackTaskResult) -> None:
|
|
369
|
+
"""Standardized handling of warnings/deprecations and exceptions from a task/item result."""
|
|
370
|
+
# DTFIX5: make/doc/porting-guide a public version of this method?
|
|
371
|
+
try:
|
|
372
|
+
use_stderr = self.get_option('display_failed_stderr')
|
|
373
|
+
except KeyError:
|
|
374
|
+
use_stderr = False
|
|
314
375
|
|
|
315
|
-
|
|
376
|
+
self._handle_warnings(result.result)
|
|
377
|
+
self._handle_exception(result.result, use_stderr=use_stderr)
|
|
316
378
|
|
|
317
379
|
def _serialize_diff(self, diff):
|
|
318
380
|
try:
|
|
@@ -329,7 +391,8 @@ class CallbackBase(AnsiblePlugin):
|
|
|
329
391
|
|
|
330
392
|
if result_format == 'json':
|
|
331
393
|
return json.dumps(diff, sort_keys=True, indent=4, separators=(u',', u': ')) + u'\n'
|
|
332
|
-
|
|
394
|
+
|
|
395
|
+
if result_format == 'yaml':
|
|
333
396
|
# None is a sentinel in this case that indicates default behavior
|
|
334
397
|
# default behavior for yaml is to prettify results
|
|
335
398
|
lossy = pretty_results in (None, True)
|
|
@@ -337,7 +400,7 @@ class CallbackBase(AnsiblePlugin):
|
|
|
337
400
|
yaml.dump(
|
|
338
401
|
diff,
|
|
339
402
|
allow_unicode=True,
|
|
340
|
-
Dumper=_AnsibleCallbackDumper
|
|
403
|
+
Dumper=functools.partial(_AnsibleCallbackDumper, lossy=lossy),
|
|
341
404
|
default_flow_style=False,
|
|
342
405
|
indent=4,
|
|
343
406
|
# sort_keys=sort_keys # This requires PyYAML>=5.1
|
|
@@ -345,6 +408,9 @@ class CallbackBase(AnsiblePlugin):
|
|
|
345
408
|
' '
|
|
346
409
|
)
|
|
347
410
|
|
|
411
|
+
# DTFIX5: add test to exercise this case
|
|
412
|
+
raise ValueError(f'Unsupported result_format {result_format!r}.')
|
|
413
|
+
|
|
348
414
|
def _get_diff(self, difflist):
|
|
349
415
|
|
|
350
416
|
if not isinstance(difflist, list):
|
|
@@ -363,7 +429,7 @@ class CallbackBase(AnsiblePlugin):
|
|
|
363
429
|
if 'before' in diff and 'after' in diff:
|
|
364
430
|
# format complex structures into 'files'
|
|
365
431
|
for x in ['before', 'after']:
|
|
366
|
-
if isinstance(diff[x],
|
|
432
|
+
if isinstance(diff[x], _c.Mapping):
|
|
367
433
|
diff[x] = self._serialize_diff(diff[x])
|
|
368
434
|
elif diff[x] is None:
|
|
369
435
|
diff[x] = ''
|
|
@@ -405,22 +471,23 @@ class CallbackBase(AnsiblePlugin):
|
|
|
405
471
|
ret.append(diff['prepared'])
|
|
406
472
|
return u''.join(ret)
|
|
407
473
|
|
|
408
|
-
def _get_item_label(self, result):
|
|
409
|
-
|
|
474
|
+
def _get_item_label(self, result: _c.Mapping[str, t.Any]) -> t.Any:
|
|
475
|
+
""" retrieves the value to be displayed as a label for an item entry from a result object"""
|
|
410
476
|
if result.get('_ansible_no_log', False):
|
|
411
477
|
item = "(censored due to no_log)"
|
|
412
478
|
else:
|
|
413
479
|
item = result.get('_ansible_item_label', result.get('item'))
|
|
414
480
|
return item
|
|
415
481
|
|
|
416
|
-
def _process_items(self, result):
|
|
482
|
+
def _process_items(self, result: CallbackTaskResult) -> None:
|
|
417
483
|
# just remove them as now they get handled by individual callbacks
|
|
418
|
-
del result.
|
|
484
|
+
del result.result['results']
|
|
419
485
|
|
|
420
486
|
def _clean_results(self, result, task_name):
|
|
421
|
-
|
|
487
|
+
""" removes data from results for display """
|
|
422
488
|
|
|
423
489
|
# mostly controls that debug only outputs what it was meant to
|
|
490
|
+
# FIXME: this is a terrible heuristic to format debug's output- it masks exception detail
|
|
424
491
|
if task_name in C._ACTION_DEBUG:
|
|
425
492
|
if 'msg' in result:
|
|
426
493
|
# msg should be alone
|
|
@@ -455,9 +522,6 @@ class CallbackBase(AnsiblePlugin):
|
|
|
455
522
|
def runner_on_unreachable(self, host, res):
|
|
456
523
|
pass
|
|
457
524
|
|
|
458
|
-
def runner_on_no_hosts(self):
|
|
459
|
-
pass
|
|
460
|
-
|
|
461
525
|
def runner_on_async_poll(self, host, res, jid, clock):
|
|
462
526
|
pass
|
|
463
527
|
|
|
@@ -485,15 +549,6 @@ class CallbackBase(AnsiblePlugin):
|
|
|
485
549
|
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
|
|
486
550
|
pass
|
|
487
551
|
|
|
488
|
-
def playbook_on_setup(self):
|
|
489
|
-
pass
|
|
490
|
-
|
|
491
|
-
def playbook_on_import_for_host(self, host, imported_file):
|
|
492
|
-
pass
|
|
493
|
-
|
|
494
|
-
def playbook_on_not_import_for_host(self, host, missing_file):
|
|
495
|
-
pass
|
|
496
|
-
|
|
497
552
|
def playbook_on_play_start(self, name):
|
|
498
553
|
pass
|
|
499
554
|
|
|
@@ -507,80 +562,104 @@ class CallbackBase(AnsiblePlugin):
|
|
|
507
562
|
def v2_on_any(self, *args, **kwargs):
|
|
508
563
|
self.on_any(args, kwargs)
|
|
509
564
|
|
|
510
|
-
def v2_runner_on_failed(self, result:
|
|
511
|
-
"""
|
|
512
|
-
running tasks on the host where the failure occurred, then process the details
|
|
513
|
-
as required by the callback (output, profiling, logging, notifications, etc.)
|
|
514
|
-
|
|
515
|
-
Note: The 'ignore_errors' directive only works when the task can run and returns
|
|
516
|
-
a value of 'failed'. It does not make Ansible ignore undefined variable errors,
|
|
517
|
-
connection failures, execution issues (for example, missing packages), or syntax errors.
|
|
565
|
+
def v2_runner_on_failed(self, result: CallbackTaskResult, ignore_errors: bool = False) -> None:
|
|
566
|
+
"""Process results of a failed task.
|
|
518
567
|
|
|
519
|
-
|
|
520
|
-
|
|
568
|
+
Note: The value of 'ignore_errors' tells Ansible whether to
|
|
569
|
+
continue running tasks on the host where this task failed.
|
|
570
|
+
But the 'ignore_errors' directive only works when the task can
|
|
571
|
+
run and returns a value of 'failed'. It does not make Ansible
|
|
572
|
+
ignore undefined variable errors, connection failures, execution
|
|
573
|
+
issues (for example, missing packages), or syntax errors.
|
|
521
574
|
|
|
522
|
-
:param
|
|
523
|
-
:
|
|
524
|
-
|
|
575
|
+
:param result: The parameters of the task and its results.
|
|
576
|
+
:type result: CallbackTaskResult
|
|
577
|
+
:param ignore_errors: Whether Ansible should continue \
|
|
578
|
+
running tasks on the host where the task failed.
|
|
579
|
+
:type ignore_errors: bool
|
|
525
580
|
|
|
526
581
|
:return: None
|
|
582
|
+
:rtype: None
|
|
527
583
|
"""
|
|
528
|
-
host = result.
|
|
529
|
-
self.runner_on_failed(host, result.
|
|
584
|
+
host = result.host.get_name()
|
|
585
|
+
self.runner_on_failed(host, result.result, ignore_errors)
|
|
530
586
|
|
|
531
|
-
def v2_runner_on_ok(self, result:
|
|
532
|
-
"""
|
|
533
|
-
(output, profiling, logging, notifications, etc.)
|
|
587
|
+
def v2_runner_on_ok(self, result: CallbackTaskResult) -> None:
|
|
588
|
+
"""Process results of a successful task.
|
|
534
589
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
:param TaskResult result: An object that contains details about the task
|
|
590
|
+
:param result: The parameters of the task and its results.
|
|
591
|
+
:type result: CallbackTaskResult
|
|
539
592
|
|
|
540
593
|
:return: None
|
|
594
|
+
:rtype: None
|
|
541
595
|
"""
|
|
542
|
-
host = result.
|
|
543
|
-
self.runner_on_ok(host, result.
|
|
544
|
-
|
|
545
|
-
def v2_runner_on_skipped(self, result: TaskResult) -> None:
|
|
546
|
-
"""Get details about a skipped task and process them as required by the callback
|
|
547
|
-
(output, profiling, logging, notifications, etc.)
|
|
596
|
+
host = result.host.get_name()
|
|
597
|
+
self.runner_on_ok(host, result.result)
|
|
548
598
|
|
|
549
|
-
|
|
550
|
-
|
|
599
|
+
def v2_runner_on_skipped(self, result: CallbackTaskResult) -> None:
|
|
600
|
+
"""Process results of a skipped task.
|
|
551
601
|
|
|
552
|
-
:param
|
|
602
|
+
:param result: The parameters of the task and its results.
|
|
603
|
+
:type result: CallbackTaskResult
|
|
553
604
|
|
|
554
605
|
:return: None
|
|
606
|
+
:rtype: None
|
|
555
607
|
"""
|
|
556
608
|
if C.DISPLAY_SKIPPED_HOSTS:
|
|
557
|
-
host = result.
|
|
558
|
-
self.runner_on_skipped(host, self._get_item_label(getattr(result.
|
|
609
|
+
host = result.host.get_name()
|
|
610
|
+
self.runner_on_skipped(host, self._get_item_label(getattr(result.result, 'results', {})))
|
|
559
611
|
|
|
560
|
-
def v2_runner_on_unreachable(self, result):
|
|
561
|
-
|
|
562
|
-
self.runner_on_unreachable(host, result._result)
|
|
612
|
+
def v2_runner_on_unreachable(self, result: CallbackTaskResult) -> None:
|
|
613
|
+
"""Process results of a task if a target node is unreachable.
|
|
563
614
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
615
|
+
:param result: The parameters of the task and its results.
|
|
616
|
+
:type result: CallbackTaskResult
|
|
617
|
+
|
|
618
|
+
:return: None
|
|
619
|
+
:rtype: None
|
|
620
|
+
"""
|
|
621
|
+
host = result.host.get_name()
|
|
622
|
+
self.runner_on_unreachable(host, result.result)
|
|
623
|
+
|
|
624
|
+
def v2_runner_on_async_poll(self, result: CallbackTaskResult) -> None:
|
|
625
|
+
"""Get details about an unfinished task running in async mode.
|
|
626
|
+
|
|
627
|
+
Note: The value of the `poll` keyword in the task determines
|
|
628
|
+
the interval at which polling occurs and this method is run.
|
|
629
|
+
|
|
630
|
+
:param result: The parameters of the task and its status.
|
|
631
|
+
:type result: CallbackTaskResult
|
|
632
|
+
|
|
633
|
+
:rtype: None
|
|
634
|
+
:rtype: None
|
|
635
|
+
"""
|
|
636
|
+
host = result.host.get_name()
|
|
637
|
+
jid = result.result.get('ansible_job_id')
|
|
567
638
|
# FIXME, get real clock
|
|
568
639
|
clock = 0
|
|
569
|
-
self.runner_on_async_poll(host, result.
|
|
640
|
+
self.runner_on_async_poll(host, result.result, jid, clock)
|
|
641
|
+
|
|
642
|
+
def v2_runner_on_async_ok(self, result: CallbackTaskResult) -> None:
|
|
643
|
+
"""Process results of a successful task that ran in async mode.
|
|
570
644
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
jid = result._result.get('ansible_job_id')
|
|
574
|
-
self.runner_on_async_ok(host, result._result, jid)
|
|
645
|
+
:param result: The parameters of the task and its results.
|
|
646
|
+
:type result: CallbackTaskResult
|
|
575
647
|
|
|
576
|
-
|
|
577
|
-
|
|
648
|
+
:return: None
|
|
649
|
+
:rtype: None
|
|
650
|
+
"""
|
|
651
|
+
host = result.host.get_name()
|
|
652
|
+
jid = result.result.get('ansible_job_id')
|
|
653
|
+
self.runner_on_async_ok(host, result.result, jid)
|
|
654
|
+
|
|
655
|
+
def v2_runner_on_async_failed(self, result: CallbackTaskResult) -> None:
|
|
656
|
+
host = result.host.get_name()
|
|
578
657
|
# Attempt to get the async job ID. If the job does not finish before the
|
|
579
658
|
# async timeout value, the ID may be within the unparsed 'async_result' dict.
|
|
580
|
-
jid = result.
|
|
581
|
-
if not jid and 'async_result' in result.
|
|
582
|
-
jid = result.
|
|
583
|
-
self.runner_on_async_failed(host, result.
|
|
659
|
+
jid = result.result.get('ansible_job_id')
|
|
660
|
+
if not jid and 'async_result' in result.result:
|
|
661
|
+
jid = result.result['async_result'].get('ansible_job_id')
|
|
662
|
+
self.runner_on_async_failed(host, result.result, jid)
|
|
584
663
|
|
|
585
664
|
def v2_playbook_on_start(self, playbook):
|
|
586
665
|
self.playbook_on_start()
|
|
@@ -597,50 +676,36 @@ class CallbackBase(AnsiblePlugin):
|
|
|
597
676
|
def v2_playbook_on_task_start(self, task, is_conditional):
|
|
598
677
|
self.playbook_on_task_start(task.name, is_conditional)
|
|
599
678
|
|
|
600
|
-
# FIXME: not called
|
|
601
|
-
def v2_playbook_on_cleanup_task_start(self, task):
|
|
602
|
-
pass # no v1 correspondence
|
|
603
|
-
|
|
604
679
|
def v2_playbook_on_handler_task_start(self, task):
|
|
605
680
|
pass # no v1 correspondence
|
|
606
681
|
|
|
607
682
|
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):
|
|
608
683
|
self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default, unsafe)
|
|
609
684
|
|
|
610
|
-
# FIXME: not called
|
|
611
|
-
def v2_playbook_on_import_for_host(self, result, imported_file):
|
|
612
|
-
host = result._host.get_name()
|
|
613
|
-
self.playbook_on_import_for_host(host, imported_file)
|
|
614
|
-
|
|
615
|
-
# FIXME: not called
|
|
616
|
-
def v2_playbook_on_not_import_for_host(self, result, missing_file):
|
|
617
|
-
host = result._host.get_name()
|
|
618
|
-
self.playbook_on_not_import_for_host(host, missing_file)
|
|
619
|
-
|
|
620
685
|
def v2_playbook_on_play_start(self, play):
|
|
621
686
|
self.playbook_on_play_start(play.name)
|
|
622
687
|
|
|
623
688
|
def v2_playbook_on_stats(self, stats):
|
|
624
689
|
self.playbook_on_stats(stats)
|
|
625
690
|
|
|
626
|
-
def v2_on_file_diff(self, result):
|
|
627
|
-
if 'diff' in result.
|
|
628
|
-
host = result.
|
|
629
|
-
self.on_file_diff(host, result.
|
|
691
|
+
def v2_on_file_diff(self, result: CallbackTaskResult) -> None:
|
|
692
|
+
if 'diff' in result.result:
|
|
693
|
+
host = result.host.get_name()
|
|
694
|
+
self.on_file_diff(host, result.result['diff'])
|
|
630
695
|
|
|
631
696
|
def v2_playbook_on_include(self, included_file):
|
|
632
697
|
pass # no v1 correspondence
|
|
633
698
|
|
|
634
|
-
def v2_runner_item_on_ok(self, result):
|
|
699
|
+
def v2_runner_item_on_ok(self, result: CallbackTaskResult) -> None:
|
|
635
700
|
pass
|
|
636
701
|
|
|
637
|
-
def v2_runner_item_on_failed(self, result):
|
|
702
|
+
def v2_runner_item_on_failed(self, result: CallbackTaskResult) -> None:
|
|
638
703
|
pass
|
|
639
704
|
|
|
640
|
-
def v2_runner_item_on_skipped(self, result):
|
|
705
|
+
def v2_runner_item_on_skipped(self, result: CallbackTaskResult) -> None:
|
|
641
706
|
pass
|
|
642
707
|
|
|
643
|
-
def v2_runner_retry(self, result):
|
|
708
|
+
def v2_runner_retry(self, result: CallbackTaskResult) -> None:
|
|
644
709
|
pass
|
|
645
710
|
|
|
646
711
|
def v2_runner_on_start(self, host, task):
|
|
@@ -649,3 +714,31 @@ class CallbackBase(AnsiblePlugin):
|
|
|
649
714
|
.. versionadded:: 2.8
|
|
650
715
|
"""
|
|
651
716
|
pass
|
|
717
|
+
|
|
718
|
+
_v2_v1_method_map = {
|
|
719
|
+
v2_on_any: on_any,
|
|
720
|
+
v2_on_file_diff: on_file_diff,
|
|
721
|
+
v2_playbook_on_handler_task_start: None,
|
|
722
|
+
v2_playbook_on_include: None,
|
|
723
|
+
v2_playbook_on_no_hosts_matched: playbook_on_no_hosts_matched,
|
|
724
|
+
v2_playbook_on_no_hosts_remaining: playbook_on_no_hosts_remaining,
|
|
725
|
+
v2_playbook_on_notify: playbook_on_notify,
|
|
726
|
+
v2_playbook_on_play_start: playbook_on_play_start,
|
|
727
|
+
v2_playbook_on_start: playbook_on_start,
|
|
728
|
+
v2_playbook_on_stats: playbook_on_stats,
|
|
729
|
+
v2_playbook_on_task_start: playbook_on_task_start,
|
|
730
|
+
v2_playbook_on_vars_prompt: playbook_on_vars_prompt,
|
|
731
|
+
v2_runner_item_on_failed: None,
|
|
732
|
+
v2_runner_item_on_ok: None,
|
|
733
|
+
v2_runner_item_on_skipped: None,
|
|
734
|
+
v2_runner_on_async_failed: runner_on_async_failed,
|
|
735
|
+
v2_runner_on_async_ok: runner_on_async_ok,
|
|
736
|
+
v2_runner_on_async_poll: runner_on_async_poll,
|
|
737
|
+
v2_runner_on_failed: runner_on_failed,
|
|
738
|
+
v2_runner_on_ok: runner_on_ok,
|
|
739
|
+
v2_runner_on_skipped: runner_on_skipped,
|
|
740
|
+
v2_runner_on_start: None,
|
|
741
|
+
v2_runner_on_unreachable: runner_on_unreachable,
|
|
742
|
+
v2_runner_retry: None,
|
|
743
|
+
}
|
|
744
|
+
"""Internal mapping of v2 callback methods with v1 counterparts; populated after type init for deprecation warnings and bypass calculation."""
|