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
|
@@ -21,35 +21,42 @@ import os
|
|
|
21
21
|
|
|
22
22
|
from ansible import constants as C
|
|
23
23
|
from ansible.errors import AnsibleError
|
|
24
|
-
from ansible.executor.
|
|
24
|
+
from ansible.executor.task_result import _RawTaskResult
|
|
25
|
+
from ansible.inventory.host import Host
|
|
25
26
|
from ansible.module_utils.common.text.converters import to_text
|
|
27
|
+
from ansible.parsing.dataloader import DataLoader
|
|
26
28
|
from ansible.playbook.handler import Handler
|
|
27
29
|
from ansible.playbook.task_include import TaskInclude
|
|
28
30
|
from ansible.playbook.role_include import IncludeRole
|
|
29
|
-
from ansible.
|
|
31
|
+
from ansible._internal._templating._engine import TemplateEngine
|
|
30
32
|
from ansible.utils.display import Display
|
|
33
|
+
from ansible.vars.manager import VariableManager
|
|
31
34
|
|
|
32
35
|
display = Display()
|
|
33
36
|
|
|
34
37
|
|
|
35
38
|
class IncludedFile:
|
|
36
39
|
|
|
37
|
-
def __init__(self, filename, args, vars, task, is_role=False):
|
|
40
|
+
def __init__(self, filename, args, vars, task, is_role: bool = False) -> None:
|
|
38
41
|
self._filename = filename
|
|
39
42
|
self._args = args
|
|
40
43
|
self._vars = vars
|
|
41
44
|
self._task = task
|
|
42
|
-
self._hosts = []
|
|
45
|
+
self._hosts: list[Host] = []
|
|
43
46
|
self._is_role = is_role
|
|
44
|
-
self._results = []
|
|
47
|
+
self._results: list[_RawTaskResult] = []
|
|
45
48
|
|
|
46
|
-
def add_host(self, host):
|
|
49
|
+
def add_host(self, host: Host) -> None:
|
|
47
50
|
if host not in self._hosts:
|
|
48
51
|
self._hosts.append(host)
|
|
49
52
|
return
|
|
53
|
+
|
|
50
54
|
raise ValueError()
|
|
51
55
|
|
|
52
56
|
def __eq__(self, other):
|
|
57
|
+
if not isinstance(other, IncludedFile):
|
|
58
|
+
return False
|
|
59
|
+
|
|
53
60
|
return (other._filename == self._filename and
|
|
54
61
|
other._args == self._args and
|
|
55
62
|
other._vars == self._vars and
|
|
@@ -60,23 +67,28 @@ class IncludedFile:
|
|
|
60
67
|
return "%s (args=%s vars=%s): %s" % (self._filename, self._args, self._vars, self._hosts)
|
|
61
68
|
|
|
62
69
|
@staticmethod
|
|
63
|
-
def process_include_results(
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
def process_include_results(
|
|
71
|
+
results: list[_RawTaskResult],
|
|
72
|
+
iterator,
|
|
73
|
+
loader: DataLoader,
|
|
74
|
+
variable_manager: VariableManager,
|
|
75
|
+
) -> list[IncludedFile]:
|
|
76
|
+
included_files: list[IncludedFile] = []
|
|
77
|
+
task_vars_cache: dict[tuple, dict] = {}
|
|
66
78
|
|
|
67
79
|
for res in results:
|
|
68
80
|
|
|
69
|
-
original_host = res.
|
|
70
|
-
original_task = res.
|
|
81
|
+
original_host = res.host
|
|
82
|
+
original_task = res.task
|
|
71
83
|
|
|
72
84
|
if original_task.action in C._ACTION_ALL_INCLUDES:
|
|
73
85
|
|
|
74
86
|
if original_task.loop:
|
|
75
|
-
if 'results' not in res.
|
|
87
|
+
if 'results' not in res._return_data:
|
|
76
88
|
continue
|
|
77
|
-
include_results = res.
|
|
89
|
+
include_results = res._loop_results
|
|
78
90
|
else:
|
|
79
|
-
include_results = [res.
|
|
91
|
+
include_results = [res._return_data]
|
|
80
92
|
|
|
81
93
|
for include_result in include_results:
|
|
82
94
|
# if the task result was skipped or failed, continue
|
|
@@ -114,7 +126,7 @@ class IncludedFile:
|
|
|
114
126
|
if loader.get_basedir() not in task_vars['ansible_search_path']:
|
|
115
127
|
task_vars['ansible_search_path'].append(loader.get_basedir())
|
|
116
128
|
|
|
117
|
-
templar =
|
|
129
|
+
templar = TemplateEngine(loader=loader, variables=task_vars)
|
|
118
130
|
|
|
119
131
|
if original_task.action in C._ACTION_INCLUDE_TASKS:
|
|
120
132
|
include_file = None
|
|
@@ -132,6 +144,8 @@ class IncludedFile:
|
|
|
132
144
|
parent_include_dir = parent_include._role_path
|
|
133
145
|
else:
|
|
134
146
|
try:
|
|
147
|
+
# FUTURE: Since the parent include path has already been resolved, it should be used here.
|
|
148
|
+
# Unfortunately it's not currently stored anywhere, so it must be calculated again.
|
|
135
149
|
parent_include_dir = os.path.dirname(templar.template(parent_include.args.get('_raw_params')))
|
|
136
150
|
except AnsibleError as e:
|
|
137
151
|
parent_include_dir = ''
|
|
@@ -144,7 +158,7 @@ class IncludedFile:
|
|
|
144
158
|
cumulative_path = os.path.join(parent_include_dir, cumulative_path)
|
|
145
159
|
else:
|
|
146
160
|
cumulative_path = parent_include_dir
|
|
147
|
-
include_target =
|
|
161
|
+
include_target = include_result['include']
|
|
148
162
|
if original_task._role:
|
|
149
163
|
dirname = 'handlers' if isinstance(original_task, Handler) else 'tasks'
|
|
150
164
|
new_basedir = os.path.join(original_task._role._role_path, dirname, cumulative_path)
|
|
@@ -170,7 +184,7 @@ class IncludedFile:
|
|
|
170
184
|
|
|
171
185
|
if include_file is None:
|
|
172
186
|
if original_task._role:
|
|
173
|
-
include_target =
|
|
187
|
+
include_target = include_result['include']
|
|
174
188
|
include_file = loader.path_dwim_relative(
|
|
175
189
|
original_task._role._role_path,
|
|
176
190
|
'handlers' if isinstance(original_task, Handler) else 'tasks',
|
|
@@ -179,25 +193,17 @@ class IncludedFile:
|
|
|
179
193
|
else:
|
|
180
194
|
include_file = loader.path_dwim(include_result['include'])
|
|
181
195
|
|
|
182
|
-
include_file = templar.template(include_file)
|
|
183
196
|
inc_file = IncludedFile(include_file, include_args, special_vars, original_task)
|
|
184
197
|
else:
|
|
185
198
|
# template the included role's name here
|
|
186
199
|
role_name = include_args.pop('name', include_args.pop('role', None))
|
|
187
|
-
if role_name is not None:
|
|
188
|
-
role_name = templar.template(role_name)
|
|
189
|
-
|
|
190
200
|
new_task = original_task.copy()
|
|
191
201
|
new_task.post_validate(templar=templar)
|
|
192
202
|
new_task._role_name = role_name
|
|
193
203
|
for from_arg in new_task.FROM_ARGS:
|
|
194
204
|
if from_arg in include_args:
|
|
195
205
|
from_key = from_arg.removesuffix('_from')
|
|
196
|
-
new_task._from_files[from_key] =
|
|
197
|
-
|
|
198
|
-
omit_token = task_vars.get('omit')
|
|
199
|
-
if omit_token:
|
|
200
|
-
new_task._from_files = remove_omit(new_task._from_files, omit_token)
|
|
206
|
+
new_task._from_files[from_key] = include_args.pop(from_arg)
|
|
201
207
|
|
|
202
208
|
inc_file = IncludedFile(role_name, include_args, special_vars, new_task, is_role=True)
|
|
203
209
|
|
ansible/playbook/loop_control.py
CHANGED
|
@@ -40,8 +40,8 @@ class LoopControl(FieldAttributeBase):
|
|
|
40
40
|
return t.load_data(data, variable_manager=variable_manager, loader=loader)
|
|
41
41
|
|
|
42
42
|
def _post_validate_break_when(self, attr, value, templar):
|
|
43
|
-
|
|
43
|
+
"""
|
|
44
44
|
break_when is evaluated after the execution of the loop is complete,
|
|
45
45
|
and should not be templated during the regular post_validate step.
|
|
46
|
-
|
|
46
|
+
"""
|
|
47
47
|
return value
|
ansible/playbook/play.py
CHANGED
|
@@ -19,8 +19,8 @@ from __future__ import annotations
|
|
|
19
19
|
|
|
20
20
|
from ansible import constants as C
|
|
21
21
|
from ansible import context
|
|
22
|
+
from ansible.errors import AnsibleError
|
|
22
23
|
from ansible.errors import AnsibleParserError, AnsibleAssertionError
|
|
23
|
-
from ansible.module_utils.common.text.converters import to_native
|
|
24
24
|
from ansible.module_utils.common.collections import is_sequence
|
|
25
25
|
from ansible.module_utils.six import binary_type, string_types, text_type
|
|
26
26
|
from ansible.playbook.attribute import NonInheritableFieldAttribute
|
|
@@ -31,6 +31,7 @@ from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles
|
|
|
31
31
|
from ansible.playbook.role import Role
|
|
32
32
|
from ansible.playbook.task import Task
|
|
33
33
|
from ansible.playbook.taggable import Taggable
|
|
34
|
+
from ansible.parsing.vault import EncryptedString
|
|
34
35
|
from ansible.utils.display import Display
|
|
35
36
|
|
|
36
37
|
display = Display()
|
|
@@ -99,6 +100,15 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
99
100
|
def __repr__(self):
|
|
100
101
|
return self.get_name()
|
|
101
102
|
|
|
103
|
+
def _get_cached_role(self, role):
|
|
104
|
+
role_path = role.get_role_path()
|
|
105
|
+
role_cache = self.role_cache[role_path]
|
|
106
|
+
try:
|
|
107
|
+
idx = role_cache.index(role)
|
|
108
|
+
return role_cache[idx]
|
|
109
|
+
except ValueError:
|
|
110
|
+
raise AnsibleError(f'Cannot locate {role.get_name()} in role cache')
|
|
111
|
+
|
|
102
112
|
def _validate_hosts(self, attribute, name, value):
|
|
103
113
|
# Only validate 'hosts' if a value was passed in to original data set.
|
|
104
114
|
if 'hosts' in self._ds:
|
|
@@ -113,11 +123,11 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
113
123
|
elif not isinstance(entry, (binary_type, text_type)):
|
|
114
124
|
raise AnsibleParserError("Hosts list contains an invalid host value: '{host!s}'".format(host=entry))
|
|
115
125
|
|
|
116
|
-
elif not isinstance(value, (binary_type, text_type)):
|
|
126
|
+
elif not isinstance(value, (binary_type, text_type, EncryptedString)):
|
|
117
127
|
raise AnsibleParserError("Hosts list must be a sequence or string. Please check your playbook.")
|
|
118
128
|
|
|
119
129
|
def get_name(self):
|
|
120
|
-
|
|
130
|
+
""" return the name of the Play """
|
|
121
131
|
if self.name:
|
|
122
132
|
return self.name
|
|
123
133
|
|
|
@@ -136,9 +146,9 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
136
146
|
return p.load_data(data, variable_manager=variable_manager, loader=loader)
|
|
137
147
|
|
|
138
148
|
def preprocess_data(self, ds):
|
|
139
|
-
|
|
149
|
+
"""
|
|
140
150
|
Adjusts play datastructure to cleanup old/legacy items
|
|
141
|
-
|
|
151
|
+
"""
|
|
142
152
|
|
|
143
153
|
if not isinstance(ds, dict):
|
|
144
154
|
raise AnsibleAssertionError('while preprocessing data (%s), ds should be a dict but was a %s' % (ds, type(ds)))
|
|
@@ -158,55 +168,57 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
158
168
|
|
|
159
169
|
return super(Play, self).preprocess_data(ds)
|
|
160
170
|
|
|
171
|
+
# DTFIX-FUTURE: these do nothing but augment the exception message; DRY and nuke
|
|
172
|
+
|
|
161
173
|
def _load_tasks(self, attr, ds):
|
|
162
|
-
|
|
174
|
+
"""
|
|
163
175
|
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
|
164
176
|
Bare tasks outside of a block are given an implicit block.
|
|
165
|
-
|
|
177
|
+
"""
|
|
166
178
|
try:
|
|
167
179
|
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
|
|
168
|
-
except AssertionError as
|
|
169
|
-
raise AnsibleParserError("A malformed block was encountered while loading tasks
|
|
180
|
+
except AssertionError as ex:
|
|
181
|
+
raise AnsibleParserError("A malformed block was encountered while loading tasks.", obj=self._ds) from ex
|
|
170
182
|
|
|
171
183
|
def _load_pre_tasks(self, attr, ds):
|
|
172
|
-
|
|
184
|
+
"""
|
|
173
185
|
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
|
174
186
|
Bare tasks outside of a block are given an implicit block.
|
|
175
|
-
|
|
187
|
+
"""
|
|
176
188
|
try:
|
|
177
189
|
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
|
|
178
|
-
except AssertionError as
|
|
179
|
-
raise AnsibleParserError("A malformed block was encountered while loading pre_tasks", obj=self._ds
|
|
190
|
+
except AssertionError as ex:
|
|
191
|
+
raise AnsibleParserError("A malformed block was encountered while loading pre_tasks.", obj=self._ds) from ex
|
|
180
192
|
|
|
181
193
|
def _load_post_tasks(self, attr, ds):
|
|
182
|
-
|
|
194
|
+
"""
|
|
183
195
|
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
|
184
196
|
Bare tasks outside of a block are given an implicit block.
|
|
185
|
-
|
|
197
|
+
"""
|
|
186
198
|
try:
|
|
187
199
|
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
|
|
188
|
-
except AssertionError as
|
|
189
|
-
raise AnsibleParserError("A malformed block was encountered while loading post_tasks", obj=self._ds
|
|
200
|
+
except AssertionError as ex:
|
|
201
|
+
raise AnsibleParserError("A malformed block was encountered while loading post_tasks.", obj=self._ds) from ex
|
|
190
202
|
|
|
191
203
|
def _load_handlers(self, attr, ds):
|
|
192
|
-
|
|
204
|
+
"""
|
|
193
205
|
Loads a list of blocks from a list which may be mixed handlers/blocks.
|
|
194
206
|
Bare handlers outside of a block are given an implicit block.
|
|
195
|
-
|
|
207
|
+
"""
|
|
196
208
|
try:
|
|
197
209
|
return self._extend_value(
|
|
198
210
|
self.handlers,
|
|
199
211
|
load_list_of_blocks(ds=ds, play=self, use_handlers=True, variable_manager=self._variable_manager, loader=self._loader),
|
|
200
212
|
prepend=True
|
|
201
213
|
)
|
|
202
|
-
except AssertionError as
|
|
203
|
-
raise AnsibleParserError("A malformed block was encountered while loading handlers", obj=self._ds
|
|
214
|
+
except AssertionError as ex:
|
|
215
|
+
raise AnsibleParserError("A malformed block was encountered while loading handlers.", obj=self._ds) from ex
|
|
204
216
|
|
|
205
217
|
def _load_roles(self, attr, ds):
|
|
206
|
-
|
|
218
|
+
"""
|
|
207
219
|
Loads and returns a list of RoleInclude objects from the datastructure
|
|
208
220
|
list of role definitions and creates the Role from those objects
|
|
209
|
-
|
|
221
|
+
"""
|
|
210
222
|
|
|
211
223
|
if ds is None:
|
|
212
224
|
ds = []
|
|
@@ -214,8 +226,8 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
214
226
|
try:
|
|
215
227
|
role_includes = load_list_of_roles(ds, play=self, variable_manager=self._variable_manager,
|
|
216
228
|
loader=self._loader, collection_search_list=self.collections)
|
|
217
|
-
except AssertionError as
|
|
218
|
-
raise AnsibleParserError("A malformed role declaration was encountered.", obj=self._ds
|
|
229
|
+
except AssertionError as ex:
|
|
230
|
+
raise AnsibleParserError("A malformed role declaration was encountered.", obj=self._ds) from ex
|
|
219
231
|
|
|
220
232
|
roles = []
|
|
221
233
|
for ri in role_includes:
|
|
@@ -242,13 +254,13 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
242
254
|
return vars_prompts
|
|
243
255
|
|
|
244
256
|
def _compile_roles(self):
|
|
245
|
-
|
|
257
|
+
"""
|
|
246
258
|
Handles the role compilation step, returning a flat list of tasks
|
|
247
259
|
with the lowest level dependencies first. For example, if a role R
|
|
248
260
|
has a dependency D1, which also has a dependency D2, the tasks from
|
|
249
261
|
D2 are merged first, followed by D1, and lastly by the tasks from
|
|
250
262
|
the parent role R last. This is done for all roles in the Play.
|
|
251
|
-
|
|
263
|
+
"""
|
|
252
264
|
|
|
253
265
|
block_list = []
|
|
254
266
|
|
|
@@ -263,10 +275,10 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
263
275
|
return block_list
|
|
264
276
|
|
|
265
277
|
def compile_roles_handlers(self):
|
|
266
|
-
|
|
278
|
+
"""
|
|
267
279
|
Handles the role handler compilation step, returning a flat list of Handlers
|
|
268
280
|
This is done for all roles in the Play.
|
|
269
|
-
|
|
281
|
+
"""
|
|
270
282
|
|
|
271
283
|
block_list = []
|
|
272
284
|
|
|
@@ -279,25 +291,39 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
279
291
|
return block_list
|
|
280
292
|
|
|
281
293
|
def compile(self):
|
|
282
|
-
|
|
294
|
+
"""
|
|
283
295
|
Compiles and returns the task list for this play, compiled from the
|
|
284
296
|
roles (which are themselves compiled recursively) and/or the list of
|
|
285
297
|
tasks specified in the play.
|
|
286
|
-
|
|
287
|
-
|
|
298
|
+
"""
|
|
288
299
|
# create a block containing a single flush handlers meta
|
|
289
300
|
# task, so we can be sure to run handlers at certain points
|
|
290
301
|
# of the playbook execution
|
|
291
|
-
flush_block = Block
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
302
|
+
flush_block = Block(play=self)
|
|
303
|
+
|
|
304
|
+
t = Task(block=flush_block)
|
|
305
|
+
t.action = 'meta'
|
|
306
|
+
t.resolved_action = 'ansible.builtin.meta'
|
|
307
|
+
t.args['_raw_params'] = 'flush_handlers'
|
|
308
|
+
t.implicit = True
|
|
309
|
+
t.set_loader(self._loader)
|
|
310
|
+
|
|
311
|
+
if self.tags:
|
|
312
|
+
# Avoid calling flush_handlers in case the whole play is skipped on tags,
|
|
313
|
+
# this could be performance improvement since calling flush_handlers on
|
|
314
|
+
# large inventories could be expensive even if no hosts are notified
|
|
315
|
+
# since we call flush_handlers per host.
|
|
316
|
+
# Block.filter_tagged_tasks ignores evaluating tags on implicit meta
|
|
317
|
+
# tasks so we need to explicitly call Task.evaluate_tags here.
|
|
318
|
+
t.tags = self.tags
|
|
319
|
+
if t.evaluate_tags(self.only_tags, self.skip_tags, all_vars=self.vars):
|
|
320
|
+
flush_block.block = [t]
|
|
321
|
+
else:
|
|
322
|
+
flush_block.block = [t]
|
|
300
323
|
|
|
324
|
+
# NOTE keep flush_handlers tasks even if a section has no regular tasks,
|
|
325
|
+
# there may be notified handlers from the previous section
|
|
326
|
+
# (typically when a handler notifies a handler defined before)
|
|
301
327
|
block_list = []
|
|
302
328
|
if self.force_handlers:
|
|
303
329
|
noop_task = Task()
|
|
@@ -307,18 +333,33 @@ class Play(Base, Taggable, CollectionSearch):
|
|
|
307
333
|
noop_task.set_loader(self._loader)
|
|
308
334
|
|
|
309
335
|
b = Block(play=self)
|
|
310
|
-
|
|
336
|
+
if self.pre_tasks:
|
|
337
|
+
b.block = self.pre_tasks
|
|
338
|
+
else:
|
|
339
|
+
nt = noop_task.copy(exclude_parent=True)
|
|
340
|
+
nt._parent = b
|
|
341
|
+
b.block = [nt]
|
|
311
342
|
b.always = [flush_block]
|
|
312
343
|
block_list.append(b)
|
|
313
344
|
|
|
314
345
|
tasks = self._compile_roles() + self.tasks
|
|
315
346
|
b = Block(play=self)
|
|
316
|
-
|
|
347
|
+
if tasks:
|
|
348
|
+
b.block = tasks
|
|
349
|
+
else:
|
|
350
|
+
nt = noop_task.copy(exclude_parent=True)
|
|
351
|
+
nt._parent = b
|
|
352
|
+
b.block = [nt]
|
|
317
353
|
b.always = [flush_block]
|
|
318
354
|
block_list.append(b)
|
|
319
355
|
|
|
320
356
|
b = Block(play=self)
|
|
321
|
-
|
|
357
|
+
if self.post_tasks:
|
|
358
|
+
b.block = self.post_tasks
|
|
359
|
+
else:
|
|
360
|
+
nt = noop_task.copy(exclude_parent=True)
|
|
361
|
+
nt._parent = b
|
|
362
|
+
b.block = [nt]
|
|
322
363
|
b.always = [flush_block]
|
|
323
364
|
block_list.append(b)
|
|
324
365
|
|
ansible/playbook/play_context.py
CHANGED
|
@@ -65,11 +65,13 @@ RESET_VARS = (
|
|
|
65
65
|
|
|
66
66
|
class PlayContext(Base):
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
"""
|
|
69
69
|
This class is used to consolidate the connection information for
|
|
70
70
|
hosts in a play and child tasks, where the task may override some
|
|
71
71
|
connection/authentication information.
|
|
72
|
-
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
_post_validate_object = True
|
|
73
75
|
|
|
74
76
|
# base
|
|
75
77
|
module_compression = FieldAttribute(isa='string', default=C.DEFAULT_MODULE_COMPRESSION)
|
|
@@ -88,7 +90,7 @@ class PlayContext(Base):
|
|
|
88
90
|
# networking modules
|
|
89
91
|
network_os = FieldAttribute(isa='string')
|
|
90
92
|
|
|
91
|
-
#
|
|
93
|
+
# FIXME: docker - remove these
|
|
92
94
|
docker_extra_args = FieldAttribute(isa='string')
|
|
93
95
|
|
|
94
96
|
# ???
|
|
@@ -103,10 +105,6 @@ class PlayContext(Base):
|
|
|
103
105
|
become_flags = FieldAttribute(isa='string', default=C.DEFAULT_BECOME_FLAGS)
|
|
104
106
|
prompt = FieldAttribute(isa='string')
|
|
105
107
|
|
|
106
|
-
# general flags
|
|
107
|
-
only_tags = FieldAttribute(isa='set', default=set)
|
|
108
|
-
skip_tags = FieldAttribute(isa='set', default=set)
|
|
109
|
-
|
|
110
108
|
start_at_task = FieldAttribute(isa='string')
|
|
111
109
|
step = FieldAttribute(isa='bool', default=False)
|
|
112
110
|
|
|
@@ -158,11 +156,11 @@ class PlayContext(Base):
|
|
|
158
156
|
self.force_handlers = play.force_handlers
|
|
159
157
|
|
|
160
158
|
def set_attributes_from_cli(self):
|
|
161
|
-
|
|
159
|
+
"""
|
|
162
160
|
Configures this connection information instance with data from
|
|
163
161
|
options specified by the user on the command line. These have a
|
|
164
162
|
lower precedence than those set on the play or host.
|
|
165
|
-
|
|
163
|
+
"""
|
|
166
164
|
if context.CLIARGS.get('timeout', False):
|
|
167
165
|
self.timeout = int(context.CLIARGS['timeout'])
|
|
168
166
|
|
|
@@ -175,14 +173,14 @@ class PlayContext(Base):
|
|
|
175
173
|
self.start_at_task = context.CLIARGS.get('start_at_task', None) # Else default
|
|
176
174
|
|
|
177
175
|
def set_task_and_variable_override(self, task, variables, templar):
|
|
178
|
-
|
|
176
|
+
"""
|
|
179
177
|
Sets attributes from the task if they are set, which will override
|
|
180
178
|
those from the play.
|
|
181
179
|
|
|
182
180
|
:arg task: the task object with the parameters that were set on it
|
|
183
181
|
:arg variables: variables from inventory
|
|
184
182
|
:arg templar: templar instance if templating variables is needed
|
|
185
|
-
|
|
183
|
+
"""
|
|
186
184
|
|
|
187
185
|
new_info = self.copy()
|
|
188
186
|
|
|
@@ -201,8 +199,7 @@ class PlayContext(Base):
|
|
|
201
199
|
# In the case of a loop, the delegated_to host may have been
|
|
202
200
|
# templated based on the loop variable, so we try and locate
|
|
203
201
|
# the host name in the delegated variable dictionary here
|
|
204
|
-
|
|
205
|
-
delegated_vars = variables.get('ansible_delegated_vars', dict()).get(delegated_host_name, dict())
|
|
202
|
+
delegated_vars = variables.get('ansible_delegated_vars', dict()).get(task.delegate_to, dict())
|
|
206
203
|
|
|
207
204
|
delegated_transport = C.DEFAULT_TRANSPORT
|
|
208
205
|
for transport_var in C.MAGIC_VARIABLE_MAPPING.get('connection'):
|
|
@@ -218,8 +215,8 @@ class PlayContext(Base):
|
|
|
218
215
|
if address_var in delegated_vars:
|
|
219
216
|
break
|
|
220
217
|
else:
|
|
221
|
-
display.debug("no remote address found for delegated host %s\nusing its name, so success depends on DNS resolution" %
|
|
222
|
-
delegated_vars['ansible_host'] =
|
|
218
|
+
display.debug("no remote address found for delegated host %s\nusing its name, so success depends on DNS resolution" % task.delegate_to)
|
|
219
|
+
delegated_vars['ansible_host'] = task.delegate_to
|
|
223
220
|
|
|
224
221
|
# reset the port back to the default if none was specified, to prevent
|
|
225
222
|
# the delegated host from inheriting the original host's setting
|
|
@@ -312,10 +309,10 @@ class PlayContext(Base):
|
|
|
312
309
|
self._become_plugin = plugin
|
|
313
310
|
|
|
314
311
|
def update_vars(self, variables):
|
|
315
|
-
|
|
312
|
+
"""
|
|
316
313
|
Adds 'magic' variables relating to connections to the variable dictionary provided.
|
|
317
314
|
In case users need to access from the play, this is a legacy from runner.
|
|
318
|
-
|
|
315
|
+
"""
|
|
319
316
|
|
|
320
317
|
for prop, var_list in C.MAGIC_VARIABLE_MAPPING.items():
|
|
321
318
|
try:
|
|
@@ -19,38 +19,45 @@ from __future__ import annotations
|
|
|
19
19
|
|
|
20
20
|
import os
|
|
21
21
|
|
|
22
|
-
import ansible.constants as C
|
|
23
|
-
from ansible.errors import AnsibleParserError, AnsibleAssertionError
|
|
24
22
|
from ansible.module_utils.common.text.converters import to_bytes
|
|
25
|
-
from ansible.module_utils.six import string_types
|
|
26
|
-
from ansible.parsing.splitter import split_args
|
|
27
|
-
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping
|
|
28
23
|
from ansible.playbook.attribute import NonInheritableFieldAttribute
|
|
29
24
|
from ansible.playbook.base import Base
|
|
30
25
|
from ansible.playbook.conditional import Conditional
|
|
31
26
|
from ansible.playbook.taggable import Taggable
|
|
32
27
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
|
33
28
|
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path, _get_collection_playbook_path
|
|
34
|
-
from ansible.
|
|
35
|
-
from ansible.
|
|
36
|
-
|
|
37
|
-
display = Display()
|
|
29
|
+
from ansible._internal._templating._engine import TemplateEngine
|
|
30
|
+
from ansible.errors import AnsibleError
|
|
31
|
+
from ansible import constants as C
|
|
38
32
|
|
|
39
33
|
|
|
40
34
|
class PlaybookInclude(Base, Conditional, Taggable):
|
|
41
35
|
|
|
42
|
-
import_playbook = NonInheritableFieldAttribute(isa='string')
|
|
43
|
-
|
|
36
|
+
import_playbook = NonInheritableFieldAttribute(isa='string', required=True)
|
|
37
|
+
|
|
38
|
+
_post_validate_object = True # manually post_validate to get free arg validation/coercion
|
|
39
|
+
|
|
40
|
+
def preprocess_data(self, ds):
|
|
41
|
+
keys = {action for action in C._ACTION_IMPORT_PLAYBOOK if action in ds}
|
|
42
|
+
|
|
43
|
+
if len(keys) != 1:
|
|
44
|
+
raise AnsibleError(f'Found conflicting import_playbook actions: {", ".join(sorted(keys))}')
|
|
45
|
+
|
|
46
|
+
key = next(iter(keys))
|
|
47
|
+
|
|
48
|
+
ds['import_playbook'] = ds.pop(key)
|
|
49
|
+
|
|
50
|
+
return ds
|
|
44
51
|
|
|
45
52
|
@staticmethod
|
|
46
53
|
def load(data, basedir, variable_manager=None, loader=None):
|
|
47
54
|
return PlaybookInclude().load_data(ds=data, basedir=basedir, variable_manager=variable_manager, loader=loader)
|
|
48
55
|
|
|
49
56
|
def load_data(self, ds, variable_manager=None, loader=None, basedir=None):
|
|
50
|
-
|
|
57
|
+
"""
|
|
51
58
|
Overrides the base load_data(), as we're actually going to return a new
|
|
52
59
|
Playbook() object rather than a PlaybookInclude object
|
|
53
|
-
|
|
60
|
+
"""
|
|
54
61
|
|
|
55
62
|
# import here to avoid a dependency loop
|
|
56
63
|
from ansible.playbook import Playbook
|
|
@@ -62,18 +69,22 @@ class PlaybookInclude(Base, Conditional, Taggable):
|
|
|
62
69
|
new_obj = super(PlaybookInclude, self).load_data(ds, variable_manager, loader)
|
|
63
70
|
|
|
64
71
|
all_vars = self.vars.copy()
|
|
72
|
+
|
|
65
73
|
if variable_manager:
|
|
66
74
|
all_vars |= variable_manager.get_vars()
|
|
67
75
|
|
|
68
|
-
templar =
|
|
76
|
+
templar = TemplateEngine(loader=loader, variables=all_vars)
|
|
77
|
+
|
|
78
|
+
new_obj.post_validate(templar)
|
|
69
79
|
|
|
70
80
|
# then we use the object to load a Playbook
|
|
71
81
|
pb = Playbook(loader=loader)
|
|
72
82
|
|
|
73
|
-
file_name =
|
|
83
|
+
file_name = new_obj.import_playbook
|
|
74
84
|
|
|
75
85
|
# check for FQCN
|
|
76
86
|
resource = _get_collection_playbook_path(file_name)
|
|
87
|
+
|
|
77
88
|
if resource is not None:
|
|
78
89
|
playbook = resource[1]
|
|
79
90
|
playbook_collection = resource[2]
|
|
@@ -92,6 +103,7 @@ class PlaybookInclude(Base, Conditional, Taggable):
|
|
|
92
103
|
else:
|
|
93
104
|
# it is NOT a collection playbook, setup adjacent paths
|
|
94
105
|
AnsibleCollectionConfig.playbook_paths.append(os.path.dirname(os.path.abspath(to_bytes(playbook, errors='surrogate_or_strict'))))
|
|
106
|
+
# broken, see: https://github.com/ansible/ansible/issues/85357
|
|
95
107
|
|
|
96
108
|
pb._load_playbook_data(file_name=playbook, variable_manager=variable_manager, vars=self.vars.copy())
|
|
97
109
|
|
|
@@ -120,50 +132,3 @@ class PlaybookInclude(Base, Conditional, Taggable):
|
|
|
120
132
|
task_block._when = new_obj.when[:] + task_block.when[:]
|
|
121
133
|
|
|
122
134
|
return pb
|
|
123
|
-
|
|
124
|
-
def preprocess_data(self, ds):
|
|
125
|
-
'''
|
|
126
|
-
Reorganizes the data for a PlaybookInclude datastructure to line
|
|
127
|
-
up with what we expect the proper attributes to be
|
|
128
|
-
'''
|
|
129
|
-
|
|
130
|
-
if not isinstance(ds, dict):
|
|
131
|
-
raise AnsibleAssertionError('ds (%s) should be a dict but was a %s' % (ds, type(ds)))
|
|
132
|
-
|
|
133
|
-
# the new, cleaned datastructure, which will have legacy
|
|
134
|
-
# items reduced to a standard structure
|
|
135
|
-
new_ds = AnsibleMapping()
|
|
136
|
-
if isinstance(ds, AnsibleBaseYAMLObject):
|
|
137
|
-
new_ds.ansible_pos = ds.ansible_pos
|
|
138
|
-
|
|
139
|
-
for (k, v) in ds.items():
|
|
140
|
-
if k in C._ACTION_IMPORT_PLAYBOOK:
|
|
141
|
-
self._preprocess_import(ds, new_ds, k, v)
|
|
142
|
-
else:
|
|
143
|
-
# some basic error checking, to make sure vars are properly
|
|
144
|
-
# formatted and do not conflict with k=v parameters
|
|
145
|
-
if k == 'vars':
|
|
146
|
-
if 'vars' in new_ds:
|
|
147
|
-
raise AnsibleParserError("import_playbook parameters cannot be mixed with 'vars' entries for import statements", obj=ds)
|
|
148
|
-
elif not isinstance(v, dict):
|
|
149
|
-
raise AnsibleParserError("vars for import_playbook statements must be specified as a dictionary", obj=ds)
|
|
150
|
-
new_ds[k] = v
|
|
151
|
-
|
|
152
|
-
return super(PlaybookInclude, self).preprocess_data(new_ds)
|
|
153
|
-
|
|
154
|
-
def _preprocess_import(self, ds, new_ds, k, v):
|
|
155
|
-
'''
|
|
156
|
-
Splits the playbook import line up into filename and parameters
|
|
157
|
-
'''
|
|
158
|
-
if v is None:
|
|
159
|
-
raise AnsibleParserError("playbook import parameter is missing", obj=ds)
|
|
160
|
-
elif not isinstance(v, string_types):
|
|
161
|
-
raise AnsibleParserError("playbook import parameter must be a string indicating a file path, got %s instead" % type(v), obj=ds)
|
|
162
|
-
|
|
163
|
-
# The import_playbook line must include at least one item, which is the filename
|
|
164
|
-
# to import. Anything after that should be regarded as a parameter to the import
|
|
165
|
-
items = split_args(v)
|
|
166
|
-
if len(items) == 0:
|
|
167
|
-
raise AnsibleParserError("import_playbook statements must specify the file name to import", obj=ds)
|
|
168
|
-
|
|
169
|
-
new_ds['import_playbook'] = items[0].strip()
|