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
@@ -16,7 +16,7 @@
|
|
16
16
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
|
-
DOCUMENTATION =
|
19
|
+
DOCUMENTATION = """
|
20
20
|
name: linear
|
21
21
|
short_description: Executes tasks in a linear fashion
|
22
22
|
description:
|
@@ -27,29 +27,32 @@ DOCUMENTATION = '''
|
|
27
27
|
notes:
|
28
28
|
- This was the default Ansible behaviour before 'strategy plugins' were introduced in 2.0.
|
29
29
|
author: Ansible Core Team
|
30
|
-
|
30
|
+
"""
|
31
31
|
|
32
32
|
from ansible import constants as C
|
33
|
-
from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError
|
34
|
-
from ansible.module_utils.common.text.converters import to_text
|
33
|
+
from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError, AnsibleValueOmittedError
|
35
34
|
from ansible.playbook.handler import Handler
|
36
35
|
from ansible.playbook.included_file import IncludedFile
|
37
36
|
from ansible.plugins.loader import action_loader
|
38
37
|
from ansible.plugins.strategy import StrategyBase
|
39
|
-
from ansible.
|
38
|
+
from ansible._internal._templating._engine import TemplateEngine
|
40
39
|
from ansible.utils.display import Display
|
40
|
+
from ansible.inventory.host import Host
|
41
|
+
from ansible.playbook.task import Task
|
42
|
+
from ansible.executor.play_iterator import PlayIterator
|
41
43
|
|
42
44
|
display = Display()
|
43
45
|
|
44
46
|
|
45
47
|
class StrategyModule(StrategyBase):
|
46
48
|
|
47
|
-
def _get_next_task_lockstep(self, hosts, iterator):
|
48
|
-
|
49
|
+
def _get_next_task_lockstep(self, hosts: list[Host], iterator: PlayIterator) -> list[tuple[Host, Task]]:
|
50
|
+
"""
|
49
51
|
Returns a list of (host, task) tuples, where the task may
|
50
52
|
be a noop task to keep the iterator in lock step across
|
51
53
|
all hosts.
|
52
|
-
|
54
|
+
"""
|
55
|
+
|
53
56
|
state_task_per_host = {}
|
54
57
|
for host in hosts:
|
55
58
|
state, task = iterator.get_next_task_for_host(host, peek=True)
|
@@ -84,17 +87,17 @@ class StrategyModule(StrategyBase):
|
|
84
87
|
iterator.set_state_for_host(host.name, state)
|
85
88
|
host_tasks.append((host, task))
|
86
89
|
|
87
|
-
if cur_task.
|
90
|
+
if cur_task._get_meta() == 'flush_handlers':
|
88
91
|
iterator.all_tasks[iterator.cur_task:iterator.cur_task] = [h for b in iterator._play.handlers for h in b.block]
|
89
92
|
|
90
93
|
return host_tasks
|
91
94
|
|
92
95
|
def run(self, iterator, play_context):
|
93
|
-
|
96
|
+
"""
|
94
97
|
The linear strategy is simple - get the next task and queue
|
95
98
|
it for all hosts, then wait for the queue to drain before
|
96
99
|
moving on to the next task
|
97
|
-
|
100
|
+
"""
|
98
101
|
|
99
102
|
# iterate over each task, while there is one left to run
|
100
103
|
result = self._tqm.RUN_OK
|
@@ -130,26 +133,23 @@ class StrategyModule(StrategyBase):
|
|
130
133
|
run_once = False
|
131
134
|
work_to_do = True
|
132
135
|
|
133
|
-
|
134
|
-
# role which has already run (and whether that role allows duplicate execution)
|
135
|
-
if not isinstance(task, Handler) and task._role:
|
136
|
-
role_obj = self._get_cached_role(task, iterator._play)
|
137
|
-
if role_obj.has_run(host) and task._role._metadata.allow_duplicates is False:
|
138
|
-
display.debug("'%s' skipped because role has already run" % task)
|
139
|
-
continue
|
136
|
+
host_name = host.get_name()
|
140
137
|
|
141
138
|
display.debug("getting variables")
|
142
139
|
task_vars = self._variable_manager.get_vars(play=iterator._play, host=host, task=task,
|
143
140
|
_hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
|
144
141
|
self.add_tqm_variables(task_vars, play=iterator._play)
|
145
|
-
templar =
|
142
|
+
templar = TemplateEngine(loader=self._loader, variables=task_vars)
|
146
143
|
display.debug("done getting variables")
|
147
144
|
|
148
145
|
# test to see if the task across all hosts points to an action plugin which
|
149
146
|
# sets BYPASS_HOST_LOOP to true, or if it has run_once enabled. If so, we
|
150
147
|
# will only send this task to the first host in the list.
|
151
148
|
|
152
|
-
|
149
|
+
try:
|
150
|
+
task_action = templar.template(task.action)
|
151
|
+
except AnsibleValueOmittedError:
|
152
|
+
raise AnsibleParserError("Omit is not valid for the `action` keyword.", obj=task.action) from None
|
153
153
|
|
154
154
|
try:
|
155
155
|
action = action_loader.get(task_action, class_only=True, collection_list=task.collections)
|
@@ -162,7 +162,7 @@ class StrategyModule(StrategyBase):
|
|
162
162
|
# for the linear strategy, we run meta tasks just once and for
|
163
163
|
# all hosts currently being iterated over rather than one host
|
164
164
|
results.extend(self._execute_meta(task, play_context, iterator, host))
|
165
|
-
if task.
|
165
|
+
if task._get_meta() not in ('noop', 'reset_connection', 'end_host', 'role_complete', 'flush_handlers', 'end_role'):
|
166
166
|
run_once = True
|
167
167
|
if (task.any_errors_fatal or run_once) and not task.ignore_errors:
|
168
168
|
any_errors_fatal = True
|
@@ -176,22 +176,20 @@ class StrategyModule(StrategyBase):
|
|
176
176
|
break
|
177
177
|
|
178
178
|
run_once = action and getattr(action, 'BYPASS_HOST_LOOP', False) or templar.template(task.run_once)
|
179
|
-
try:
|
180
|
-
task.name = to_text(templar.template(task.name, fail_on_undefined=False), nonstring='empty')
|
181
|
-
except Exception as e:
|
182
|
-
display.debug(f"Failed to templalte task name ({task.name}), ignoring error and continuing: {e}")
|
183
179
|
|
184
180
|
if (task.any_errors_fatal or run_once) and not task.ignore_errors:
|
185
181
|
any_errors_fatal = True
|
186
182
|
|
187
183
|
if not callback_sent:
|
184
|
+
task.post_validate_attribute("name", templar=templar)
|
185
|
+
|
188
186
|
if isinstance(task, Handler):
|
189
187
|
self._tqm.send_callback('v2_playbook_on_handler_task_start', task)
|
190
188
|
else:
|
191
189
|
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
|
192
190
|
callback_sent = True
|
193
191
|
|
194
|
-
self._blocked_hosts[
|
192
|
+
self._blocked_hosts[host_name] = True
|
195
193
|
self._queue_task(host, task, task_vars, play_context)
|
196
194
|
del task_vars
|
197
195
|
|
@@ -283,11 +281,12 @@ class StrategyModule(StrategyBase):
|
|
283
281
|
display.debug("done iterating over new_blocks loaded from include file")
|
284
282
|
except AnsibleParserError:
|
285
283
|
raise
|
286
|
-
except AnsibleError as
|
287
|
-
|
284
|
+
except AnsibleError as ex:
|
285
|
+
# FIXME: send the error to the callback; don't directly write to display here
|
286
|
+
display.error(ex)
|
288
287
|
for r in included_file._results:
|
289
288
|
r._result['failed'] = True
|
290
|
-
r._result['reason'] = str(
|
289
|
+
r._result['reason'] = str(ex)
|
291
290
|
self._tqm._stats.increment('failures', r._host.name)
|
292
291
|
self._tqm.send_callback('v2_runner_on_failed', r)
|
293
292
|
failed_includes_hosts.add(r._host)
|
@@ -355,10 +354,9 @@ class StrategyModule(StrategyBase):
|
|
355
354
|
return result
|
356
355
|
display.debug("done checking to see if all hosts have failed")
|
357
356
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
return self._tqm.RUN_UNKNOWN_ERROR
|
357
|
+
finally:
|
358
|
+
# removed unnecessary exception handler, don't want to mis-attribute the entire code block by changing indentation
|
359
|
+
pass
|
362
360
|
|
363
361
|
# run the base class run() method, which executes the cleanup function
|
364
362
|
# and runs any outstanding handlers which have been triggered
|
@@ -26,7 +26,7 @@ from ansible.errors import AnsibleConnectionFailure
|
|
26
26
|
|
27
27
|
|
28
28
|
class TerminalBase(ABC):
|
29
|
-
|
29
|
+
"""
|
30
30
|
A base class for implementing cli connections
|
31
31
|
|
32
32
|
.. note:: Unlike most of Ansible, nearly all strings in
|
@@ -36,7 +36,7 @@ class TerminalBase(ABC):
|
|
36
36
|
:func:`~ansible.module_utils.common.text.converters.to_bytes` and
|
37
37
|
:func:`~ansible.module_utils.common.text.converters.to_text` to avoid unexpected
|
38
38
|
problems.
|
39
|
-
|
39
|
+
"""
|
40
40
|
|
41
41
|
#: compiled bytes regular expressions as stdout
|
42
42
|
terminal_stdout_re = [] # type: list[re.Pattern]
|
@@ -64,11 +64,11 @@ class TerminalBase(ABC):
|
|
64
64
|
self._connection = connection
|
65
65
|
|
66
66
|
def _exec_cli_command(self, cmd, check_rc=True):
|
67
|
-
|
67
|
+
"""
|
68
68
|
Executes the CLI command on the remote device and returns the output
|
69
69
|
|
70
70
|
:arg cmd: Byte string command to be executed
|
71
|
-
|
71
|
+
"""
|
72
72
|
return self._connection.exec_command(cmd)
|
73
73
|
|
74
74
|
def _get_prompt(self):
|
ansible/plugins/test/__init__.py
CHANGED
@@ -3,10 +3,15 @@
|
|
3
3
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
+
import typing as t
|
7
|
+
|
6
8
|
from ansible.plugins import AnsibleJinja2Plugin
|
7
9
|
|
8
10
|
|
9
11
|
class AnsibleJinja2Test(AnsibleJinja2Plugin):
|
12
|
+
@property
|
13
|
+
def plugin_type(self) -> str:
|
14
|
+
return "test"
|
10
15
|
|
11
|
-
def _no_options(self, *args, **kwargs):
|
12
|
-
raise NotImplementedError("
|
16
|
+
def _no_options(self, *args, **kwargs) -> t.NoReturn:
|
17
|
+
raise NotImplementedError("Jinja2 test plugins do not support option functions, they use direct arguments instead.")
|
ansible/plugins/test/core.py
CHANGED
@@ -17,17 +17,22 @@
|
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
|
+
import functools
|
20
21
|
import re
|
21
22
|
import operator as py_operator
|
22
23
|
|
23
24
|
from collections.abc import MutableMapping, MutableSequence
|
24
25
|
|
26
|
+
from jinja2.tests import test_defined, test_undefined
|
27
|
+
|
25
28
|
from ansible.module_utils.compat.version import LooseVersion, StrictVersion
|
26
29
|
|
27
30
|
from ansible import errors
|
28
31
|
from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
|
32
|
+
from ansible._internal._templating._jinja_common import Marker, UndefinedMarker
|
29
33
|
from ansible.module_utils.parsing.convert_bool import boolean
|
30
|
-
from ansible.
|
34
|
+
from ansible.plugins import accept_args_markers
|
35
|
+
from ansible.parsing.vault import is_encrypted_file, VaultHelper, VaultLib
|
31
36
|
from ansible.utils.display import Display
|
32
37
|
from ansible.utils.version import SemanticVersion
|
33
38
|
|
@@ -41,38 +46,38 @@ display = Display()
|
|
41
46
|
|
42
47
|
|
43
48
|
def timedout(result):
|
44
|
-
|
49
|
+
""" Test if task result yields a time out"""
|
45
50
|
if not isinstance(result, MutableMapping):
|
46
51
|
raise errors.AnsibleFilterError("The 'timedout' test expects a dictionary")
|
47
52
|
return result.get('timedout', False) and result['timedout'].get('period', False)
|
48
53
|
|
49
54
|
|
50
55
|
def failed(result):
|
51
|
-
|
56
|
+
""" Test if task result yields failed """
|
52
57
|
if not isinstance(result, MutableMapping):
|
53
58
|
raise errors.AnsibleFilterError("The 'failed' test expects a dictionary")
|
54
59
|
return result.get('failed', False)
|
55
60
|
|
56
61
|
|
57
62
|
def success(result):
|
58
|
-
|
63
|
+
""" Test if task result yields success """
|
59
64
|
return not failed(result)
|
60
65
|
|
61
66
|
|
62
67
|
def unreachable(result):
|
63
|
-
|
68
|
+
""" Test if task result yields unreachable """
|
64
69
|
if not isinstance(result, MutableMapping):
|
65
70
|
raise errors.AnsibleFilterError("The 'unreachable' test expects a dictionary")
|
66
71
|
return result.get('unreachable', False)
|
67
72
|
|
68
73
|
|
69
74
|
def reachable(result):
|
70
|
-
|
75
|
+
""" Test if task result yields reachable """
|
71
76
|
return not unreachable(result)
|
72
77
|
|
73
78
|
|
74
79
|
def changed(result):
|
75
|
-
|
80
|
+
""" Test if task result yields changed """
|
76
81
|
if not isinstance(result, MutableMapping):
|
77
82
|
raise errors.AnsibleFilterError("The 'changed' test expects a dictionary")
|
78
83
|
if 'changed' not in result:
|
@@ -92,14 +97,14 @@ def changed(result):
|
|
92
97
|
|
93
98
|
|
94
99
|
def skipped(result):
|
95
|
-
|
100
|
+
""" Test if task result yields skipped """
|
96
101
|
if not isinstance(result, MutableMapping):
|
97
102
|
raise errors.AnsibleFilterError("The 'skipped' test expects a dictionary")
|
98
103
|
return result.get('skipped', False)
|
99
104
|
|
100
105
|
|
101
106
|
def started(result):
|
102
|
-
|
107
|
+
""" Test if async task has started """
|
103
108
|
if not isinstance(result, MutableMapping):
|
104
109
|
raise errors.AnsibleFilterError("The 'started' test expects a dictionary")
|
105
110
|
if 'started' in result:
|
@@ -113,7 +118,7 @@ def started(result):
|
|
113
118
|
|
114
119
|
|
115
120
|
def finished(result):
|
116
|
-
|
121
|
+
""" Test if async task has finished """
|
117
122
|
if not isinstance(result, MutableMapping):
|
118
123
|
raise errors.AnsibleFilterError("The 'finished' test expects a dictionary")
|
119
124
|
if 'finished' in result:
|
@@ -127,12 +132,10 @@ def finished(result):
|
|
127
132
|
|
128
133
|
|
129
134
|
def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='search'):
|
130
|
-
|
135
|
+
""" Expose `re` as a boolean filter using the `search` method by default.
|
131
136
|
This is likely only useful for `search` and `match` which already
|
132
137
|
have their own filters.
|
133
|
-
|
134
|
-
# In addition to ensuring the correct type, to_text here will ensure
|
135
|
-
# _fail_with_undefined_error happens if the value is Undefined
|
138
|
+
"""
|
136
139
|
value = to_text(value, errors='surrogate_or_strict')
|
137
140
|
flags = 0
|
138
141
|
if ignorecase:
|
@@ -143,12 +146,19 @@ def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='s
|
|
143
146
|
return bool(getattr(_re, match_type, 'search')(value))
|
144
147
|
|
145
148
|
|
146
|
-
|
149
|
+
@accept_args_markers
|
150
|
+
def vault_encrypted(value: object) -> bool:
|
147
151
|
"""Evaluate whether a variable is a single vault encrypted value
|
148
152
|
|
149
153
|
.. versionadded:: 2.10
|
150
154
|
"""
|
151
|
-
|
155
|
+
if ciphertext := VaultHelper.get_ciphertext(value, with_tags=False):
|
156
|
+
return VaultLib.is_encrypted(ciphertext)
|
157
|
+
|
158
|
+
if isinstance(value, Marker):
|
159
|
+
value.trip()
|
160
|
+
|
161
|
+
return False
|
152
162
|
|
153
163
|
|
154
164
|
def vaulted_file(value):
|
@@ -164,17 +174,17 @@ def vaulted_file(value):
|
|
164
174
|
|
165
175
|
|
166
176
|
def match(value, pattern='', ignorecase=False, multiline=False):
|
167
|
-
|
177
|
+
""" Perform a `re.match` returning a boolean """
|
168
178
|
return regex(value, pattern, ignorecase, multiline, 'match')
|
169
179
|
|
170
180
|
|
171
181
|
def search(value, pattern='', ignorecase=False, multiline=False):
|
172
|
-
|
182
|
+
""" Perform a `re.search` returning a boolean """
|
173
183
|
return regex(value, pattern, ignorecase, multiline, 'search')
|
174
184
|
|
175
185
|
|
176
186
|
def version_compare(value, version, operator='eq', strict=None, version_type=None):
|
177
|
-
|
187
|
+
""" Perform a version comparison on a value """
|
178
188
|
op_map = {
|
179
189
|
'==': 'eq', '=': 'eq', 'eq': 'eq',
|
180
190
|
'<': 'lt', 'lt': 'lt',
|
@@ -257,8 +267,28 @@ def falsy(value, convert_bool=False):
|
|
257
267
|
return not truthy(value, convert_bool=convert_bool)
|
258
268
|
|
259
269
|
|
270
|
+
@accept_args_markers
|
271
|
+
@functools.wraps(test_defined)
|
272
|
+
def wrapped_test_defined(value: object) -> Marker | bool:
|
273
|
+
"""Wrapper around Jinja's `defined` test to avoid mutating the externally-owned function with our marker attribute."""
|
274
|
+
if isinstance(value, Marker) and not isinstance(value, UndefinedMarker):
|
275
|
+
return value
|
276
|
+
|
277
|
+
return test_defined(value)
|
278
|
+
|
279
|
+
|
280
|
+
@accept_args_markers
|
281
|
+
@functools.wraps(test_undefined)
|
282
|
+
def wrapped_test_undefined(value: object) -> Marker | bool:
|
283
|
+
"""Wrapper around Jinja's `undefined` test to avoid mutating the externally-owned function with our marker attribute."""
|
284
|
+
if isinstance(value, Marker) and not isinstance(value, UndefinedMarker):
|
285
|
+
return value
|
286
|
+
|
287
|
+
return test_undefined(value)
|
288
|
+
|
289
|
+
|
260
290
|
class TestModule(object):
|
261
|
-
|
291
|
+
""" Ansible core jinja2 tests """
|
262
292
|
|
263
293
|
def tests(self):
|
264
294
|
return {
|
@@ -304,4 +334,8 @@ class TestModule(object):
|
|
304
334
|
# vault
|
305
335
|
'vault_encrypted': vault_encrypted,
|
306
336
|
'vaulted_file': vaulted_file,
|
337
|
+
|
338
|
+
# overrides that require special arg handling
|
339
|
+
'defined': wrapped_test_defined,
|
340
|
+
'undefined': wrapped_test_undefined,
|
307
341
|
}
|
ansible/plugins/test/files.py
CHANGED
@@ -36,15 +36,15 @@ def isnotanumber(x):
|
|
36
36
|
|
37
37
|
|
38
38
|
def contains(seq, value):
|
39
|
-
|
39
|
+
"""Opposite of the ``in`` test, allowing use as a test in filters like ``selectattr``
|
40
40
|
|
41
41
|
.. versionadded:: 2.8
|
42
|
-
|
42
|
+
"""
|
43
43
|
return value in seq
|
44
44
|
|
45
45
|
|
46
46
|
class TestModule:
|
47
|
-
|
47
|
+
""" Ansible math jinja2 tests """
|
48
48
|
|
49
49
|
def tests(self):
|
50
50
|
return {
|
ansible/plugins/test/uri.py
CHANGED
@@ -6,7 +6,7 @@ from urllib.parse import urlparse
|
|
6
6
|
|
7
7
|
|
8
8
|
def is_uri(value, schemes=None):
|
9
|
-
|
9
|
+
""" Will verify that the string passed is a valid 'URI', if given a list of valid schemes it will match those """
|
10
10
|
try:
|
11
11
|
x = urlparse(value)
|
12
12
|
isit = all([x.scheme is not None, x.path is not None, not schemes or x.scheme in schemes])
|
@@ -16,7 +16,7 @@ def is_uri(value, schemes=None):
|
|
16
16
|
|
17
17
|
|
18
18
|
def is_url(value, schemes=None):
|
19
|
-
|
19
|
+
""" Will verify that the string passed is a valid 'URL' """
|
20
20
|
|
21
21
|
isit = is_uri(value, schemes)
|
22
22
|
if isit:
|
@@ -33,7 +33,7 @@ def is_urn(value):
|
|
33
33
|
|
34
34
|
|
35
35
|
class TestModule(object):
|
36
|
-
|
36
|
+
""" Ansible URI jinja2 test """
|
37
37
|
|
38
38
|
def tests(self):
|
39
39
|
return {
|
@@ -17,7 +17,7 @@
|
|
17
17
|
#############################################
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
|
-
DOCUMENTATION =
|
20
|
+
DOCUMENTATION = """
|
21
21
|
name: host_group_vars
|
22
22
|
version_added: "2.4"
|
23
23
|
short_description: In charge of loading group_vars and host_vars
|
@@ -50,7 +50,7 @@ DOCUMENTATION = '''
|
|
50
50
|
elements: string
|
51
51
|
extends_documentation_fragment:
|
52
52
|
- vars_plugin_staging
|
53
|
-
|
53
|
+
"""
|
54
54
|
|
55
55
|
import os
|
56
56
|
from ansible.errors import AnsibleParserError
|
@@ -63,7 +63,6 @@ from ansible.utils.vars import combine_vars
|
|
63
63
|
CANONICAL_PATHS = {} # type: dict[str, str]
|
64
64
|
FOUND = {} # type: dict[str, list[str]]
|
65
65
|
NAK = set() # type: set[str]
|
66
|
-
PATH_CACHE = {} # type: dict[tuple[str, str], str]
|
67
66
|
|
68
67
|
|
69
68
|
class VarsModule(BaseVarsPlugin):
|
@@ -73,13 +72,13 @@ class VarsModule(BaseVarsPlugin):
|
|
73
72
|
|
74
73
|
def load_found_files(self, loader, data, found_files):
|
75
74
|
for found in found_files:
|
76
|
-
new_data = loader.load_from_file(found, cache='all', unsafe=True)
|
75
|
+
new_data = loader.load_from_file(found, cache='all', unsafe=True, trusted_as_template=True)
|
77
76
|
if new_data: # ignore empty files
|
78
77
|
data = combine_vars(data, new_data)
|
79
78
|
return data
|
80
79
|
|
81
80
|
def get_vars(self, loader, path, entities, cache=True):
|
82
|
-
|
81
|
+
""" parses the inventory file """
|
83
82
|
|
84
83
|
if not isinstance(entities, list):
|
85
84
|
entities = [entities]
|
@@ -119,21 +118,15 @@ class VarsModule(BaseVarsPlugin):
|
|
119
118
|
else:
|
120
119
|
raise AnsibleParserError("Supplied entity must be Host or Group, got %s instead" % (type(entity)))
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
opath = PATH_CACHE[(realpath_basedir, subdir)]
|
125
|
-
except KeyError:
|
126
|
-
opath = PATH_CACHE[(realpath_basedir, subdir)] = os.path.join(realpath_basedir, subdir)
|
121
|
+
opath = os.path.join(realpath_basedir, subdir)
|
122
|
+
key = '%s.%s' % (entity_name, opath)
|
127
123
|
|
124
|
+
if cache:
|
128
125
|
if opath in NAK:
|
129
126
|
continue
|
130
|
-
key = '%s.%s' % (entity_name, opath)
|
131
127
|
if key in FOUND:
|
132
128
|
data = self.load_found_files(loader, data, FOUND[key])
|
133
129
|
continue
|
134
|
-
else:
|
135
|
-
opath = PATH_CACHE[(realpath_basedir, subdir)] = os.path.join(realpath_basedir, subdir)
|
136
|
-
|
137
130
|
if os.path.isdir(opath):
|
138
131
|
self._display.debug("\tprocessing dir %s" % opath)
|
139
132
|
FOUND[key] = found_files = loader.find_vars_files(opath, entity_name)
|
ansible/release.py
CHANGED