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
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
from __future__ import annotations
|
8
8
|
|
9
|
-
DOCUMENTATION =
|
9
|
+
DOCUMENTATION = """
|
10
10
|
---
|
11
11
|
module: yum_repository
|
12
12
|
author: Jiri Tyr (@jtyr)
|
@@ -385,9 +385,9 @@ notes:
|
|
385
385
|
on disk until you run C(yum clean all). Use a notification handler for this.
|
386
386
|
- "The O(ignore:params) parameter was removed in Ansible 2.5 due to circumventing Ansible's parameter
|
387
387
|
handling"
|
388
|
-
|
388
|
+
"""
|
389
389
|
|
390
|
-
EXAMPLES =
|
390
|
+
EXAMPLES = """
|
391
391
|
- name: Add repository
|
392
392
|
ansible.builtin.yum_repository:
|
393
393
|
name: epel
|
@@ -427,9 +427,9 @@ EXAMPLES = '''
|
|
427
427
|
name: epel
|
428
428
|
file: external_repos
|
429
429
|
state: absent
|
430
|
-
|
430
|
+
"""
|
431
431
|
|
432
|
-
RETURN =
|
432
|
+
RETURN = """
|
433
433
|
repo:
|
434
434
|
description: repository name
|
435
435
|
returned: success
|
@@ -440,7 +440,7 @@ state:
|
|
440
440
|
returned: success
|
441
441
|
type: str
|
442
442
|
sample: "present"
|
443
|
-
|
443
|
+
"""
|
444
444
|
|
445
445
|
import configparser
|
446
446
|
import os
|
ansible/parsing/ajson.py
CHANGED
@@ -1,40 +1,22 @@
|
|
1
1
|
# Copyright: (c) 2018, Ansible Project
|
2
2
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
|
4
|
-
from __future__ import annotations
|
4
|
+
from __future__ import annotations as _annotations
|
5
5
|
|
6
|
-
import
|
6
|
+
# from ansible.utils.display import Display as _Display
|
7
7
|
|
8
|
-
# Imported for backwards compat
|
9
|
-
from ansible.module_utils.common.json import AnsibleJSONEncoder # pylint: disable=unused-import
|
10
8
|
|
11
|
-
|
12
|
-
from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
|
13
|
-
from ansible.utils.unsafe_proxy import wrap_var
|
9
|
+
# DTFIX-RELEASE: The pylint deprecated checker does not detect `Display().deprecated` calls, of which we have many.
|
14
10
|
|
11
|
+
# deprecated: description='deprecate ajson' core_version='2.23'
|
12
|
+
# _Display().deprecated(
|
13
|
+
# msg='The `ansible.parsing.ajson` module is deprecated.',
|
14
|
+
# version='2.27',
|
15
|
+
# help_text="", # DTFIX-RELEASE: complete this help text
|
16
|
+
# )
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
kwargs['object_hook'] = self.object_hook
|
22
|
-
super(AnsibleJSONDecoder, self).__init__(*args, **kwargs)
|
23
|
-
|
24
|
-
@classmethod
|
25
|
-
def set_secrets(cls, secrets):
|
26
|
-
cls._vaults['default'] = VaultLib(secrets=secrets)
|
27
|
-
|
28
|
-
def object_hook(self, pairs):
|
29
|
-
for key in pairs:
|
30
|
-
value = pairs[key]
|
31
|
-
|
32
|
-
if key == '__ansible_vault':
|
33
|
-
value = AnsibleVaultEncryptedUnicode(value)
|
34
|
-
if self._vaults:
|
35
|
-
value.vault = self._vaults['default']
|
36
|
-
return value
|
37
|
-
elif key == '__ansible_unsafe':
|
38
|
-
return wrap_var(value)
|
39
|
-
|
40
|
-
return pairs
|
18
|
+
# Imported for backward compat
|
19
|
+
from ansible.module_utils.common.json import ( # pylint: disable=unused-import
|
20
|
+
_AnsibleJSONEncoder as AnsibleJSONEncoder,
|
21
|
+
_AnsibleJSONDecoder as AnsibleJSONDecoder,
|
22
|
+
)
|
ansible/parsing/dataloader.py
CHANGED
@@ -2,23 +2,28 @@
|
|
2
2
|
# Copyright: (c) 2017, Ansible Project
|
3
3
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
4
4
|
|
5
|
+
from __future__ import annotations
|
5
6
|
from __future__ import annotations
|
6
7
|
|
7
8
|
import copy
|
8
9
|
import os
|
9
10
|
import os.path
|
11
|
+
import pathlib
|
10
12
|
import re
|
11
13
|
import tempfile
|
12
14
|
import typing as t
|
13
15
|
|
14
16
|
from ansible import constants as C
|
15
17
|
from ansible.errors import AnsibleFileNotFound, AnsibleParserError
|
18
|
+
from ansible._internal._errors import _utils
|
16
19
|
from ansible.module_utils.basic import is_executable
|
20
|
+
from ansible._internal._datatag._tags import Origin, TrustedAsTemplate, SourceWasEncrypted
|
21
|
+
from ansible.module_utils._internal._datatag import AnsibleTagHelper
|
17
22
|
from ansible.module_utils.six import binary_type, text_type
|
18
23
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
19
24
|
from ansible.parsing.quoting import unquote
|
20
25
|
from ansible.parsing.utils.yaml import from_yaml
|
21
|
-
from ansible.parsing.vault import VaultLib, is_encrypted, is_encrypted_file,
|
26
|
+
from ansible.parsing.vault import VaultLib, is_encrypted, is_encrypted_file, PromptVaultSecret
|
22
27
|
from ansible.utils.path import unfrackpath
|
23
28
|
from ansible.utils.display import Display
|
24
29
|
|
@@ -32,7 +37,7 @@ RE_TASKS = re.compile(u'(?:^|%s)+tasks%s?$' % (os.path.sep, os.path.sep))
|
|
32
37
|
|
33
38
|
class DataLoader:
|
34
39
|
|
35
|
-
|
40
|
+
"""
|
36
41
|
The DataLoader class is used to load and parse YAML or JSON content,
|
37
42
|
either from a given file name or from a string that was previously
|
38
43
|
read in through other means. A Vault password can be specified, and
|
@@ -47,7 +52,7 @@ class DataLoader:
|
|
47
52
|
# optionally: dl.set_vault_secrets([('default', ansible.parsing.vault.PrompVaultSecret(...),)])
|
48
53
|
ds = dl.load('...')
|
49
54
|
ds = dl.load_from_file('/path/to/file')
|
50
|
-
|
55
|
+
"""
|
51
56
|
|
52
57
|
def __init__(self):
|
53
58
|
|
@@ -73,12 +78,19 @@ class DataLoader:
|
|
73
78
|
def set_vault_secrets(self, vault_secrets: list[tuple[str, PromptVaultSecret]] | None) -> None:
|
74
79
|
self._vault.secrets = vault_secrets
|
75
80
|
|
76
|
-
def load(
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
81
|
+
def load(
|
82
|
+
self,
|
83
|
+
data: str,
|
84
|
+
file_name: str | None = None, # DTFIX-RELEASE: consider deprecating this in favor of tagging Origin on data
|
85
|
+
show_content: bool = True, # DTFIX-RELEASE: consider future deprecation, but would need RedactAnnotatedSourceContext public
|
86
|
+
json_only: bool = False,
|
87
|
+
) -> t.Any:
|
88
|
+
"""Backwards compat for now"""
|
89
|
+
with _utils.RedactAnnotatedSourceContext.when(not show_content):
|
90
|
+
return from_yaml(data=data, file_name=file_name, json_only=json_only)
|
91
|
+
|
92
|
+
def load_from_file(self, file_name: str, cache: str = 'all', unsafe: bool = False, json_only: bool = False, trusted_as_template: bool = False) -> t.Any:
|
93
|
+
"""
|
82
94
|
Loads data from a file, which can contain either JSON or YAML.
|
83
95
|
|
84
96
|
:param file_name: The name of the file to load data from.
|
@@ -86,7 +98,7 @@ class DataLoader:
|
|
86
98
|
:param unsafe: If True, returns the parsed data as-is without deep copying.
|
87
99
|
:param json_only: If True, only loads JSON data from the file.
|
88
100
|
:return: The loaded data, optionally deep-copied for safety.
|
89
|
-
|
101
|
+
"""
|
90
102
|
|
91
103
|
# Resolve the file name
|
92
104
|
file_name = self.path_dwim(file_name)
|
@@ -98,16 +110,22 @@ class DataLoader:
|
|
98
110
|
if cache != 'none' and file_name in self._FILE_CACHE:
|
99
111
|
parsed_data = self._FILE_CACHE[file_name]
|
100
112
|
else:
|
101
|
-
|
102
|
-
(b_file_data, show_content) = self._get_file_contents(file_name)
|
113
|
+
file_data = self.get_text_file_contents(file_name)
|
103
114
|
|
104
|
-
|
105
|
-
|
115
|
+
if trusted_as_template:
|
116
|
+
file_data = TrustedAsTemplate().tag(file_data)
|
117
|
+
|
118
|
+
parsed_data = self.load(data=file_data, file_name=file_name, json_only=json_only)
|
119
|
+
|
120
|
+
# only tagging the container, used by include_vars to determine if vars should be shown or not
|
121
|
+
# this is a temporary measure until a proper data senitivity system is in place
|
122
|
+
if SourceWasEncrypted.is_tagged_on(file_data):
|
123
|
+
parsed_data = SourceWasEncrypted().tag(parsed_data)
|
106
124
|
|
107
125
|
# Cache the file contents for next time based on the cache option
|
108
126
|
if cache == 'all':
|
109
127
|
self._FILE_CACHE[file_name] = parsed_data
|
110
|
-
elif cache == 'vaulted' and
|
128
|
+
elif cache == 'vaulted' and SourceWasEncrypted.is_tagged_on(file_data):
|
111
129
|
self._FILE_CACHE[file_name] = parsed_data
|
112
130
|
|
113
131
|
# Return the parsed data, optionally deep-copied for safety
|
@@ -133,25 +151,51 @@ class DataLoader:
|
|
133
151
|
return os.listdir(path)
|
134
152
|
|
135
153
|
def is_executable(self, path: str) -> bool:
|
136
|
-
|
154
|
+
"""is the given path executable?"""
|
137
155
|
path = self.path_dwim(path)
|
138
156
|
return is_executable(path)
|
139
157
|
|
140
|
-
def _decrypt_if_vault_data(self,
|
141
|
-
|
158
|
+
def _decrypt_if_vault_data(self, b_data: bytes) -> tuple[bytes, bool]:
|
159
|
+
"""Decrypt b_vault_data if encrypted and return b_data and the show_content flag"""
|
160
|
+
|
161
|
+
if encrypted_source := is_encrypted(b_data):
|
162
|
+
b_data = self._vault.decrypt(b_data)
|
163
|
+
|
164
|
+
return b_data, not encrypted_source
|
165
|
+
|
166
|
+
def get_text_file_contents(self, file_name: str, encoding: str | None = None) -> str:
|
167
|
+
"""
|
168
|
+
Returns an `Origin` tagged string with the content of the specified (DWIM-expanded for relative) file path, decrypting if necessary.
|
169
|
+
Callers must only specify `encoding` when the user can configure it, as error messages in that case will imply configurability.
|
170
|
+
If `encoding` is not specified, UTF-8 will be used.
|
171
|
+
"""
|
172
|
+
bytes_content, source_was_plaintext = self._get_file_contents(file_name)
|
173
|
+
|
174
|
+
if encoding is None:
|
175
|
+
encoding = 'utf-8'
|
176
|
+
help_text = 'This file must be UTF-8 encoded.'
|
177
|
+
else:
|
178
|
+
help_text = 'Ensure the correct encoding was specified.'
|
179
|
+
|
180
|
+
try:
|
181
|
+
str_content = bytes_content.decode(encoding=encoding, errors='strict')
|
182
|
+
except UnicodeDecodeError:
|
183
|
+
str_content = bytes_content.decode(encoding=encoding, errors='surrogateescape')
|
142
184
|
|
143
|
-
|
144
|
-
|
145
|
-
|
185
|
+
display.deprecated(
|
186
|
+
msg=f"File {file_name!r} could not be decoded as {encoding!r}. Invalid content has been escaped.",
|
187
|
+
version="2.23",
|
188
|
+
# obj intentionally omitted since there's no value in showing its contents
|
189
|
+
help_text=help_text,
|
190
|
+
)
|
146
191
|
|
147
|
-
|
148
|
-
|
192
|
+
if not source_was_plaintext:
|
193
|
+
str_content = SourceWasEncrypted().tag(str_content)
|
149
194
|
|
150
|
-
|
151
|
-
return b_data, show_content
|
195
|
+
return AnsibleTagHelper.tag_copy(bytes_content, str_content)
|
152
196
|
|
153
197
|
def _get_file_contents(self, file_name: str) -> tuple[bytes, bool]:
|
154
|
-
|
198
|
+
"""
|
155
199
|
Reads the file contents from the given file name
|
156
200
|
|
157
201
|
If the contents are vault-encrypted, it will decrypt them and return
|
@@ -162,40 +206,41 @@ class DataLoader:
|
|
162
206
|
:raises AnsibleFileNotFound: if the file_name does not refer to a file
|
163
207
|
:raises AnsibleParserError: if we were unable to read the file
|
164
208
|
:return: Returns a byte string of the file contents
|
165
|
-
|
166
|
-
if not file_name or not isinstance(file_name,
|
167
|
-
raise
|
209
|
+
"""
|
210
|
+
if not file_name or not isinstance(file_name, str):
|
211
|
+
raise TypeError(f"Invalid filename {file_name!r}.")
|
168
212
|
|
169
|
-
|
170
|
-
# This is what we really want but have to fix unittests to make it pass
|
171
|
-
# if not os.path.exists(b_file_name) or not os.path.isfile(b_file_name):
|
172
|
-
if not self.path_exists(b_file_name):
|
173
|
-
raise AnsibleFileNotFound("Unable to retrieve file contents", file_name=file_name)
|
213
|
+
file_name = self.path_dwim(file_name)
|
174
214
|
|
175
215
|
try:
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
216
|
+
data = pathlib.Path(file_name).read_bytes()
|
217
|
+
except FileNotFoundError as ex:
|
218
|
+
# DTFIX-FUTURE: why not just let the builtin one fly?
|
219
|
+
raise AnsibleFileNotFound("Unable to retrieve file contents.", file_name=file_name) from ex
|
220
|
+
except (IOError, OSError) as ex:
|
221
|
+
raise AnsibleParserError(f"An error occurred while trying to read the file {file_name!r}.") from ex
|
222
|
+
|
223
|
+
data = Origin(path=file_name).tag(data)
|
224
|
+
|
225
|
+
return self._decrypt_if_vault_data(data)
|
181
226
|
|
182
227
|
def get_basedir(self) -> str:
|
183
|
-
|
228
|
+
""" returns the current basedir """
|
184
229
|
return self._basedir
|
185
230
|
|
186
231
|
def set_basedir(self, basedir: str) -> None:
|
187
|
-
|
232
|
+
""" sets the base directory, used to find files when a relative path is given """
|
188
233
|
|
189
234
|
if basedir is not None:
|
190
235
|
self._basedir = to_text(basedir)
|
191
236
|
|
192
237
|
def path_dwim(self, given: str) -> str:
|
193
|
-
|
238
|
+
"""
|
194
239
|
make relative paths work like folks expect.
|
195
|
-
|
240
|
+
"""
|
196
241
|
|
197
|
-
given = unquote(given)
|
198
242
|
given = to_text(given, errors='surrogate_or_strict')
|
243
|
+
given = unquote(given)
|
199
244
|
|
200
245
|
if given.startswith(to_text(os.path.sep)) or given.startswith(u'~'):
|
201
246
|
path = given
|
@@ -206,7 +251,7 @@ class DataLoader:
|
|
206
251
|
return unfrackpath(path, follow=False)
|
207
252
|
|
208
253
|
def _is_role(self, path: str) -> bool:
|
209
|
-
|
254
|
+
""" imperfect role detection, roles are still valid w/o tasks|meta/main.yml|yaml|etc """
|
210
255
|
|
211
256
|
b_path = to_bytes(path, errors='surrogate_or_strict')
|
212
257
|
b_path_dirname = os.path.dirname(b_path)
|
@@ -240,13 +285,13 @@ class DataLoader:
|
|
240
285
|
return False
|
241
286
|
|
242
287
|
def path_dwim_relative(self, path: str, dirname: str, source: str, is_role: bool = False) -> str:
|
243
|
-
|
288
|
+
"""
|
244
289
|
find one file in either a role or playbook dir with or without
|
245
290
|
explicitly named dirname subdirs
|
246
291
|
|
247
292
|
Used in action plugins and lookups to find supplemental files that
|
248
293
|
could be in either place.
|
249
|
-
|
294
|
+
"""
|
250
295
|
|
251
296
|
search = []
|
252
297
|
source = to_text(source, errors='surrogate_or_strict')
|
@@ -295,7 +340,7 @@ class DataLoader:
|
|
295
340
|
return candidate
|
296
341
|
|
297
342
|
def path_dwim_relative_stack(self, paths: list[str], dirname: str, source: str, is_role: bool = False) -> str:
|
298
|
-
|
343
|
+
"""
|
299
344
|
find one file in first path in stack taking roles into account and adding play basedir as fallback
|
300
345
|
|
301
346
|
:arg paths: A list of text strings which are the paths to look for the filename in.
|
@@ -305,7 +350,7 @@ class DataLoader:
|
|
305
350
|
:rtype: A text string
|
306
351
|
:returns: An absolute path to the filename ``source`` if found
|
307
352
|
:raises: An AnsibleFileNotFound Exception if the file is found to exist in the search paths
|
308
|
-
|
353
|
+
"""
|
309
354
|
b_dirname = to_bytes(dirname, errors='surrogate_or_strict')
|
310
355
|
b_source = to_bytes(source, errors='surrogate_or_strict')
|
311
356
|
|
@@ -353,7 +398,7 @@ class DataLoader:
|
|
353
398
|
return result
|
354
399
|
|
355
400
|
def _create_content_tempfile(self, content: str | bytes) -> str:
|
356
|
-
|
401
|
+
""" Create a tempfile containing defined content """
|
357
402
|
fd, content_tempfile = tempfile.mkstemp(dir=C.DEFAULT_LOCAL_TMP)
|
358
403
|
f = os.fdopen(fd, 'wb')
|
359
404
|
content = to_bytes(content)
|
@@ -392,19 +437,19 @@ class DataLoader:
|
|
392
437
|
# if the file is encrypted and no password was specified,
|
393
438
|
# the decrypt call would throw an error, but we check first
|
394
439
|
# since the decrypt function doesn't know the file name
|
395
|
-
data = f.read()
|
440
|
+
data = Origin(path=real_path).tag(f.read())
|
396
441
|
if not self._vault.secrets:
|
397
442
|
raise AnsibleParserError("A vault password or secret must be specified to decrypt %s" % to_native(file_path))
|
398
443
|
|
399
|
-
data = self._vault.decrypt(data
|
444
|
+
data = self._vault.decrypt(data)
|
400
445
|
# Make a temp file
|
401
446
|
real_path = self._create_content_tempfile(data)
|
402
447
|
self._tempfiles.add(real_path)
|
403
448
|
|
404
449
|
return real_path
|
405
450
|
|
406
|
-
except (IOError, OSError) as
|
407
|
-
raise AnsibleParserError("an error occurred while trying to read the file
|
451
|
+
except (IOError, OSError) as ex:
|
452
|
+
raise AnsibleParserError(f"an error occurred while trying to read the file {to_text(real_path)!r}.") from ex
|
408
453
|
|
409
454
|
def cleanup_tmp_file(self, file_path: str) -> None:
|
410
455
|
"""
|
ansible/parsing/mod_args.py
CHANGED
@@ -19,13 +19,15 @@ from __future__ import annotations
|
|
19
19
|
|
20
20
|
import ansible.constants as C
|
21
21
|
from ansible.errors import AnsibleParserError, AnsibleError, AnsibleAssertionError
|
22
|
+
from ansible.module_utils._internal._datatag import AnsibleTagHelper
|
22
23
|
from ansible.module_utils.six import string_types
|
24
|
+
from ansible.module_utils.common.sentinel import Sentinel
|
23
25
|
from ansible.module_utils.common.text.converters import to_text
|
24
26
|
from ansible.parsing.splitter import parse_kv, split_args
|
27
|
+
from ansible.parsing.vault import EncryptedString
|
25
28
|
from ansible.plugins.loader import module_loader, action_loader
|
26
|
-
from ansible.
|
29
|
+
from ansible._internal._templating._engine import TemplateEngine
|
27
30
|
from ansible.utils.fqcn import add_internal_fqcns
|
28
|
-
from ansible.utils.sentinel import Sentinel
|
29
31
|
|
30
32
|
|
31
33
|
# modules formated for user msg
|
@@ -129,26 +131,26 @@ class ModuleArgsParser:
|
|
129
131
|
self._task_attrs.update(['local_action', 'static'])
|
130
132
|
self._task_attrs = frozenset(self._task_attrs)
|
131
133
|
|
132
|
-
|
133
|
-
|
134
|
-
def _split_module_string(self, module_string):
|
135
|
-
'''
|
134
|
+
def _split_module_string(self, module_string: str) -> tuple[str, str]:
|
135
|
+
"""
|
136
136
|
when module names are expressed like:
|
137
137
|
action: copy src=a dest=b
|
138
138
|
the first part of the string is the name of the module
|
139
139
|
and the rest are strings pertaining to the arguments.
|
140
|
-
|
140
|
+
"""
|
141
141
|
|
142
142
|
tokens = split_args(module_string)
|
143
143
|
if len(tokens) > 1:
|
144
|
-
|
144
|
+
result = (tokens[0].strip(), " ".join(tokens[1:]))
|
145
145
|
else:
|
146
|
-
|
146
|
+
result = (tokens[0].strip(), "")
|
147
|
+
|
148
|
+
return AnsibleTagHelper.tag_copy(module_string, result[0]), AnsibleTagHelper.tag_copy(module_string, result[1])
|
147
149
|
|
148
150
|
def _normalize_parameters(self, thing, action=None, additional_args=None):
|
149
|
-
|
151
|
+
"""
|
150
152
|
arguments can be fuzzy. Deal with all the forms.
|
151
|
-
|
153
|
+
"""
|
152
154
|
|
153
155
|
additional_args = {} if additional_args is None else additional_args
|
154
156
|
|
@@ -157,9 +159,9 @@ class ModuleArgsParser:
|
|
157
159
|
# than those which may be parsed/normalized next
|
158
160
|
final_args = dict()
|
159
161
|
if additional_args:
|
160
|
-
if isinstance(additional_args,
|
161
|
-
|
162
|
-
if
|
162
|
+
if isinstance(additional_args, (str, EncryptedString)):
|
163
|
+
# DTFIX-RELEASE: should this be is_possibly_template?
|
164
|
+
if TemplateEngine().is_template(additional_args):
|
163
165
|
final_args['_variable_params'] = additional_args
|
164
166
|
else:
|
165
167
|
raise AnsibleParserError("Complex args containing variables cannot use bare variables (without Jinja2 delimiters), "
|
@@ -205,7 +207,7 @@ class ModuleArgsParser:
|
|
205
207
|
return (action, final_args)
|
206
208
|
|
207
209
|
def _normalize_new_style_args(self, thing, action):
|
208
|
-
|
210
|
+
"""
|
209
211
|
deals with fuzziness in new style module invocations
|
210
212
|
accepting key=value pairs and dictionaries, and returns
|
211
213
|
a dictionary of arguments
|
@@ -215,7 +217,7 @@ class ModuleArgsParser:
|
|
215
217
|
{'region': 'xyz'}, 'ec2'
|
216
218
|
standardized outputs like:
|
217
219
|
{ _raw_params: 'echo hi', _uses_shell: True }
|
218
|
-
|
220
|
+
"""
|
219
221
|
|
220
222
|
if isinstance(thing, dict):
|
221
223
|
# form is like: { xyz: { x: 2, y: 3 } }
|
@@ -224,6 +226,8 @@ class ModuleArgsParser:
|
|
224
226
|
# form is like: copy: src=a dest=b
|
225
227
|
check_raw = action in FREEFORM_ACTIONS
|
226
228
|
args = parse_kv(thing, check_raw=check_raw)
|
229
|
+
elif isinstance(thing, EncryptedString):
|
230
|
+
args = dict(_raw_params=thing)
|
227
231
|
elif thing is None:
|
228
232
|
# this can happen with modules which take no params, like ping:
|
229
233
|
args = None
|
@@ -232,7 +236,7 @@ class ModuleArgsParser:
|
|
232
236
|
return args
|
233
237
|
|
234
238
|
def _normalize_old_style_args(self, thing):
|
235
|
-
|
239
|
+
"""
|
236
240
|
deals with fuzziness in old-style (action/local_action) module invocations
|
237
241
|
returns tuple of (module_name, dictionary_args)
|
238
242
|
|
@@ -242,7 +246,7 @@ class ModuleArgsParser:
|
|
242
246
|
{'module': 'ec2', 'x': 1 }
|
243
247
|
standardized outputs like:
|
244
248
|
('ec2', { 'x': 1} )
|
245
|
-
|
249
|
+
"""
|
246
250
|
|
247
251
|
action = None
|
248
252
|
args = None
|
@@ -270,13 +274,11 @@ class ModuleArgsParser:
|
|
270
274
|
return (action, args)
|
271
275
|
|
272
276
|
def parse(self, skip_action_validation=False):
|
273
|
-
|
277
|
+
"""
|
274
278
|
Given a task in one of the supported forms, parses and returns
|
275
279
|
returns the action, arguments, and delegate_to values for the
|
276
280
|
task, dealing with all sorts of levels of fuzziness.
|
277
|
-
|
278
|
-
|
279
|
-
thing = None
|
281
|
+
"""
|
280
282
|
|
281
283
|
action = None
|
282
284
|
delegate_to = self._task_ds.get('delegate_to', Sentinel)
|
@@ -292,7 +294,7 @@ class ModuleArgsParser:
|
|
292
294
|
if 'action' in self._task_ds:
|
293
295
|
# an old school 'action' statement
|
294
296
|
thing = self._task_ds['action']
|
295
|
-
action, args = self._normalize_parameters(thing,
|
297
|
+
action, args = self._normalize_parameters(thing, additional_args=additional_args)
|
296
298
|
|
297
299
|
# local_action
|
298
300
|
if 'local_action' in self._task_ds:
|
@@ -301,12 +303,7 @@ class ModuleArgsParser:
|
|
301
303
|
raise AnsibleParserError("action and local_action are mutually exclusive", obj=self._task_ds)
|
302
304
|
thing = self._task_ds.get('local_action', '')
|
303
305
|
delegate_to = 'localhost'
|
304
|
-
action, args = self._normalize_parameters(thing,
|
305
|
-
|
306
|
-
if action is not None and not skip_action_validation:
|
307
|
-
context = _get_action_context(action, self._collection_list)
|
308
|
-
if context is not None and context.resolved:
|
309
|
-
self.resolved_action = context.resolved_fqcn
|
306
|
+
action, args = self._normalize_parameters(thing, additional_args=additional_args)
|
310
307
|
|
311
308
|
# module: <stuff> is the more new-style invocation
|
312
309
|
|
@@ -315,14 +312,13 @@ class ModuleArgsParser:
|
|
315
312
|
|
316
313
|
# walk the filtered input dictionary to see if we recognize a module name
|
317
314
|
for item, value in non_task_ds.items():
|
318
|
-
context = None
|
319
|
-
is_action_candidate = False
|
320
315
|
if item in BUILTIN_TASKS:
|
321
316
|
is_action_candidate = True
|
322
317
|
elif skip_action_validation:
|
323
318
|
is_action_candidate = True
|
324
319
|
else:
|
325
320
|
try:
|
321
|
+
# DTFIX-FUTURE: extract to a helper method, shared with Task.post_validate_args
|
326
322
|
context = _get_action_context(item, self._collection_list)
|
327
323
|
except AnsibleError as e:
|
328
324
|
if e.obj is None:
|
@@ -336,9 +332,6 @@ class ModuleArgsParser:
|
|
336
332
|
if action is not None:
|
337
333
|
raise AnsibleParserError("conflicting action statements: %s, %s" % (action, item), obj=self._task_ds)
|
338
334
|
|
339
|
-
if context is not None and context.resolved:
|
340
|
-
self.resolved_action = context.resolved_fqcn
|
341
|
-
|
342
335
|
action = item
|
343
336
|
thing = value
|
344
337
|
action, args = self._normalize_parameters(thing, action=action, additional_args=additional_args)
|
@@ -353,14 +346,5 @@ class ModuleArgsParser:
|
|
353
346
|
else:
|
354
347
|
raise AnsibleParserError("no module/action detected in task.",
|
355
348
|
obj=self._task_ds)
|
356
|
-
elif args.get('_raw_params', '') != '' and action not in RAW_PARAM_MODULES:
|
357
|
-
templar = Templar(loader=None)
|
358
|
-
raw_params = args.pop('_raw_params')
|
359
|
-
if templar.is_template(raw_params):
|
360
|
-
args['_variable_params'] = raw_params
|
361
|
-
else:
|
362
|
-
raise AnsibleParserError(
|
363
|
-
"this task '%s' has extra params, which is only allowed in the following modules: %s" % (action, ", ".join(RAW_PARAM_MODULES_SIMPLE)),
|
364
|
-
obj=self._task_ds)
|
365
349
|
|
366
|
-
return
|
350
|
+
return action, args, delegate_to
|