ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_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/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +203 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +197 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +345 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +62 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +159 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +62 -53
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +166 -112
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +161 -96
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +268 -258
- ansible/executor/task_queue_manager.py +124 -90
- ansible/executor/task_result.py +183 -78
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +78 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +152 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +86 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +1 -1
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +4 -4
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +9 -8
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +19 -17
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +32 -27
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +31 -27
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +4 -5
- ansible/plugins/action/gather_facts.py +7 -6
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +35 -44
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +284 -179
- ansible/plugins/callback/default.py +99 -92
- ansible/plugins/callback/junit.py +44 -39
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +28 -21
- ansible/plugins/callback/tree.py +16 -11
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +6 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +225 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +97 -77
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +86 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +159 -184
- 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 +55 -21
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +370 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +433 -63
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +51 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +206 -282
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/WHEEL +1 -1
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -0
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +1 -0
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +2 -1
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +4 -0
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +1 -0
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +16 -1
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +24 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +2 -0
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/delegation.py +1 -0
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +35 -27
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
ansible/playbook/block.py
CHANGED
@@ -19,6 +19,7 @@ from __future__ import annotations
|
|
19
19
|
|
20
20
|
import ansible.constants as C
|
21
21
|
from ansible.errors import AnsibleParserError
|
22
|
+
from ansible.module_utils.common.sentinel import Sentinel
|
22
23
|
from ansible.playbook.attribute import NonInheritableFieldAttribute
|
23
24
|
from ansible.playbook.base import Base
|
24
25
|
from ansible.playbook.conditional import Conditional
|
@@ -28,7 +29,6 @@ from ansible.playbook.helpers import load_list_of_tasks
|
|
28
29
|
from ansible.playbook.notifiable import Notifiable
|
29
30
|
from ansible.playbook.role import Role
|
30
31
|
from ansible.playbook.taggable import Taggable
|
31
|
-
from ansible.utils.sentinel import Sentinel
|
32
32
|
|
33
33
|
|
34
34
|
class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatable):
|
@@ -61,18 +61,18 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
61
61
|
return "BLOCK(uuid=%s)(id=%s)(parent=%s)" % (self._uuid, id(self), self._parent)
|
62
62
|
|
63
63
|
def __eq__(self, other):
|
64
|
-
|
64
|
+
"""object comparison based on _uuid"""
|
65
65
|
return self._uuid == other._uuid
|
66
66
|
|
67
67
|
def __ne__(self, other):
|
68
|
-
|
68
|
+
"""object comparison based on _uuid"""
|
69
69
|
return self._uuid != other._uuid
|
70
70
|
|
71
71
|
def get_vars(self):
|
72
|
-
|
72
|
+
"""
|
73
73
|
Blocks do not store variables directly, however they may be a member
|
74
74
|
of a role or task include which does, so return those if present.
|
75
|
-
|
75
|
+
"""
|
76
76
|
|
77
77
|
all_vars = {}
|
78
78
|
|
@@ -100,10 +100,10 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
100
100
|
return is_block
|
101
101
|
|
102
102
|
def preprocess_data(self, ds):
|
103
|
-
|
103
|
+
"""
|
104
104
|
If a simple task is given, an implicit block for that single task
|
105
105
|
is created, which goes in the main portion of the block
|
106
|
-
|
106
|
+
"""
|
107
107
|
|
108
108
|
if not Block.is_block(ds):
|
109
109
|
if isinstance(ds, list):
|
@@ -113,6 +113,8 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
113
113
|
|
114
114
|
return super(Block, self).preprocess_data(ds)
|
115
115
|
|
116
|
+
# FIXME: these do nothing but augment the exception message; DRY and nuke
|
117
|
+
|
116
118
|
def _load_block(self, attr, ds):
|
117
119
|
try:
|
118
120
|
return load_list_of_tasks(
|
@@ -125,8 +127,8 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
125
127
|
loader=self._loader,
|
126
128
|
use_handlers=self._use_handlers,
|
127
129
|
)
|
128
|
-
except AssertionError as
|
129
|
-
raise AnsibleParserError("A malformed block was encountered while loading a block", obj=self._ds
|
130
|
+
except AssertionError as ex:
|
131
|
+
raise AnsibleParserError("A malformed block was encountered while loading a block", obj=self._ds) from ex
|
130
132
|
|
131
133
|
def _load_rescue(self, attr, ds):
|
132
134
|
try:
|
@@ -140,8 +142,8 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
140
142
|
loader=self._loader,
|
141
143
|
use_handlers=self._use_handlers,
|
142
144
|
)
|
143
|
-
except AssertionError as
|
144
|
-
raise AnsibleParserError("A malformed block was encountered while loading rescue.", obj=self._ds
|
145
|
+
except AssertionError as ex:
|
146
|
+
raise AnsibleParserError("A malformed block was encountered while loading rescue.", obj=self._ds) from ex
|
145
147
|
|
146
148
|
def _load_always(self, attr, ds):
|
147
149
|
try:
|
@@ -155,8 +157,8 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
155
157
|
loader=self._loader,
|
156
158
|
use_handlers=self._use_handlers,
|
157
159
|
)
|
158
|
-
except AssertionError as
|
159
|
-
raise AnsibleParserError("A malformed block was encountered while loading always", obj=self._ds
|
160
|
+
except AssertionError as ex:
|
161
|
+
raise AnsibleParserError("A malformed block was encountered while loading always", obj=self._ds) from ex
|
160
162
|
|
161
163
|
def _validate_always(self, attr, name, value):
|
162
164
|
if value and not self.block:
|
@@ -177,7 +179,7 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
177
179
|
def _dupe_task_list(task_list, new_block):
|
178
180
|
new_task_list = []
|
179
181
|
for task in task_list:
|
180
|
-
new_task = task.copy(exclude_parent=True)
|
182
|
+
new_task = task.copy(exclude_parent=True, exclude_tasks=exclude_tasks)
|
181
183
|
if task._parent:
|
182
184
|
new_task._parent = task._parent.copy(exclude_tasks=True)
|
183
185
|
if task._parent == new_block:
|
@@ -219,10 +221,10 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
219
221
|
return new_me
|
220
222
|
|
221
223
|
def serialize(self):
|
222
|
-
|
224
|
+
"""
|
223
225
|
Override of the default serialize method, since when we're serializing
|
224
226
|
a task we don't want to include the attribute list of tasks.
|
225
|
-
|
227
|
+
"""
|
226
228
|
|
227
229
|
data = dict()
|
228
230
|
for attr in self.fattributes:
|
@@ -240,10 +242,10 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
240
242
|
return data
|
241
243
|
|
242
244
|
def deserialize(self, data):
|
243
|
-
|
245
|
+
"""
|
244
246
|
Override of the default deserialize method, to match the above overridden
|
245
247
|
serialize method
|
246
|
-
|
248
|
+
"""
|
247
249
|
|
248
250
|
# import is here to avoid import loops
|
249
251
|
from ansible.playbook.task_include import TaskInclude
|
@@ -290,9 +292,9 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
290
292
|
dep.set_loader(loader)
|
291
293
|
|
292
294
|
def _get_parent_attribute(self, attr, omit=False):
|
293
|
-
|
295
|
+
"""
|
294
296
|
Generic logic to get the attribute or parent attribute for a block value.
|
295
|
-
|
297
|
+
"""
|
296
298
|
fattr = self.fattributes[attr]
|
297
299
|
|
298
300
|
extend = fattr.extend
|
@@ -363,9 +365,9 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
363
365
|
return value
|
364
366
|
|
365
367
|
def filter_tagged_tasks(self, all_vars):
|
366
|
-
|
368
|
+
"""
|
367
369
|
Creates a new block, with task lists filtered based on the tags.
|
368
|
-
|
370
|
+
"""
|
369
371
|
|
370
372
|
def evaluate_and_append_task(target):
|
371
373
|
tmp_list = []
|
@@ -417,12 +419,12 @@ class Block(Base, Conditional, CollectionSearch, Taggable, Notifiable, Delegatab
|
|
417
419
|
return dict()
|
418
420
|
|
419
421
|
def all_parents_static(self):
|
420
|
-
|
422
|
+
"""
|
421
423
|
Determine if all of the parents of this block were statically loaded
|
422
424
|
or not. Since Task/TaskInclude objects may be in the chain, they simply
|
423
425
|
call their parents all_parents_static() method. Only Block objects in
|
424
426
|
the chain check the statically_loaded value of the parent.
|
425
|
-
|
427
|
+
"""
|
426
428
|
from ansible.playbook.task_include import TaskInclude
|
427
429
|
if self._parent:
|
428
430
|
if isinstance(self._parent, TaskInclude) and not self._parent.statically_loaded:
|
@@ -6,11 +6,8 @@ from __future__ import annotations
|
|
6
6
|
from ansible.module_utils.six import string_types
|
7
7
|
from ansible.playbook.attribute import FieldAttribute
|
8
8
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
9
|
-
from ansible.template import is_template
|
10
9
|
from ansible.utils.display import Display
|
11
10
|
|
12
|
-
from jinja2.nativetypes import NativeEnvironment
|
13
|
-
|
14
11
|
display = Display()
|
15
12
|
|
16
13
|
|
@@ -35,8 +32,7 @@ def _ensure_default_collection(collection_list=None):
|
|
35
32
|
class CollectionSearch:
|
36
33
|
|
37
34
|
# this needs to be populated before we can resolve tasks/roles/etc
|
38
|
-
collections = FieldAttribute(isa='list', listof=string_types, priority=100, default=_ensure_default_collection,
|
39
|
-
always_post_validate=True, static=True)
|
35
|
+
collections = FieldAttribute(isa='list', listof=string_types, priority=100, default=_ensure_default_collection, always_post_validate=True, static=True)
|
40
36
|
|
41
37
|
def _load_collections(self, attr, ds):
|
42
38
|
# We are always a mixin with Base, so we can validate this untemplated
|
@@ -49,14 +45,4 @@ class CollectionSearch:
|
|
49
45
|
if not ds: # don't return an empty collection list, just return None
|
50
46
|
return None
|
51
47
|
|
52
|
-
# This duplicates static attr checking logic from post_validate()
|
53
|
-
# because if the user attempts to template a collection name, it may
|
54
|
-
# error before it ever gets to the post_validate() warning (e.g. trying
|
55
|
-
# to import a role from the collection).
|
56
|
-
env = NativeEnvironment()
|
57
|
-
for collection_name in ds:
|
58
|
-
if is_template(collection_name, env):
|
59
|
-
display.warning('"collections" is not templatable, but we found: %s, '
|
60
|
-
'it will not be templated and will be used "as is".' % (collection_name))
|
61
|
-
|
62
48
|
return ds
|
ansible/playbook/conditional.py
CHANGED
@@ -17,97 +17,23 @@
|
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
|
-
import typing as t
|
21
|
-
|
22
|
-
from ansible.errors import AnsibleError, AnsibleUndefinedVariable, AnsibleTemplateError
|
23
|
-
from ansible.module_utils.common.text.converters import to_native
|
24
20
|
from ansible.playbook.attribute import FieldAttribute
|
25
|
-
from ansible.template import Templar
|
26
21
|
from ansible.utils.display import Display
|
27
22
|
|
28
23
|
display = Display()
|
29
24
|
|
30
25
|
|
31
26
|
class Conditional:
|
32
|
-
|
27
|
+
"""
|
33
28
|
This is a mix-in class, to be used with Base to allow the object
|
34
29
|
to be run conditionally when a condition is met or skipped.
|
35
|
-
|
30
|
+
"""
|
36
31
|
|
37
32
|
when = FieldAttribute(isa='list', default=list, extend=True, prepend=True)
|
38
33
|
|
39
|
-
def __init__(self,
|
40
|
-
# when used directly, this class needs a loader, but we want to
|
41
|
-
# make sure we don't trample on the existing one if this class
|
42
|
-
# is used as a mix-in with a playbook base class
|
43
|
-
if not hasattr(self, '_loader'):
|
44
|
-
if loader is None:
|
45
|
-
raise AnsibleError("a loader must be specified when using Conditional() directly")
|
46
|
-
else:
|
47
|
-
self._loader = loader
|
34
|
+
def __init__(self, *args, **kwargs):
|
48
35
|
super().__init__()
|
49
36
|
|
50
37
|
def _validate_when(self, attr, name, value):
|
51
38
|
if not isinstance(value, list):
|
52
39
|
setattr(self, name, [value])
|
53
|
-
|
54
|
-
def evaluate_conditional(self, templar: Templar, all_vars: dict[str, t.Any]) -> bool:
|
55
|
-
'''
|
56
|
-
Loops through the conditionals set on this object, returning
|
57
|
-
False if any of them evaluate as such.
|
58
|
-
'''
|
59
|
-
return self.evaluate_conditional_with_result(templar, all_vars)[0]
|
60
|
-
|
61
|
-
def evaluate_conditional_with_result(self, templar: Templar, all_vars: dict[str, t.Any]) -> tuple[bool, t.Optional[str]]:
|
62
|
-
"""Loops through the conditionals set on this object, returning
|
63
|
-
False if any of them evaluate as such as well as the condition
|
64
|
-
that was false.
|
65
|
-
"""
|
66
|
-
for conditional in self.when:
|
67
|
-
if conditional is None or conditional == "":
|
68
|
-
res = True
|
69
|
-
elif isinstance(conditional, bool):
|
70
|
-
res = conditional
|
71
|
-
else:
|
72
|
-
try:
|
73
|
-
res = self._check_conditional(conditional, templar, all_vars)
|
74
|
-
except AnsibleError as e:
|
75
|
-
raise AnsibleError(
|
76
|
-
"The conditional check '%s' failed. The error was: %s" % (to_native(conditional), to_native(e)),
|
77
|
-
obj=getattr(self, '_ds', None)
|
78
|
-
)
|
79
|
-
|
80
|
-
display.debug("Evaluated conditional (%s): %s" % (conditional, res))
|
81
|
-
if not res:
|
82
|
-
return res, conditional
|
83
|
-
|
84
|
-
return True, None
|
85
|
-
|
86
|
-
def _check_conditional(self, conditional: str, templar: Templar, all_vars: dict[str, t.Any]) -> bool:
|
87
|
-
original = conditional
|
88
|
-
templar.available_variables = all_vars
|
89
|
-
try:
|
90
|
-
if templar.is_template(conditional):
|
91
|
-
display.warning(
|
92
|
-
"conditional statements should not include jinja2 "
|
93
|
-
"templating delimiters such as {{ }} or {%% %%}. "
|
94
|
-
"Found: %s" % conditional
|
95
|
-
)
|
96
|
-
conditional = templar.template(conditional)
|
97
|
-
if isinstance(conditional, bool):
|
98
|
-
return conditional
|
99
|
-
elif conditional == "":
|
100
|
-
return False
|
101
|
-
|
102
|
-
# If the result of the first-pass template render (to resolve inline templates) is marked unsafe,
|
103
|
-
# explicitly fail since the next templating operation would never evaluate
|
104
|
-
if hasattr(conditional, '__UNSAFE__'):
|
105
|
-
raise AnsibleTemplateError('Conditional is marked as unsafe, and cannot be evaluated.')
|
106
|
-
|
107
|
-
# NOTE The spaces around True and False are intentional to short-circuit literal_eval for
|
108
|
-
# jinja2_native=False and avoid its expensive calls.
|
109
|
-
return templar.template(
|
110
|
-
"{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional,
|
111
|
-
).strip() == "True"
|
112
|
-
except AnsibleUndefinedVariable as e:
|
113
|
-
raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))
|
ansible/playbook/handler.py
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
|
+
from ansible.errors import AnsibleAssertionError
|
20
21
|
from ansible.playbook.attribute import NonInheritableFieldAttribute
|
21
22
|
from ansible.playbook.task import Task
|
22
23
|
from ansible.module_utils.six import string_types
|
@@ -34,7 +35,7 @@ class Handler(Task):
|
|
34
35
|
super(Handler, self).__init__(block=block, role=role, task_include=task_include)
|
35
36
|
|
36
37
|
def __repr__(self):
|
37
|
-
|
38
|
+
""" returns a human-readable representation of the handler """
|
38
39
|
return "HANDLER: %s" % self.get_name()
|
39
40
|
|
40
41
|
def _validate_listen(self, attr, name, value):
|
@@ -59,7 +60,12 @@ class Handler(Task):
|
|
59
60
|
return False
|
60
61
|
|
61
62
|
def remove_host(self, host):
|
62
|
-
|
63
|
+
try:
|
64
|
+
self.notified_hosts.remove(host)
|
65
|
+
except ValueError:
|
66
|
+
raise AnsibleAssertionError(
|
67
|
+
f"Attempting to remove a notification on handler '{self}' for host '{host}' but it has not been notified."
|
68
|
+
)
|
63
69
|
|
64
70
|
def clear_hosts(self):
|
65
71
|
self.notified_hosts = []
|
ansible/playbook/helpers.py
CHANGED
@@ -21,19 +21,19 @@ import os
|
|
21
21
|
|
22
22
|
from ansible import constants as C
|
23
23
|
from ansible.errors import AnsibleParserError, AnsibleUndefinedVariable, AnsibleAssertionError
|
24
|
-
from ansible.module_utils.common.text.converters import to_native
|
25
24
|
from ansible.parsing.mod_args import ModuleArgsParser
|
26
25
|
from ansible.utils.display import Display
|
26
|
+
from ansible._internal._templating._engine import TemplateEngine
|
27
27
|
|
28
28
|
display = Display()
|
29
29
|
|
30
30
|
|
31
31
|
def load_list_of_blocks(ds, play, parent_block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
32
|
-
|
32
|
+
"""
|
33
33
|
Given a list of mixed task/block data (parsed from YAML),
|
34
34
|
return a list of Block() objects, where implicit blocks
|
35
35
|
are created for each bare Task.
|
36
|
-
|
36
|
+
"""
|
37
37
|
|
38
38
|
# we import here to prevent a circular dependency with imports
|
39
39
|
from ansible.playbook.block import Block
|
@@ -80,10 +80,10 @@ def load_list_of_blocks(ds, play, parent_block=None, role=None, task_include=Non
|
|
80
80
|
|
81
81
|
|
82
82
|
def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
83
|
-
|
83
|
+
"""
|
84
84
|
Given a list of task datastructures (parsed from YAML),
|
85
85
|
return a list of Task() or TaskInclude() objects.
|
86
|
-
|
86
|
+
"""
|
87
87
|
|
88
88
|
# we import here to prevent a circular dependency with imports
|
89
89
|
from ansible.playbook.block import Block
|
@@ -92,7 +92,6 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
92
92
|
from ansible.playbook.task_include import TaskInclude
|
93
93
|
from ansible.playbook.role_include import IncludeRole
|
94
94
|
from ansible.playbook.handler_task_include import HandlerTaskInclude
|
95
|
-
from ansible.template import Templar
|
96
95
|
|
97
96
|
if not isinstance(ds, list):
|
98
97
|
raise AnsibleAssertionError('The ds (%s) should be a list but was a %s' % (ds, type(ds)))
|
@@ -105,7 +104,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
105
104
|
if 'block' in task_ds:
|
106
105
|
if use_handlers:
|
107
106
|
raise AnsibleParserError("Using a block as a handler is not supported.", obj=task_ds)
|
108
|
-
|
107
|
+
task = Block.load(
|
109
108
|
task_ds,
|
110
109
|
play=play,
|
111
110
|
parent_block=block,
|
@@ -115,18 +114,20 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
115
114
|
variable_manager=variable_manager,
|
116
115
|
loader=loader,
|
117
116
|
)
|
118
|
-
task_list.append(
|
117
|
+
task_list.append(task)
|
119
118
|
else:
|
120
119
|
args_parser = ModuleArgsParser(task_ds)
|
121
120
|
try:
|
122
121
|
(action, args, delegate_to) = args_parser.parse(skip_action_validation=True)
|
123
|
-
except AnsibleParserError as
|
122
|
+
except AnsibleParserError as ex:
|
124
123
|
# if the raises exception was created with obj=ds args, then it includes the detail
|
125
124
|
# so we dont need to add it so we can just re raise.
|
126
|
-
if
|
125
|
+
if ex.obj:
|
127
126
|
raise
|
128
127
|
# But if it wasn't, we can add the yaml object now to get more detail
|
129
|
-
|
128
|
+
# DTFIX-FUTURE: this *should* be unnecessary- check code coverage.
|
129
|
+
# Will definitely be unnecessary once we have proper contexts to consult.
|
130
|
+
raise AnsibleParserError("Error loading tasks.", obj=task_ds) from ex
|
130
131
|
|
131
132
|
if action in C._ACTION_ALL_INCLUDE_IMPORT_TASKS:
|
132
133
|
|
@@ -135,7 +136,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
135
136
|
else:
|
136
137
|
include_class = TaskInclude
|
137
138
|
|
138
|
-
|
139
|
+
task = include_class.load(
|
139
140
|
task_ds,
|
140
141
|
block=block,
|
141
142
|
role=role,
|
@@ -144,16 +145,16 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
144
145
|
loader=loader
|
145
146
|
)
|
146
147
|
|
147
|
-
all_vars = variable_manager.get_vars(play=play, task=
|
148
|
-
templar =
|
148
|
+
all_vars = variable_manager.get_vars(play=play, task=task)
|
149
|
+
templar = TemplateEngine(loader=loader, variables=all_vars)
|
149
150
|
|
150
151
|
# check to see if this include is dynamic or static:
|
151
152
|
if action in C._ACTION_IMPORT_TASKS:
|
152
|
-
if
|
153
|
+
if task.loop is not None:
|
153
154
|
raise AnsibleParserError("You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.", obj=task_ds)
|
154
155
|
|
155
156
|
# we set a flag to indicate this include was static
|
156
|
-
|
157
|
+
task.statically_loaded = True
|
157
158
|
|
158
159
|
# handle relative includes by walking up the list of parent include
|
159
160
|
# tasks and checking the relative result to see if it exists
|
@@ -168,26 +169,14 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
168
169
|
if not isinstance(parent_include, TaskInclude):
|
169
170
|
parent_include = parent_include._parent
|
170
171
|
continue
|
171
|
-
|
172
|
-
parent_include_dir = os.path.dirname(templar.template(parent_include.args.get('_raw_params')))
|
173
|
-
except AnsibleUndefinedVariable as e:
|
174
|
-
if not parent_include.statically_loaded:
|
175
|
-
raise AnsibleParserError(
|
176
|
-
"Error when evaluating variable in dynamic parent include path: %s. "
|
177
|
-
"When using static imports, the parent dynamic include cannot utilize host facts "
|
178
|
-
"or variables from inventory" % parent_include.args.get('_raw_params'),
|
179
|
-
obj=task_ds,
|
180
|
-
suppress_extended_error=True,
|
181
|
-
orig_exc=e
|
182
|
-
)
|
183
|
-
raise
|
172
|
+
parent_include_dir = os.path.dirname(parent_include.args.get('_raw_params'))
|
184
173
|
if cumulative_path is None:
|
185
174
|
cumulative_path = parent_include_dir
|
186
175
|
elif not os.path.isabs(cumulative_path):
|
187
176
|
cumulative_path = os.path.join(parent_include_dir, cumulative_path)
|
188
|
-
include_target = templar.template(
|
189
|
-
if
|
190
|
-
new_basedir = os.path.join(
|
177
|
+
include_target = templar.template(task.args['_raw_params'])
|
178
|
+
if task._role:
|
179
|
+
new_basedir = os.path.join(task._role._role_path, subdir, cumulative_path)
|
191
180
|
include_file = loader.path_dwim_relative(new_basedir, subdir, include_target)
|
192
181
|
else:
|
193
182
|
include_file = loader.path_dwim_relative(loader.get_basedir(), cumulative_path, include_target)
|
@@ -200,22 +189,21 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
200
189
|
|
201
190
|
if not found:
|
202
191
|
try:
|
203
|
-
include_target = templar.template(
|
204
|
-
except AnsibleUndefinedVariable as
|
192
|
+
include_target = templar.template(task.args['_raw_params'])
|
193
|
+
except AnsibleUndefinedVariable as ex:
|
205
194
|
raise AnsibleParserError(
|
206
|
-
"Error when evaluating variable in import path
|
207
|
-
"When using static imports, ensure that any variables used in their names are defined in vars/vars_files\n"
|
195
|
+
message=f"Error when evaluating variable in import path {task.args['_raw_params']!r}.",
|
196
|
+
help_text="When using static imports, ensure that any variables used in their names are defined in vars/vars_files\n"
|
208
197
|
"or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory\n"
|
209
|
-
"sources like group or host vars."
|
198
|
+
"sources like group or host vars.",
|
210
199
|
obj=task_ds,
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
include_file = loader.path_dwim_relative(t._role._role_path, subdir, include_target)
|
200
|
+
) from ex
|
201
|
+
if task._role:
|
202
|
+
include_file = loader.path_dwim_relative(task._role._role_path, subdir, include_target)
|
215
203
|
else:
|
216
204
|
include_file = loader.path_dwim(include_target)
|
217
205
|
|
218
|
-
data = loader.load_from_file(include_file)
|
206
|
+
data = loader.load_from_file(include_file, trusted_as_template=True)
|
219
207
|
if not data:
|
220
208
|
display.warning('file %s is empty and had no tasks to include' % include_file)
|
221
209
|
continue
|
@@ -228,7 +216,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
228
216
|
# nested includes, and we want the include order printed correctly
|
229
217
|
display.vv("statically imported: %s" % include_file)
|
230
218
|
|
231
|
-
ti_copy =
|
219
|
+
ti_copy = task.copy(exclude_parent=True)
|
232
220
|
ti_copy._parent = block
|
233
221
|
included_blocks = load_list_of_blocks(
|
234
222
|
data,
|
@@ -246,7 +234,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
246
234
|
# now we extend the tags on each of the included blocks
|
247
235
|
for b in included_blocks:
|
248
236
|
b.tags = list(set(b.tags).union(tags))
|
249
|
-
# END
|
237
|
+
# FIXME - END
|
250
238
|
|
251
239
|
# FIXME: handlers shouldn't need this special handling, but do
|
252
240
|
# right now because they don't iterate blocks correctly
|
@@ -256,7 +244,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
256
244
|
else:
|
257
245
|
task_list.extend(included_blocks)
|
258
246
|
else:
|
259
|
-
task_list.append(
|
247
|
+
task_list.append(task)
|
260
248
|
|
261
249
|
elif action in C._ACTION_ALL_PROPER_INCLUDE_IMPORT_ROLES:
|
262
250
|
if use_handlers:
|
@@ -280,7 +268,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
280
268
|
|
281
269
|
# template the role name now, if needed
|
282
270
|
all_vars = variable_manager.get_vars(play=play, task=ir)
|
283
|
-
templar =
|
271
|
+
templar = TemplateEngine(loader=loader, variables=all_vars)
|
284
272
|
ir.post_validate(templar=templar)
|
285
273
|
ir._role_name = templar.template(ir._role_name)
|
286
274
|
|
@@ -292,15 +280,15 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
|
292
280
|
task_list.append(ir)
|
293
281
|
else:
|
294
282
|
if use_handlers:
|
295
|
-
|
296
|
-
if
|
297
|
-
raise AnsibleParserError("Cannot execute 'end_role' from a handler")
|
283
|
+
task = Handler.load(task_ds, block=block, role=role, task_include=task_include, variable_manager=variable_manager, loader=loader)
|
284
|
+
if task._get_meta() == "end_role":
|
285
|
+
raise AnsibleParserError("Cannot execute 'end_role' from a handler", obj=task)
|
298
286
|
else:
|
299
|
-
|
300
|
-
if
|
301
|
-
raise AnsibleParserError("Cannot execute 'end_role' from outside of a role")
|
287
|
+
task = Task.load(task_ds, block=block, role=role, task_include=task_include, variable_manager=variable_manager, loader=loader)
|
288
|
+
if task._get_meta() == "end_role" and role is None:
|
289
|
+
raise AnsibleParserError("Cannot execute 'end_role' from outside of a role", obj=task)
|
302
290
|
|
303
|
-
task_list.append(
|
291
|
+
task_list.append(task)
|
304
292
|
|
305
293
|
return task_list
|
306
294
|
|