ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -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/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +160 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +198 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -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 +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +351 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -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 +62 -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 +18 -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 +153 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +48 -46
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +165 -108
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- 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 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- 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 +136 -76
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +237 -236
- ansible/executor/task_queue_manager.py +62 -38
- ansible/executor/task_result.py +21 -12
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +77 -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.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -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 +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -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 +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -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_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +154 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -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/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- 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 +86 -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 +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -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 +1 -1
- 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 +4 -4
- 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 +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- 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 +9 -8
- 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 +1 -2
- 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/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 +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- 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 +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +19 -17
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- 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 +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- 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 +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +32 -27
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- 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/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- 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 +36 -339
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- 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 +6 -15
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- 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 +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- 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 +4 -5
- ansible/plugins/action/gather_facts.py +7 -6
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- 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 +35 -44
- 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 +141 -123
- ansible/plugins/callback/default.py +30 -23
- ansible/plugins/callback/junit.py +28 -24
- ansible/plugins/callback/minimal.py +17 -14
- ansible/plugins/callback/oneline.py +13 -7
- ansible/plugins/callback/tree.py +10 -6
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- 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 +6 -2
- 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 +218 -108
- ansible/plugins/filter/encryption.py +32 -32
- 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/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- 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 +97 -77
- 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 +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- 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 +86 -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 +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +94 -113
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +13 -28
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +31 -33
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +54 -20
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +368 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +428 -58
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +28 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +4 -4
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +205 -264
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/WHEEL +1 -1
- 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 +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- 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 +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- 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 -0
- 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 +1 -0
- 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 +2 -1
- 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 +4 -0
- 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 +2 -1
- 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 +1 -0
- 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 +16 -1
- 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 +1 -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 +24 -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 +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- 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 +2 -0
- 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/delegation.py +1 -0
- 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 +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -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 +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- 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 +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- 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/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 +35 -27
- 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/utils/jsonify.py +0 -36
- 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.5rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.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: junit
|
9
9
|
type: aggregate
|
10
10
|
short_description: write playbook output to a JUnit file.
|
@@ -80,14 +80,17 @@ 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
|
88
89
|
|
89
|
-
from ansible import constants
|
90
|
+
from ansible import constants
|
91
|
+
from ansible.module_utils.common.messages import ErrorSummary
|
90
92
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
93
|
+
from ansible.playbook.task import Task
|
91
94
|
from ansible.plugins.callback import CallbackBase
|
92
95
|
from ansible.utils._junit_xml import (
|
93
96
|
TestCase,
|
@@ -126,7 +129,7 @@ class CallbackModule(CallbackBase):
|
|
126
129
|
Default: True
|
127
130
|
JUNIT_HIDE_TASK_ARGUMENTS (optional): Hide the arguments for a task
|
128
131
|
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
|
132
|
+
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
133
|
test cases.
|
131
134
|
Default: <empty>
|
132
135
|
"""
|
@@ -136,7 +139,7 @@ class CallbackModule(CallbackBase):
|
|
136
139
|
CALLBACK_NAME = 'junit'
|
137
140
|
CALLBACK_NEEDS_ENABLED = True
|
138
141
|
|
139
|
-
def __init__(self):
|
142
|
+
def __init__(self) -> None:
|
140
143
|
super(CallbackModule, self).__init__()
|
141
144
|
|
142
145
|
self._output_dir = os.getenv('JUNIT_OUTPUT_DIR', os.path.expanduser('~/.ansible.log'))
|
@@ -150,20 +153,18 @@ class CallbackModule(CallbackBase):
|
|
150
153
|
self._replace_out_of_tree_path = os.getenv('JUNIT_REPLACE_OUT_OF_TREE_PATH', None)
|
151
154
|
self._playbook_path = None
|
152
155
|
self._playbook_name = None
|
153
|
-
self._play_name = None
|
154
|
-
self._task_data =
|
156
|
+
self._play_name: str | None = None
|
157
|
+
self._task_data: dict[str, TaskData] = {}
|
155
158
|
|
156
159
|
self.disabled = False
|
157
160
|
|
158
|
-
self._task_data = {}
|
159
|
-
|
160
161
|
if self._replace_out_of_tree_path is not None:
|
161
162
|
self._replace_out_of_tree_path = to_text(self._replace_out_of_tree_path)
|
162
163
|
|
163
164
|
if not os.path.exists(self._output_dir):
|
164
165
|
os.makedirs(self._output_dir)
|
165
166
|
|
166
|
-
def _start_task(self, task):
|
167
|
+
def _start_task(self, task: Task) -> None:
|
167
168
|
""" record the start of a task for one or more hosts """
|
168
169
|
|
169
170
|
uuid = task._uuid
|
@@ -212,11 +213,11 @@ class CallbackModule(CallbackBase):
|
|
212
213
|
if task_data.name.startswith(self._test_case_prefix) or status == 'failed':
|
213
214
|
task_data.add_host(HostData(host_uuid, host_name, status, result))
|
214
215
|
|
215
|
-
def _build_test_case(self, task_data, host_data):
|
216
|
+
def _build_test_case(self, task_data: TaskData, host_data: HostData) -> TestCase:
|
216
217
|
""" build a TestCase from the given TaskData and HostData """
|
217
218
|
|
218
219
|
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
|
219
|
-
duration = host_data.finish - task_data.start
|
220
|
+
duration = decimal.Decimal(host_data.finish - task_data.start)
|
220
221
|
|
221
222
|
if self._task_relative_path and task_data.path:
|
222
223
|
junit_classname = to_text(os.path.relpath(to_bytes(task_data.path), to_bytes(self._task_relative_path)))
|
@@ -242,10 +243,12 @@ class CallbackModule(CallbackBase):
|
|
242
243
|
|
243
244
|
test_case = TestCase(name=name, classname=junit_classname, time=duration)
|
244
245
|
|
246
|
+
error_summary: ErrorSummary
|
247
|
+
|
245
248
|
if host_data.status == 'failed':
|
246
|
-
if 'exception'
|
247
|
-
message =
|
248
|
-
output =
|
249
|
+
if error_summary := res.get('exception'):
|
250
|
+
message = error_summary._format()
|
251
|
+
output = error_summary.formatted_traceback
|
249
252
|
test_case.errors.append(TestError(message=message, output=output))
|
250
253
|
elif 'msg' in res:
|
251
254
|
message = res['msg']
|
@@ -261,7 +264,8 @@ class CallbackModule(CallbackBase):
|
|
261
264
|
|
262
265
|
return test_case
|
263
266
|
|
264
|
-
|
267
|
+
@staticmethod
|
268
|
+
def _cleanse_string(value):
|
265
269
|
""" convert surrogate escapes to the unicode replacement character to avoid XML encoding errors """
|
266
270
|
return to_text(to_bytes(value, errors='surrogateescape'), errors='replace')
|
267
271
|
|
@@ -271,7 +275,7 @@ class CallbackModule(CallbackBase):
|
|
271
275
|
test_cases = []
|
272
276
|
|
273
277
|
for task_uuid, task_data in self._task_data.items():
|
274
|
-
if task_data.action in
|
278
|
+
if task_data.action in constants._ACTION_SETUP and self._include_setup_tasks_in_report == 'false':
|
275
279
|
continue
|
276
280
|
|
277
281
|
for host_uuid, host_data in task_data.host_data.items():
|
@@ -293,16 +297,16 @@ class CallbackModule(CallbackBase):
|
|
293
297
|
def v2_playbook_on_play_start(self, play):
|
294
298
|
self._play_name = play.get_name()
|
295
299
|
|
296
|
-
def v2_runner_on_no_hosts(self, task):
|
300
|
+
def v2_runner_on_no_hosts(self, task: Task) -> None:
|
297
301
|
self._start_task(task)
|
298
302
|
|
299
|
-
def v2_playbook_on_task_start(self, task, is_conditional):
|
303
|
+
def v2_playbook_on_task_start(self, task: Task, is_conditional: bool) -> None:
|
300
304
|
self._start_task(task)
|
301
305
|
|
302
|
-
def v2_playbook_on_cleanup_task_start(self, task):
|
306
|
+
def v2_playbook_on_cleanup_task_start(self, task: Task) -> None:
|
303
307
|
self._start_task(task)
|
304
308
|
|
305
|
-
def v2_playbook_on_handler_task_start(self, task):
|
309
|
+
def v2_playbook_on_handler_task_start(self, task: Task) -> None:
|
306
310
|
self._start_task(task)
|
307
311
|
|
308
312
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
@@ -329,17 +333,17 @@ class TaskData:
|
|
329
333
|
Data about an individual task.
|
330
334
|
"""
|
331
335
|
|
332
|
-
def __init__(self, uuid, name, path, play, action):
|
336
|
+
def __init__(self, uuid: str, name: str, path: str, play: str, action: str) -> None:
|
333
337
|
self.uuid = uuid
|
334
338
|
self.name = name
|
335
339
|
self.path = path
|
336
340
|
self.play = play
|
337
341
|
self.start = None
|
338
|
-
self.host_data = {}
|
342
|
+
self.host_data: dict[str, HostData] = {}
|
339
343
|
self.start = time.time()
|
340
344
|
self.action = action
|
341
345
|
|
342
|
-
def add_host(self, host):
|
346
|
+
def add_host(self, host: HostData) -> None:
|
343
347
|
if host.uuid in self.host_data:
|
344
348
|
if host.status == 'included':
|
345
349
|
# concatenate task include output from multiple items
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
|
-
DOCUMENTATION =
|
7
|
+
DOCUMENTATION = """
|
8
8
|
name: minimal
|
9
9
|
type: stdout
|
10
10
|
short_description: minimal Ansible screen output
|
@@ -13,25 +13,26 @@ DOCUMENTATION = '''
|
|
13
13
|
- This is the default output callback used by the ansible command (ad-hoc)
|
14
14
|
extends_documentation_fragment:
|
15
15
|
- result_format_callback
|
16
|
-
|
16
|
+
"""
|
17
17
|
|
18
|
+
from ansible.executor.task_result import TaskResult
|
18
19
|
from ansible.plugins.callback import CallbackBase
|
19
20
|
from ansible import constants as C
|
20
21
|
|
21
22
|
|
22
23
|
class CallbackModule(CallbackBase):
|
23
24
|
|
24
|
-
|
25
|
+
"""
|
25
26
|
This is the default callback interface, which simply prints messages
|
26
27
|
to stdout when new callback events are received.
|
27
|
-
|
28
|
+
"""
|
28
29
|
|
29
30
|
CALLBACK_VERSION = 2.0
|
30
31
|
CALLBACK_TYPE = 'stdout'
|
31
32
|
CALLBACK_NAME = 'minimal'
|
32
33
|
|
33
34
|
def _command_generic_msg(self, host, result, caption):
|
34
|
-
|
35
|
+
""" output the result of a command run """
|
35
36
|
|
36
37
|
buf = "%s | %s | rc=%s >>\n" % (host, caption, result.get('rc', -1))
|
37
38
|
buf += result.get('stdout', '')
|
@@ -40,20 +41,18 @@ class CallbackModule(CallbackBase):
|
|
40
41
|
|
41
42
|
return buf + "\n"
|
42
43
|
|
43
|
-
def v2_runner_on_failed(self, result, ignore_errors=False):
|
44
|
-
|
45
|
-
self._handle_exception(result._result)
|
46
|
-
self._handle_warnings(result._result)
|
44
|
+
def v2_runner_on_failed(self, result: TaskResult, ignore_errors: bool = False) -> None:
|
45
|
+
self._handle_warnings_and_exception(result)
|
47
46
|
|
48
47
|
if result._task.action in C.MODULE_NO_JSON and 'module_stderr' not in result._result:
|
49
48
|
self._display.display(self._command_generic_msg(result._host.get_name(), result._result, "FAILED"), color=C.COLOR_ERROR)
|
50
49
|
else:
|
51
50
|
self._display.display("%s | FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result, indent=4)), color=C.COLOR_ERROR)
|
52
51
|
|
53
|
-
def v2_runner_on_ok(self, result):
|
54
|
-
self.
|
52
|
+
def v2_runner_on_ok(self, result: TaskResult) -> None:
|
53
|
+
self._handle_warnings_and_exception(result)
|
55
54
|
|
56
|
-
self.
|
55
|
+
self._clean_results(result._result, result._task.action)
|
57
56
|
|
58
57
|
if result._result.get('changed', False):
|
59
58
|
color = C.COLOR_CHANGED
|
@@ -67,10 +66,14 @@ class CallbackModule(CallbackBase):
|
|
67
66
|
else:
|
68
67
|
self._display.display("%s | %s => %s" % (result._host.get_name(), state, self._dump_results(result._result, indent=4)), color=color)
|
69
68
|
|
70
|
-
def v2_runner_on_skipped(self, result):
|
69
|
+
def v2_runner_on_skipped(self, result: TaskResult) -> None:
|
70
|
+
self._handle_warnings_and_exception(result)
|
71
|
+
|
71
72
|
self._display.display("%s | SKIPPED" % (result._host.get_name()), color=C.COLOR_SKIP)
|
72
73
|
|
73
|
-
def v2_runner_on_unreachable(self, result):
|
74
|
+
def v2_runner_on_unreachable(self, result: TaskResult) -> None:
|
75
|
+
self._handle_warnings_and_exception(result)
|
76
|
+
|
74
77
|
self._display.display("%s | UNREACHABLE! => %s" % (result._host.get_name(), self._dump_results(result._result, indent=4)), color=C.COLOR_UNREACHABLE)
|
75
78
|
|
76
79
|
def v2_on_file_diff(self, result):
|
@@ -4,30 +4,35 @@
|
|
4
4
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
|
-
DOCUMENTATION =
|
7
|
+
DOCUMENTATION = """
|
8
8
|
name: oneline
|
9
9
|
type: stdout
|
10
10
|
short_description: oneline Ansible screen output
|
11
11
|
version_added: historical
|
12
12
|
description:
|
13
13
|
- This is the output callback used by the C(-o)/C(--one-line) command line option.
|
14
|
-
|
14
|
+
"""
|
15
15
|
|
16
|
-
from ansible.plugins.callback import CallbackBase
|
17
16
|
from ansible import constants as C
|
17
|
+
from ansible.plugins.callback import CallbackBase
|
18
|
+
from ansible.template import Templar
|
18
19
|
|
19
20
|
|
20
21
|
class CallbackModule(CallbackBase):
|
21
22
|
|
22
|
-
|
23
|
+
"""
|
23
24
|
This is the default callback interface, which simply prints messages
|
24
25
|
to stdout when new callback events are received.
|
25
|
-
|
26
|
+
"""
|
26
27
|
|
27
28
|
CALLBACK_VERSION = 2.0
|
28
29
|
CALLBACK_TYPE = 'stdout'
|
29
30
|
CALLBACK_NAME = 'oneline'
|
30
31
|
|
32
|
+
def __init__(self, *args, **kwargs):
|
33
|
+
super().__init__(*args, **kwargs)
|
34
|
+
self._display.deprecated('The oneline callback plugin is deprecated.', version='2.23')
|
35
|
+
|
31
36
|
def _command_generic_msg(self, hostname, result, caption):
|
32
37
|
stdout = result.get('stdout', '').replace('\n', '\\n').replace('\r', '\\r')
|
33
38
|
if 'stderr' in result and result['stderr']:
|
@@ -38,12 +43,13 @@ class CallbackModule(CallbackBase):
|
|
38
43
|
|
39
44
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
40
45
|
if 'exception' in result._result:
|
46
|
+
error_text = Templar().template(result._result['exception']) # transform to a string
|
41
47
|
if self._display.verbosity < 3:
|
42
48
|
# extract just the actual error message from the exception text
|
43
|
-
error =
|
49
|
+
error = error_text.strip().split('\n')[-1]
|
44
50
|
msg = "An exception occurred during task execution. To see the full traceback, use -vvv. The error was: %s" % error
|
45
51
|
else:
|
46
|
-
msg = "An exception occurred during task execution. The full traceback is:\n" +
|
52
|
+
msg = "An exception occurred during task execution. The full traceback is:\n" + error_text.replace('\n', '')
|
47
53
|
|
48
54
|
if result._task.action in C.MODULE_NO_JSON and 'module_stderr' not in result._result:
|
49
55
|
self._display.display(self._command_generic_msg(result._host.get_name(), result._result, 'FAILED'), color=C.COLOR_ERROR)
|
ansible/plugins/callback/tree.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
|
-
DOCUMENTATION =
|
7
|
+
DOCUMENTATION = """
|
8
8
|
name: tree
|
9
9
|
type: notification
|
10
10
|
requirements:
|
@@ -25,7 +25,7 @@ DOCUMENTATION = '''
|
|
25
25
|
description:
|
26
26
|
- "This callback is used by the Ansible (adhoc) command line option C(-t|--tree)."
|
27
27
|
- This produces a JSON dump of events in a directory, a file for each host, the directory used MUST be passed as a command line option.
|
28
|
-
|
28
|
+
"""
|
29
29
|
|
30
30
|
import os
|
31
31
|
|
@@ -36,17 +36,21 @@ from ansible.utils.path import makedirs_safe, unfrackpath
|
|
36
36
|
|
37
37
|
|
38
38
|
class CallbackModule(CallbackBase):
|
39
|
-
|
39
|
+
"""
|
40
40
|
This callback puts results into a host specific file in a directory in json format.
|
41
|
-
|
41
|
+
"""
|
42
42
|
|
43
43
|
CALLBACK_VERSION = 2.0
|
44
44
|
CALLBACK_TYPE = 'aggregate'
|
45
45
|
CALLBACK_NAME = 'tree'
|
46
46
|
CALLBACK_NEEDS_ENABLED = True
|
47
47
|
|
48
|
+
def __init__(self, *args, **kwargs):
|
49
|
+
super().__init__(*args, **kwargs)
|
50
|
+
self._display.deprecated('The tree callback plugin is deprecated.', version='2.23')
|
51
|
+
|
48
52
|
def set_options(self, task_keys=None, var_options=None, direct=None):
|
49
|
-
|
53
|
+
""" override to set self.tree """
|
50
54
|
|
51
55
|
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
52
56
|
|
@@ -57,7 +61,7 @@ class CallbackModule(CallbackBase):
|
|
57
61
|
self.tree = self.get_option('directory')
|
58
62
|
|
59
63
|
def write_tree_file(self, hostname, buf):
|
60
|
-
|
64
|
+
""" write something into treedir/hostname """
|
61
65
|
|
62
66
|
buf = to_bytes(buf)
|
63
67
|
try:
|
@@ -15,6 +15,7 @@ from abc import abstractmethod
|
|
15
15
|
from functools import wraps
|
16
16
|
|
17
17
|
from ansible import constants as C
|
18
|
+
from ansible.errors import AnsibleValueOmittedError
|
18
19
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
19
20
|
from ansible.playbook.play_context import PlayContext
|
20
21
|
from ansible.plugins import AnsiblePlugin
|
@@ -35,6 +36,12 @@ P = t.ParamSpec('P')
|
|
35
36
|
T = t.TypeVar('T')
|
36
37
|
|
37
38
|
|
39
|
+
class ConnectionKwargs(t.TypedDict):
|
40
|
+
task_uuid: str
|
41
|
+
ansible_playbook_pid: str
|
42
|
+
shell: t.NotRequired[ShellBase]
|
43
|
+
|
44
|
+
|
38
45
|
def ensure_connect(
|
39
46
|
func: c.Callable[t.Concatenate[ConnectionBase, P], T],
|
40
47
|
) -> c.Callable[t.Concatenate[ConnectionBase, P], T]:
|
@@ -47,9 +54,9 @@ def ensure_connect(
|
|
47
54
|
|
48
55
|
|
49
56
|
class ConnectionBase(AnsiblePlugin):
|
50
|
-
|
57
|
+
"""
|
51
58
|
A base class for connections to contain common code.
|
52
|
-
|
59
|
+
"""
|
53
60
|
|
54
61
|
has_pipelining = False
|
55
62
|
has_native_async = False # eg, winrm
|
@@ -71,10 +78,8 @@ class ConnectionBase(AnsiblePlugin):
|
|
71
78
|
def __init__(
|
72
79
|
self,
|
73
80
|
play_context: PlayContext,
|
74
|
-
new_stdin: io.TextIOWrapper | None = None,
|
75
|
-
shell: ShellBase | None = None,
|
76
81
|
*args: t.Any,
|
77
|
-
**kwargs: t.
|
82
|
+
**kwargs: t.Unpack[ConnectionKwargs],
|
78
83
|
) -> None:
|
79
84
|
|
80
85
|
super(ConnectionBase, self).__init__()
|
@@ -83,9 +88,6 @@ class ConnectionBase(AnsiblePlugin):
|
|
83
88
|
if not hasattr(self, '_play_context'):
|
84
89
|
# Backwards compat: self._play_context isn't really needed, using set_options/get_option
|
85
90
|
self._play_context = play_context
|
86
|
-
# Delete once the deprecation period is over for WorkerProcess._new_stdin
|
87
|
-
if not hasattr(self, '__new_stdin'):
|
88
|
-
self.__new_stdin = new_stdin
|
89
91
|
if not hasattr(self, '_display'):
|
90
92
|
# Backwards compat: self._display isn't really needed, just import the global display and use that.
|
91
93
|
self._display = display
|
@@ -95,36 +97,25 @@ class ConnectionBase(AnsiblePlugin):
|
|
95
97
|
self._connected = False
|
96
98
|
self._socket_path: str | None = None
|
97
99
|
|
98
|
-
# helper plugins
|
99
|
-
self._shell = shell
|
100
|
-
|
101
100
|
# we always must have shell
|
102
|
-
if not
|
101
|
+
if not (shell := kwargs.get('shell')):
|
103
102
|
shell_type = play_context.shell if play_context.shell else getattr(self, '_shell_type', None)
|
104
|
-
|
103
|
+
shell = get_shell_plugin(shell_type=shell_type, executable=self._play_context.executable)
|
104
|
+
self._shell = shell
|
105
105
|
|
106
106
|
self.become: BecomeBase | None = None
|
107
107
|
|
108
|
-
@property
|
109
|
-
def _new_stdin(self) -> io.TextIOWrapper | None:
|
110
|
-
display.deprecated(
|
111
|
-
"The connection's stdin object is deprecated. "
|
112
|
-
"Call display.prompt_until(msg) instead.",
|
113
|
-
version='2.19',
|
114
|
-
)
|
115
|
-
return self.__new_stdin
|
116
|
-
|
117
108
|
def set_become_plugin(self, plugin: BecomeBase) -> None:
|
118
109
|
self.become = plugin
|
119
110
|
|
120
111
|
@property
|
121
112
|
def connected(self) -> bool:
|
122
|
-
|
113
|
+
"""Read-only property holding whether the connection to the remote host is active or closed."""
|
123
114
|
return self._connected
|
124
115
|
|
125
116
|
@property
|
126
117
|
def socket_path(self) -> str | None:
|
127
|
-
|
118
|
+
"""Read-only property holding the connection socket path for this remote host"""
|
128
119
|
return self._socket_path
|
129
120
|
|
130
121
|
@staticmethod
|
@@ -247,10 +238,10 @@ class ConnectionBase(AnsiblePlugin):
|
|
247
238
|
display.warning("Reset is not implemented for this connection")
|
248
239
|
|
249
240
|
def update_vars(self, variables: dict[str, t.Any]) -> None:
|
250
|
-
|
241
|
+
"""
|
251
242
|
Adds 'magic' variables relating to connections to the variable dictionary provided.
|
252
243
|
In case users need to access from the play, this is a legacy from runner.
|
253
|
-
|
244
|
+
"""
|
254
245
|
for varname in C.COMMON_CONNECTION_VARS:
|
255
246
|
value = None
|
256
247
|
if varname in variables:
|
@@ -296,16 +287,39 @@ class ConnectionBase(AnsiblePlugin):
|
|
296
287
|
}
|
297
288
|
for var_name in C.config.get_plugin_vars('connection', self._load_name):
|
298
289
|
if var_name in variables:
|
299
|
-
|
290
|
+
try:
|
291
|
+
var_options[var_name] = templar.template(variables[var_name])
|
292
|
+
except AnsibleValueOmittedError:
|
293
|
+
pass
|
300
294
|
|
301
295
|
# add extras if plugin supports them
|
302
296
|
if getattr(self, 'allow_extras', False):
|
303
297
|
for var_name in variables:
|
304
298
|
if var_name.startswith(f'ansible_{self.extras_prefix}_') and var_name not in var_options:
|
305
|
-
|
299
|
+
try:
|
300
|
+
var_options['_extras'][var_name] = templar.template(variables[var_name])
|
301
|
+
except AnsibleValueOmittedError:
|
302
|
+
pass
|
306
303
|
|
307
304
|
return var_options
|
308
305
|
|
306
|
+
def is_pipelining_enabled(self, wrap_async: bool = False) -> bool:
|
307
|
+
|
308
|
+
is_enabled = False
|
309
|
+
if self.has_pipelining and (not self.become or self.become.pipelining):
|
310
|
+
try:
|
311
|
+
is_enabled = self.get_option('pipelining')
|
312
|
+
except KeyError:
|
313
|
+
is_enabled = getattr(self._play_context, 'pipelining', False)
|
314
|
+
|
315
|
+
# TODO: deprecate always_pipeline_modules and has_native_async in favor for each plugin overriding this function
|
316
|
+
conditions = [
|
317
|
+
is_enabled or self.always_pipeline_modules, # enabled via config or forced via connection (eg winrm)
|
318
|
+
not C.DEFAULT_KEEP_REMOTE_FILES, # user wants remote files
|
319
|
+
not wrap_async or self.has_native_async, # async does not normally support pipelining unless it does (eg winrm)
|
320
|
+
]
|
321
|
+
return all(conditions)
|
322
|
+
|
309
323
|
|
310
324
|
class NetworkConnectionBase(ConnectionBase):
|
311
325
|
"""
|
@@ -319,11 +333,10 @@ class NetworkConnectionBase(ConnectionBase):
|
|
319
333
|
def __init__(
|
320
334
|
self,
|
321
335
|
play_context: PlayContext,
|
322
|
-
new_stdin: io.TextIOWrapper | None = None,
|
323
336
|
*args: t.Any,
|
324
337
|
**kwargs: t.Any,
|
325
338
|
) -> None:
|
326
|
-
super(NetworkConnectionBase, self).__init__(play_context,
|
339
|
+
super(NetworkConnectionBase, self).__init__(play_context, *args, **kwargs)
|
327
340
|
self._messages: list[tuple[str, str]] = []
|
328
341
|
self._conn_closed = False
|
329
342
|
|
@@ -377,9 +390,9 @@ class NetworkConnectionBase(ConnectionBase):
|
|
377
390
|
return self._local.fetch_file(in_path, out_path)
|
378
391
|
|
379
392
|
def reset(self) -> None:
|
380
|
-
|
393
|
+
"""
|
381
394
|
Reset the connection
|
382
|
-
|
395
|
+
"""
|
383
396
|
if self._socket_path:
|
384
397
|
self.queue_message('vvvv', 'resetting persistent connection for socket_path %s' % self._socket_path)
|
385
398
|
self.close()
|
@@ -411,14 +424,14 @@ class NetworkConnectionBase(ConnectionBase):
|
|
411
424
|
pass
|
412
425
|
|
413
426
|
def _update_connection_state(self) -> None:
|
414
|
-
|
427
|
+
"""
|
415
428
|
Reconstruct the connection socket_path and check if it exists
|
416
429
|
|
417
430
|
If the socket path exists then the connection is active and set
|
418
431
|
both the _socket_path value to the path and the _connected value
|
419
432
|
to True. If the socket path doesn't exist, leave the socket path
|
420
433
|
value to None and the _connected value to False
|
421
|
-
|
434
|
+
"""
|
422
435
|
ssh = connection_loader.get('ssh', class_only=True)
|
423
436
|
control_path = ssh._create_control_path(
|
424
437
|
self._play_context.remote_addr, self._play_context.port,
|