ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz/__init__.py +0 -0
- ansible/_internal/_ansiballz/_builder.py +101 -0
- ansible/_internal/_ansiballz/_wrapper.py +262 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_alarm_timeout.py +66 -0
- ansible/_internal/_errors/_captured.py +123 -0
- ansible/_internal/_errors/_error_factory.py +89 -0
- ansible/_internal/_errors/_error_utils.py +240 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_task_timeout.py +28 -0
- ansible/_internal/_event_formatting.py +127 -0
- ansible/_internal/_json/__init__.py +214 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +189 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_ssh/__init__.py +0 -0
- ansible/_internal/_ssh/_agent_launch.py +91 -0
- ansible/_internal/_ssh/_ssh_agent.py +619 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +12 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +592 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1106 -0
- ansible/_internal/_templating/_jinja_common.py +323 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +375 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_template_vars.py +72 -0
- ansible/_internal/_templating/_transform.py +70 -0
- ansible/_internal/_templating/_utils.py +108 -0
- ansible/_internal/_testing.py +26 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +70 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +93 -104
- ansible/cli/_ssh_askpass.py +54 -0
- ansible/cli/adhoc.py +20 -10
- ansible/cli/arguments/option_helpers.py +163 -10
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +13 -11
- ansible/cli/doc.py +134 -77
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -28
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +6 -3
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/compat/importlib_resources.py +9 -12
- ansible/config/base.yml +218 -133
- ansible/config/manager.py +220 -159
- ansible/constants.py +2 -65
- ansible/errors/__init__.py +350 -256
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +480 -514
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +204 -153
- ansible/executor/powershell/become_wrapper.ps1 +107 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
- ansible/executor/powershell/exec_wrapper.ps1 +675 -196
- ansible/executor/powershell/module_manifest.py +469 -265
- ansible/executor/powershell/module_wrapper.ps1 +195 -186
- ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
- ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +139 -149
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +270 -297
- ansible/executor/task_queue_manager.py +135 -137
- ansible/executor/task_result.py +182 -79
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +26 -25
- ansible/galaxy/collection/__init__.py +6 -14
- ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +4 -4
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +6 -10
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +50 -73
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +37 -54
- ansible/inventory/manager.py +79 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
- ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
- ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
- ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +961 -0
- ansible/module_utils/_internal/_datatag/_tags.py +16 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_deprecator.py +157 -0
- ansible/module_utils/_internal/_errors.py +101 -0
- ansible/module_utils/_internal/_event_utils.py +61 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
- ansible/module_utils/_internal/_messages.py +130 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_info.py +38 -0
- ansible/module_utils/_internal/_stack.py +22 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_text_utils.py +6 -0
- ansible/module_utils/_internal/_traceback.py +92 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +303 -202
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/collections.py +7 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -3
- ansible/module_utils/common/respawn.py +11 -33
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +143 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +10 -13
- ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +49 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +2 -2
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +5 -5
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +2 -3
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/sysctl.py +4 -6
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +3 -3
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +27 -13
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +2 -3
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/linux.py +3 -3
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +7 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/service.py +21 -31
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +64 -35
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +69 -49
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +32 -51
- ansible/modules/assemble.py +16 -14
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +24 -24
- ansible/modules/async_wrapper.py +20 -25
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +13 -20
- ansible/modules/copy.py +60 -147
- ansible/modules/cron.py +24 -21
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +13 -15
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +184 -144
- ansible/modules/find.py +22 -20
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +77 -54
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +38 -38
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +15 -32
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +22 -24
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +10 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +21 -26
- ansible/modules/raw.py +6 -6
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +10 -14
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +10 -17
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +16 -19
- ansible/modules/stat.py +15 -31
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +7 -7
- ansible/modules/systemd_service.py +7 -7
- ansible/modules/sysvinit.py +9 -9
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +38 -17
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +45 -32
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +70 -60
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +10 -9
- ansible/parsing/ajson.py +17 -37
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +62 -60
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +327 -99
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +187 -134
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +32 -26
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +14 -17
- ansible/playbook/playbook_include.py +27 -62
- ansible/playbook/role/__init__.py +64 -49
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +28 -12
- ansible/playbook/task.py +192 -121
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +58 -26
- ansible/plugins/action/__init__.py +188 -186
- ansible/plugins/action/add_host.py +2 -2
- ansible/plugins/action/assemble.py +11 -18
- ansible/plugins/action/assert.py +55 -67
- ansible/plugins/action/async_status.py +7 -2
- ansible/plugins/action/copy.py +14 -17
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +7 -8
- ansible/plugins/action/gather_facts.py +13 -14
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +8 -14
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +27 -38
- ansible/plugins/action/service.py +9 -18
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +47 -67
- ansible/plugins/action/unarchive.py +6 -16
- ansible/plugins/action/uri.py +9 -20
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +52 -63
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +294 -201
- ansible/plugins/callback/default.py +99 -95
- ansible/plugins/callback/junit.py +44 -43
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +34 -21
- ansible/plugins/callback/tree.py +27 -16
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +156 -60
- ansible/plugins/connection/paramiko_ssh.py +34 -24
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +326 -86
- ansible/plugins/connection/winrm.py +62 -141
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +8 -4
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +245 -120
- ansible/plugins/filter/encryption.py +42 -34
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/pow.yml +1 -1
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/strftime.yml +3 -3
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +107 -86
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +190 -120
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +72 -19
- ansible/plugins/loader.py +383 -198
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +19 -73
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +87 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +47 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +4 -10
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +58 -4
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +106 -31
- ansible/plugins/shell/sh.py +13 -7
- ansible/plugins/strategy/__init__.py +168 -193
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +75 -35
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/finished.yml +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +5 -8
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +353 -943
- ansible/utils/__init__.py +0 -18
- ansible/utils/collection_loader/__init__.py +54 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +82 -96
- ansible/utils/collection_loader/_collection_meta.py +15 -8
- ansible/utils/display.py +485 -73
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/galaxy.py +2 -2
- ansible/utils/hashing.py +8 -10
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +10 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +10 -12
- ansible/utils/plugin_docs.py +16 -14
- ansible/utils/py3compat.py +2 -7
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +6 -2
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +55 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +220 -285
- ansible/vars/plugins.py +4 -4
- ansible/vars/reserved.py +13 -12
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
- ansible_core-2.19.0.dist-info/RECORD +1097 -0
- ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +6 -0
- ansible_test/_internal/ansible_util.py +3 -1
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -5
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +52 -5
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +3 -2
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +22 -5
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +8 -2
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +19 -2
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +25 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +44 -4
- ansible_test/_internal/commands/units/__init__.py +5 -1
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +23 -13
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/debugging.py +166 -0
- ansible_test/_internal/delegation.py +22 -13
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +260 -16
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +39 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +95 -4
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/processes.py +80 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +11 -4
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +28 -0
- ansible_test/_internal/ssh.py +2 -5
- ansible_test/_internal/target.py +9 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +3 -1
- ansible_test/_internal/timeout.py +2 -1
- ansible_test/_internal/util.py +41 -12
- ansible_test/_internal/util_common.py +18 -5
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/injector/python.py +8 -0
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +38 -36
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
DOCUMENTATION =
|
|
17
|
+
DOCUMENTATION = """
|
|
18
18
|
name: debug
|
|
19
19
|
short_description: Executes tasks in interactive debug session.
|
|
20
20
|
description:
|
|
21
21
|
- Task execution is 'linear' but controlled by an interactive debug session.
|
|
22
22
|
version_added: "2.1"
|
|
23
23
|
author: Kishin Yagami (!UNKNOWN)
|
|
24
|
-
|
|
24
|
+
"""
|
|
25
25
|
|
|
26
26
|
from ansible.plugins.strategy.linear import StrategyModule as LinearStrategyModule
|
|
27
27
|
|
ansible/plugins/strategy/free.py
CHANGED
|
@@ -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: free
|
|
21
21
|
short_description: Executes tasks without waiting for all hosts
|
|
22
22
|
description:
|
|
@@ -27,7 +27,7 @@ DOCUMENTATION = '''
|
|
|
27
27
|
won't hold up the rest of the hosts and tasks.
|
|
28
28
|
version_added: "2.0"
|
|
29
29
|
author: Ansible Core Team
|
|
30
|
-
|
|
30
|
+
"""
|
|
31
31
|
|
|
32
32
|
import time
|
|
33
33
|
|
|
@@ -37,8 +37,7 @@ from ansible.playbook.handler import Handler
|
|
|
37
37
|
from ansible.playbook.included_file import IncludedFile
|
|
38
38
|
from ansible.plugins.loader import action_loader
|
|
39
39
|
from ansible.plugins.strategy import StrategyBase
|
|
40
|
-
from ansible.
|
|
41
|
-
from ansible.module_utils.common.text.converters import to_text
|
|
40
|
+
from ansible._internal._templating._engine import TemplateEngine
|
|
42
41
|
from ansible.utils.display import Display
|
|
43
42
|
|
|
44
43
|
display = Display()
|
|
@@ -54,7 +53,7 @@ class StrategyModule(StrategyBase):
|
|
|
54
53
|
self._host_pinned = False
|
|
55
54
|
|
|
56
55
|
def run(self, iterator, play_context):
|
|
57
|
-
|
|
56
|
+
"""
|
|
58
57
|
The "free" strategy is a bit more complex, in that it allows tasks to
|
|
59
58
|
be sent to hosts as quickly as they can be processed. This means that
|
|
60
59
|
some hosts may finish very quickly if run tasks result in little or no
|
|
@@ -65,7 +64,7 @@ class StrategyModule(StrategyBase):
|
|
|
65
64
|
and starting the search from there as opposed to the top of the hosts
|
|
66
65
|
list again, which would end up favoring hosts near the beginning of the
|
|
67
66
|
list.
|
|
68
|
-
|
|
67
|
+
"""
|
|
69
68
|
|
|
70
69
|
# the last host to be given a task
|
|
71
70
|
last_host = 0
|
|
@@ -124,13 +123,13 @@ class StrategyModule(StrategyBase):
|
|
|
124
123
|
_hosts=self._hosts_cache,
|
|
125
124
|
_hosts_all=self._hosts_cache_all)
|
|
126
125
|
self.add_tqm_variables(task_vars, play=iterator._play)
|
|
127
|
-
templar =
|
|
126
|
+
templar = TemplateEngine(loader=self._loader, variables=task_vars)
|
|
128
127
|
display.debug("done getting variables", host=host_name)
|
|
129
128
|
|
|
130
129
|
try:
|
|
131
130
|
throttle = int(templar.template(task.throttle))
|
|
132
|
-
except Exception as
|
|
133
|
-
raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task.
|
|
131
|
+
except Exception as ex:
|
|
132
|
+
raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task.throttle) from ex
|
|
134
133
|
|
|
135
134
|
if throttle > 0:
|
|
136
135
|
same_tasks = 0
|
|
@@ -155,13 +154,7 @@ class StrategyModule(StrategyBase):
|
|
|
155
154
|
# corresponding action plugin
|
|
156
155
|
action = None
|
|
157
156
|
|
|
158
|
-
|
|
159
|
-
task.name = to_text(templar.template(task.name, fail_on_undefined=False), nonstring='empty')
|
|
160
|
-
display.debug("done templating", host=host_name)
|
|
161
|
-
except Exception:
|
|
162
|
-
# just ignore any errors during task name templating,
|
|
163
|
-
# we don't care if it just shows the raw name
|
|
164
|
-
display.debug("templating failed for some reason", host=host_name)
|
|
157
|
+
task.post_validate_attribute("name", templar=templar)
|
|
165
158
|
|
|
166
159
|
run_once = templar.template(task.run_once) or action and getattr(action, 'BYPASS_HOST_LOOP', False)
|
|
167
160
|
if run_once:
|
|
@@ -172,15 +165,6 @@ class StrategyModule(StrategyBase):
|
|
|
172
165
|
display.warning("Using run_once with the free strategy is not currently supported. This task will still be "
|
|
173
166
|
"executed for every host in the inventory list.")
|
|
174
167
|
|
|
175
|
-
# check to see if this task should be skipped, due to it being a member of a
|
|
176
|
-
# role which has already run (and whether that role allows duplicate execution)
|
|
177
|
-
if not isinstance(task, Handler) and task._role:
|
|
178
|
-
role_obj = self._get_cached_role(task, iterator._play)
|
|
179
|
-
if role_obj.has_run(host) and task._role._metadata.allow_duplicates is False:
|
|
180
|
-
display.debug("'%s' skipped because role has already run" % task, host=host_name)
|
|
181
|
-
del self._blocked_hosts[host_name]
|
|
182
|
-
continue
|
|
183
|
-
|
|
184
168
|
if task.action in C._ACTION_META:
|
|
185
169
|
if self._host_pinned:
|
|
186
170
|
meta_task_dummy_results_count += 1
|
|
@@ -264,14 +248,15 @@ class StrategyModule(StrategyBase):
|
|
|
264
248
|
iterator.handlers = [h for b in iterator._play.handlers for h in b.block]
|
|
265
249
|
except AnsibleParserError:
|
|
266
250
|
raise
|
|
267
|
-
except AnsibleError as
|
|
268
|
-
|
|
251
|
+
except AnsibleError as ex:
|
|
252
|
+
# FIXME: send the error to the callback; don't directly write to display here
|
|
253
|
+
display.error(ex)
|
|
269
254
|
for r in included_file._results:
|
|
270
|
-
r.
|
|
271
|
-
r.
|
|
272
|
-
self._tqm._stats.increment('failures', r.
|
|
255
|
+
r._return_data['failed'] = True
|
|
256
|
+
r._return_data['reason'] = str(ex)
|
|
257
|
+
self._tqm._stats.increment('failures', r.host.name)
|
|
273
258
|
self._tqm.send_callback('v2_runner_on_failed', r)
|
|
274
|
-
failed_includes_hosts.add(r.
|
|
259
|
+
failed_includes_hosts.add(r.host)
|
|
275
260
|
continue
|
|
276
261
|
else:
|
|
277
262
|
# since we skip incrementing the stats when the task result is
|
|
@@ -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: host_pinned
|
|
21
21
|
short_description: Executes tasks on each host without interruption
|
|
22
22
|
description:
|
|
@@ -28,7 +28,7 @@ DOCUMENTATION = '''
|
|
|
28
28
|
Other than that, it behaves just like the "free" strategy.
|
|
29
29
|
version_added: "2.7"
|
|
30
30
|
author: Ansible Core Team
|
|
31
|
-
|
|
31
|
+
"""
|
|
32
32
|
|
|
33
33
|
from ansible.plugins.strategy.free import StrategyModule as FreeStrategyModule
|
|
34
34
|
from ansible.utils.display import Display
|
|
@@ -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,34 @@ 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
|
|
43
|
+
from ansible.playbook.play_context import PlayContext
|
|
44
|
+
from ansible.executor import task_result as _task_result
|
|
41
45
|
|
|
42
46
|
display = Display()
|
|
43
47
|
|
|
44
48
|
|
|
45
49
|
class StrategyModule(StrategyBase):
|
|
46
50
|
|
|
47
|
-
def _get_next_task_lockstep(self, hosts, iterator):
|
|
48
|
-
|
|
51
|
+
def _get_next_task_lockstep(self, hosts: list[Host], iterator: PlayIterator) -> list[tuple[Host, Task]]:
|
|
52
|
+
"""
|
|
49
53
|
Returns a list of (host, task) tuples, where the task may
|
|
50
54
|
be a noop task to keep the iterator in lock step across
|
|
51
55
|
all hosts.
|
|
52
|
-
|
|
56
|
+
"""
|
|
57
|
+
|
|
53
58
|
state_task_per_host = {}
|
|
54
59
|
for host in hosts:
|
|
55
60
|
state, task = iterator.get_next_task_for_host(host, peek=True)
|
|
@@ -84,20 +89,20 @@ class StrategyModule(StrategyBase):
|
|
|
84
89
|
iterator.set_state_for_host(host.name, state)
|
|
85
90
|
host_tasks.append((host, task))
|
|
86
91
|
|
|
87
|
-
if cur_task.
|
|
92
|
+
if cur_task._get_meta() == 'flush_handlers':
|
|
88
93
|
iterator.all_tasks[iterator.cur_task:iterator.cur_task] = [h for b in iterator._play.handlers for h in b.block]
|
|
89
94
|
|
|
90
95
|
return host_tasks
|
|
91
96
|
|
|
92
|
-
def run(self, iterator, play_context):
|
|
93
|
-
|
|
97
|
+
def run(self, iterator, play_context: PlayContext): # type: ignore[override]
|
|
98
|
+
"""
|
|
94
99
|
The linear strategy is simple - get the next task and queue
|
|
95
100
|
it for all hosts, then wait for the queue to drain before
|
|
96
101
|
moving on to the next task
|
|
97
|
-
|
|
102
|
+
"""
|
|
98
103
|
|
|
99
104
|
# iterate over each task, while there is one left to run
|
|
100
|
-
result = self._tqm.RUN_OK
|
|
105
|
+
result = int(self._tqm.RUN_OK)
|
|
101
106
|
work_to_do = True
|
|
102
107
|
|
|
103
108
|
self._set_hosts_cache(iterator._play)
|
|
@@ -122,7 +127,7 @@ class StrategyModule(StrategyBase):
|
|
|
122
127
|
# flag set if task is set to any_errors_fatal
|
|
123
128
|
any_errors_fatal = False
|
|
124
129
|
|
|
125
|
-
results = []
|
|
130
|
+
results: list[_task_result._RawTaskResult] = []
|
|
126
131
|
for (host, task) in host_tasks:
|
|
127
132
|
if self._tqm._terminated:
|
|
128
133
|
break
|
|
@@ -130,26 +135,23 @@ class StrategyModule(StrategyBase):
|
|
|
130
135
|
run_once = False
|
|
131
136
|
work_to_do = True
|
|
132
137
|
|
|
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
|
|
138
|
+
host_name = host.get_name()
|
|
140
139
|
|
|
141
140
|
display.debug("getting variables")
|
|
142
141
|
task_vars = self._variable_manager.get_vars(play=iterator._play, host=host, task=task,
|
|
143
142
|
_hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
|
|
144
143
|
self.add_tqm_variables(task_vars, play=iterator._play)
|
|
145
|
-
templar =
|
|
144
|
+
templar = TemplateEngine(loader=self._loader, variables=task_vars)
|
|
146
145
|
display.debug("done getting variables")
|
|
147
146
|
|
|
148
147
|
# test to see if the task across all hosts points to an action plugin which
|
|
149
148
|
# sets BYPASS_HOST_LOOP to true, or if it has run_once enabled. If so, we
|
|
150
149
|
# will only send this task to the first host in the list.
|
|
151
150
|
|
|
152
|
-
|
|
151
|
+
try:
|
|
152
|
+
task_action = templar.template(task.action)
|
|
153
|
+
except AnsibleValueOmittedError:
|
|
154
|
+
raise AnsibleParserError("Omit is not valid for the `action` keyword.", obj=task.action) from None
|
|
153
155
|
|
|
154
156
|
try:
|
|
155
157
|
action = action_loader.get(task_action, class_only=True, collection_list=task.collections)
|
|
@@ -162,7 +164,7 @@ class StrategyModule(StrategyBase):
|
|
|
162
164
|
# for the linear strategy, we run meta tasks just once and for
|
|
163
165
|
# all hosts currently being iterated over rather than one host
|
|
164
166
|
results.extend(self._execute_meta(task, play_context, iterator, host))
|
|
165
|
-
if task.
|
|
167
|
+
if task._get_meta() not in ('noop', 'reset_connection', 'end_host', 'role_complete', 'flush_handlers', 'end_role'):
|
|
166
168
|
run_once = True
|
|
167
169
|
if (task.any_errors_fatal or run_once) and not task.ignore_errors:
|
|
168
170
|
any_errors_fatal = True
|
|
@@ -176,22 +178,20 @@ class StrategyModule(StrategyBase):
|
|
|
176
178
|
break
|
|
177
179
|
|
|
178
180
|
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
181
|
|
|
184
182
|
if (task.any_errors_fatal or run_once) and not task.ignore_errors:
|
|
185
183
|
any_errors_fatal = True
|
|
186
184
|
|
|
187
185
|
if not callback_sent:
|
|
186
|
+
task.post_validate_attribute("name", templar=templar)
|
|
187
|
+
|
|
188
188
|
if isinstance(task, Handler):
|
|
189
189
|
self._tqm.send_callback('v2_playbook_on_handler_task_start', task)
|
|
190
190
|
else:
|
|
191
191
|
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
|
|
192
192
|
callback_sent = True
|
|
193
193
|
|
|
194
|
-
self._blocked_hosts[
|
|
194
|
+
self._blocked_hosts[host_name] = True
|
|
195
195
|
self._queue_task(host, task, task_vars, play_context)
|
|
196
196
|
del task_vars
|
|
197
197
|
|
|
@@ -283,14 +283,15 @@ class StrategyModule(StrategyBase):
|
|
|
283
283
|
display.debug("done iterating over new_blocks loaded from include file")
|
|
284
284
|
except AnsibleParserError:
|
|
285
285
|
raise
|
|
286
|
-
except AnsibleError as
|
|
287
|
-
|
|
286
|
+
except AnsibleError as ex:
|
|
287
|
+
# FIXME: send the error to the callback; don't directly write to display here
|
|
288
|
+
display.error(ex)
|
|
288
289
|
for r in included_file._results:
|
|
289
|
-
r.
|
|
290
|
-
r.
|
|
291
|
-
self._tqm._stats.increment('failures', r.
|
|
290
|
+
r._return_data['failed'] = True
|
|
291
|
+
r._return_data['reason'] = str(ex)
|
|
292
|
+
self._tqm._stats.increment('failures', r.host.name)
|
|
292
293
|
self._tqm.send_callback('v2_runner_on_failed', r)
|
|
293
|
-
failed_includes_hosts.add(r.
|
|
294
|
+
failed_includes_hosts.add(r.host)
|
|
294
295
|
else:
|
|
295
296
|
# since we skip incrementing the stats when the task result is
|
|
296
297
|
# first processed, we do so now for each host in the list
|
|
@@ -321,9 +322,9 @@ class StrategyModule(StrategyBase):
|
|
|
321
322
|
unreachable_hosts = []
|
|
322
323
|
for res in results:
|
|
323
324
|
if res.is_failed():
|
|
324
|
-
failed_hosts.append(res.
|
|
325
|
+
failed_hosts.append(res.host.name)
|
|
325
326
|
elif res.is_unreachable():
|
|
326
|
-
unreachable_hosts.append(res.
|
|
327
|
+
unreachable_hosts.append(res.host.name)
|
|
327
328
|
|
|
328
329
|
if any_errors_fatal and (failed_hosts or unreachable_hosts):
|
|
329
330
|
for host in hosts_left:
|
|
@@ -355,10 +356,9 @@ class StrategyModule(StrategyBase):
|
|
|
355
356
|
return result
|
|
356
357
|
display.debug("done checking to see if all hosts have failed")
|
|
357
358
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
return self._tqm.RUN_UNKNOWN_ERROR
|
|
359
|
+
finally:
|
|
360
|
+
# removed unnecessary exception handler, don't want to mis-attribute the entire code block by changing indentation
|
|
361
|
+
pass
|
|
362
362
|
|
|
363
363
|
# run the base class run() method, which executes the cleanup function
|
|
364
364
|
# 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.template 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,40 +46,44 @@ 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
|
+
|
|
53
|
+
return bool(result.get('timedout') and bool(result['timedout'].get('period')))
|
|
48
54
|
|
|
49
55
|
|
|
50
56
|
def failed(result):
|
|
51
|
-
|
|
57
|
+
""" Test if task result yields failed """
|
|
52
58
|
if not isinstance(result, MutableMapping):
|
|
53
59
|
raise errors.AnsibleFilterError("The 'failed' test expects a dictionary")
|
|
54
|
-
|
|
60
|
+
|
|
61
|
+
return bool(result.get('failed'))
|
|
55
62
|
|
|
56
63
|
|
|
57
64
|
def success(result):
|
|
58
|
-
|
|
59
|
-
return not failed(result)
|
|
65
|
+
""" Test if task result yields success """
|
|
66
|
+
return not bool(failed(result))
|
|
60
67
|
|
|
61
68
|
|
|
62
69
|
def unreachable(result):
|
|
63
|
-
|
|
70
|
+
""" Test if task result yields unreachable """
|
|
64
71
|
if not isinstance(result, MutableMapping):
|
|
65
72
|
raise errors.AnsibleFilterError("The 'unreachable' test expects a dictionary")
|
|
66
|
-
|
|
73
|
+
|
|
74
|
+
return bool(result.get('unreachable'))
|
|
67
75
|
|
|
68
76
|
|
|
69
77
|
def reachable(result):
|
|
70
|
-
|
|
71
|
-
return not unreachable(result)
|
|
78
|
+
""" Test if task result yields reachable """
|
|
79
|
+
return bool(not unreachable(result))
|
|
72
80
|
|
|
73
81
|
|
|
74
82
|
def changed(result):
|
|
75
|
-
|
|
83
|
+
""" Test if task result yields changed """
|
|
76
84
|
if not isinstance(result, MutableMapping):
|
|
77
85
|
raise errors.AnsibleFilterError("The 'changed' test expects a dictionary")
|
|
86
|
+
|
|
78
87
|
if 'changed' not in result:
|
|
79
88
|
changed = False
|
|
80
89
|
if (
|
|
@@ -83,29 +92,31 @@ def changed(result):
|
|
|
83
92
|
isinstance(result['results'][0], MutableMapping)
|
|
84
93
|
):
|
|
85
94
|
for res in result['results']:
|
|
86
|
-
if res.get('changed'
|
|
95
|
+
if res.get('changed'):
|
|
87
96
|
changed = True
|
|
88
97
|
break
|
|
89
98
|
else:
|
|
90
|
-
changed = result.get('changed'
|
|
91
|
-
|
|
99
|
+
changed = result.get('changed')
|
|
100
|
+
|
|
101
|
+
return bool(changed)
|
|
92
102
|
|
|
93
103
|
|
|
94
104
|
def skipped(result):
|
|
95
|
-
|
|
105
|
+
""" Test if task result yields skipped """
|
|
96
106
|
if not isinstance(result, MutableMapping):
|
|
97
107
|
raise errors.AnsibleFilterError("The 'skipped' test expects a dictionary")
|
|
98
|
-
|
|
108
|
+
|
|
109
|
+
return bool(result.get('skipped'))
|
|
99
110
|
|
|
100
111
|
|
|
101
112
|
def started(result):
|
|
102
|
-
|
|
113
|
+
""" Test if async task has started """
|
|
103
114
|
if not isinstance(result, MutableMapping):
|
|
104
115
|
raise errors.AnsibleFilterError("The 'started' test expects a dictionary")
|
|
116
|
+
|
|
105
117
|
if 'started' in result:
|
|
106
118
|
# For async tasks, return status
|
|
107
|
-
|
|
108
|
-
return result.get('started', 0) == 1
|
|
119
|
+
return bool(result.get('started'))
|
|
109
120
|
else:
|
|
110
121
|
# For non-async tasks, warn user, but return as if started
|
|
111
122
|
display.warning("The 'started' test expects an async task, but a non-async task was tested")
|
|
@@ -113,13 +124,13 @@ def started(result):
|
|
|
113
124
|
|
|
114
125
|
|
|
115
126
|
def finished(result):
|
|
116
|
-
|
|
127
|
+
""" Test if async task has finished """
|
|
117
128
|
if not isinstance(result, MutableMapping):
|
|
118
129
|
raise errors.AnsibleFilterError("The 'finished' test expects a dictionary")
|
|
130
|
+
|
|
119
131
|
if 'finished' in result:
|
|
120
132
|
# For async tasks, return status
|
|
121
|
-
|
|
122
|
-
return result.get('finished', 0) == 1
|
|
133
|
+
return bool(result.get('finished'))
|
|
123
134
|
else:
|
|
124
135
|
# For non-async tasks, warn user, but return as if finished
|
|
125
136
|
display.warning("The 'finished' test expects an async task, but a non-async task was tested")
|
|
@@ -127,12 +138,10 @@ def finished(result):
|
|
|
127
138
|
|
|
128
139
|
|
|
129
140
|
def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='search'):
|
|
130
|
-
|
|
141
|
+
""" Expose `re` as a boolean filter using the `search` method by default.
|
|
131
142
|
This is likely only useful for `search` and `match` which already
|
|
132
143
|
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
|
|
144
|
+
"""
|
|
136
145
|
value = to_text(value, errors='surrogate_or_strict')
|
|
137
146
|
flags = 0
|
|
138
147
|
if ignorecase:
|
|
@@ -143,12 +152,19 @@ def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='s
|
|
|
143
152
|
return bool(getattr(_re, match_type, 'search')(value))
|
|
144
153
|
|
|
145
154
|
|
|
146
|
-
|
|
155
|
+
@accept_args_markers
|
|
156
|
+
def vault_encrypted(value: object) -> bool:
|
|
147
157
|
"""Evaluate whether a variable is a single vault encrypted value
|
|
148
158
|
|
|
149
159
|
.. versionadded:: 2.10
|
|
150
160
|
"""
|
|
151
|
-
|
|
161
|
+
if ciphertext := VaultHelper.get_ciphertext(value, with_tags=False):
|
|
162
|
+
return VaultLib.is_encrypted(ciphertext)
|
|
163
|
+
|
|
164
|
+
if isinstance(value, Marker):
|
|
165
|
+
value.trip()
|
|
166
|
+
|
|
167
|
+
return False
|
|
152
168
|
|
|
153
169
|
|
|
154
170
|
def vaulted_file(value):
|
|
@@ -159,22 +175,22 @@ def vaulted_file(value):
|
|
|
159
175
|
try:
|
|
160
176
|
with open(to_bytes(value), 'rb') as f:
|
|
161
177
|
return is_encrypted_file(f)
|
|
162
|
-
except
|
|
163
|
-
raise errors.AnsibleFilterError(f"Cannot test if the file {value} is a vault"
|
|
178
|
+
except OSError as ex:
|
|
179
|
+
raise errors.AnsibleFilterError(f"Cannot test if the file {value!r} is a vault.") from ex
|
|
164
180
|
|
|
165
181
|
|
|
166
182
|
def match(value, pattern='', ignorecase=False, multiline=False):
|
|
167
|
-
|
|
183
|
+
""" Perform a `re.match` returning a boolean """
|
|
168
184
|
return regex(value, pattern, ignorecase, multiline, 'match')
|
|
169
185
|
|
|
170
186
|
|
|
171
187
|
def search(value, pattern='', ignorecase=False, multiline=False):
|
|
172
|
-
|
|
188
|
+
""" Perform a `re.search` returning a boolean """
|
|
173
189
|
return regex(value, pattern, ignorecase, multiline, 'search')
|
|
174
190
|
|
|
175
191
|
|
|
176
192
|
def version_compare(value, version, operator='eq', strict=None, version_type=None):
|
|
177
|
-
|
|
193
|
+
""" Perform a version comparison on a value """
|
|
178
194
|
op_map = {
|
|
179
195
|
'==': 'eq', '=': 'eq', 'eq': 'eq',
|
|
180
196
|
'<': 'lt', 'lt': 'lt',
|
|
@@ -257,8 +273,28 @@ def falsy(value, convert_bool=False):
|
|
|
257
273
|
return not truthy(value, convert_bool=convert_bool)
|
|
258
274
|
|
|
259
275
|
|
|
276
|
+
@accept_args_markers
|
|
277
|
+
@functools.wraps(test_defined)
|
|
278
|
+
def wrapped_test_defined(value: object) -> Marker | bool:
|
|
279
|
+
"""Wrapper around Jinja's `defined` test to avoid mutating the externally-owned function with our marker attribute."""
|
|
280
|
+
if isinstance(value, Marker) and not isinstance(value, UndefinedMarker):
|
|
281
|
+
return value
|
|
282
|
+
|
|
283
|
+
return test_defined(value)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@accept_args_markers
|
|
287
|
+
@functools.wraps(test_undefined)
|
|
288
|
+
def wrapped_test_undefined(value: object) -> Marker | bool:
|
|
289
|
+
"""Wrapper around Jinja's `undefined` test to avoid mutating the externally-owned function with our marker attribute."""
|
|
290
|
+
if isinstance(value, Marker) and not isinstance(value, UndefinedMarker):
|
|
291
|
+
return value
|
|
292
|
+
|
|
293
|
+
return test_undefined(value)
|
|
294
|
+
|
|
295
|
+
|
|
260
296
|
class TestModule(object):
|
|
261
|
-
|
|
297
|
+
""" Ansible core jinja2 tests """
|
|
262
298
|
|
|
263
299
|
def tests(self):
|
|
264
300
|
return {
|
|
@@ -304,4 +340,8 @@ class TestModule(object):
|
|
|
304
340
|
# vault
|
|
305
341
|
'vault_encrypted': vault_encrypted,
|
|
306
342
|
'vaulted_file': vaulted_file,
|
|
343
|
+
|
|
344
|
+
# overrides that require special arg handling
|
|
345
|
+
'defined': wrapped_test_defined,
|
|
346
|
+
'undefined': wrapped_test_undefined,
|
|
307
347
|
}
|
ansible/plugins/test/files.py
CHANGED
|
@@ -5,7 +5,7 @@ DOCUMENTATION:
|
|
|
5
5
|
short_description: Did async task finish
|
|
6
6
|
description:
|
|
7
7
|
- Used to test if an async task has finished, it will also work with normal tasks but will issue a warning.
|
|
8
|
-
- This test checks for the existence of a C(finished) key in the input dictionary and that it is V(
|
|
8
|
+
- This test checks for the existence of a C(finished) key in the input dictionary and that it is V(True) if present
|
|
9
9
|
options:
|
|
10
10
|
_input:
|
|
11
11
|
description: registered result from an Ansible task
|