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
@@ -160,7 +160,7 @@ def _read_password_file(b_path):
|
|
160
160
|
|
161
161
|
|
162
162
|
def _gen_candidate_chars(characters):
|
163
|
-
|
163
|
+
"""Generate a string containing all valid chars as defined by ``characters``
|
164
164
|
|
165
165
|
:arg characters: A list of character specs. The character specs are
|
166
166
|
shorthand names for sets of characters like 'digits', 'ascii_letters',
|
@@ -181,7 +181,7 @@ def _gen_candidate_chars(characters):
|
|
181
181
|
the question mark and pipe characters directly. Return will be the string::
|
182
182
|
|
183
183
|
u'0123456789?|'
|
184
|
-
|
184
|
+
"""
|
185
185
|
chars = []
|
186
186
|
for chars_spec in characters:
|
187
187
|
# getattr from string expands things like "ascii_letters" and "digits"
|
@@ -192,11 +192,11 @@ def _gen_candidate_chars(characters):
|
|
192
192
|
|
193
193
|
|
194
194
|
def _parse_content(content):
|
195
|
-
|
195
|
+
"""parse our password data format into password and salt
|
196
196
|
|
197
197
|
:arg content: The data read from the file
|
198
198
|
:returns: password and salt
|
199
|
-
|
199
|
+
"""
|
200
200
|
password = content
|
201
201
|
salt = None
|
202
202
|
ident = None
|
@@ -350,7 +350,7 @@ class LookupModule(LookupBase):
|
|
350
350
|
|
351
351
|
return relpath, params
|
352
352
|
|
353
|
-
def run(self, terms, variables, **kwargs):
|
353
|
+
def run(self, terms, variables=None, **kwargs):
|
354
354
|
ret = []
|
355
355
|
|
356
356
|
for term in terms:
|
ansible/plugins/lookup/pipe.py
CHANGED
@@ -15,14 +15,12 @@ DOCUMENTATION = r"""
|
|
15
15
|
description: command(s) to run.
|
16
16
|
required: True
|
17
17
|
notes:
|
18
|
+
- The given command is passed to a shell for execution, therefore all variables that are part of the command and
|
19
|
+
come from a remote/untrusted source MUST be sanitized using the P(ansible.builtin.quote#filter) filter to avoid
|
20
|
+
shell injection vulnerabilities. See the example section.
|
18
21
|
- Like all lookups this runs on the Ansible controller and is unaffected by other keywords, such as become,
|
19
22
|
so if you need to different permissions you must change the command or run Ansible as another user.
|
20
23
|
- Alternatively you can use a shell/command task that runs against localhost and registers the result.
|
21
|
-
- Pipe lookup internally invokes Popen with shell=True (this is required and intentional).
|
22
|
-
This type of invocation is considered a security issue if appropriate care is not taken to sanitize any user provided or variable input.
|
23
|
-
It is strongly recommended to pass user input or variable input via quote filter before using with pipe lookup.
|
24
|
-
See example section for this.
|
25
|
-
Read more about this L(Bandit B602 docs,https://bandit.readthedocs.io/en/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html)
|
26
24
|
- The directory of the play is used as the current working directory.
|
27
25
|
"""
|
28
26
|
|
@@ -52,7 +50,7 @@ from ansible.plugins.lookup import LookupBase
|
|
52
50
|
|
53
51
|
class LookupModule(LookupBase):
|
54
52
|
|
55
|
-
def run(self, terms, variables, **kwargs):
|
53
|
+
def run(self, terms, variables=None, **kwargs):
|
56
54
|
|
57
55
|
ret = []
|
58
56
|
for term in terms:
|
@@ -65,7 +63,7 @@ class LookupModule(LookupBase):
|
|
65
63
|
# https://github.com/ansible/ansible/issues/6550
|
66
64
|
term = str(term)
|
67
65
|
|
68
|
-
p = subprocess.Popen(term, cwd=self.
|
66
|
+
p = subprocess.Popen(term, cwd=self._templar.basedir, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
69
67
|
(stdout, stderr) = p.communicate()
|
70
68
|
if p.returncode == 0:
|
71
69
|
ret.append(stdout.decode("utf-8").rstrip())
|
@@ -171,6 +171,12 @@ class LookupModule(LookupBase):
|
|
171
171
|
setattr(self, f, self.get_option(f))
|
172
172
|
|
173
173
|
def sanity_check(self):
|
174
|
+
"""
|
175
|
+
Returns True if options comprise a valid sequence expression
|
176
|
+
Raises AnsibleError if options are an invalid expression
|
177
|
+
Returns false if options are valid but result in an empty sequence - these cases do not raise exceptions
|
178
|
+
in order to maintain historic behavior
|
179
|
+
"""
|
174
180
|
if self.count is None and self.end is None:
|
175
181
|
raise AnsibleError("must specify count or end in with_sequence")
|
176
182
|
elif self.count is not None and self.end is not None:
|
@@ -180,17 +186,18 @@ class LookupModule(LookupBase):
|
|
180
186
|
if self.count != 0:
|
181
187
|
self.end = self.start + self.count * self.stride - 1
|
182
188
|
else:
|
183
|
-
|
184
|
-
self.end = 0
|
185
|
-
self.stride = 0
|
186
|
-
del self.count
|
189
|
+
return False
|
187
190
|
if self.stride > 0 and self.end < self.start:
|
188
191
|
raise AnsibleError("to count backwards make stride negative")
|
189
192
|
if self.stride < 0 and self.end > self.start:
|
190
193
|
raise AnsibleError("to count forward don't make stride negative")
|
194
|
+
if self.stride == 0:
|
195
|
+
return False
|
191
196
|
if self.format.count('%') != 1:
|
192
197
|
raise AnsibleError("bad formatting string: %s" % self.format)
|
193
198
|
|
199
|
+
return True
|
200
|
+
|
194
201
|
def generate_sequence(self):
|
195
202
|
if self.stride >= 0:
|
196
203
|
adjust = 1
|
@@ -207,9 +214,13 @@ class LookupModule(LookupBase):
|
|
207
214
|
"problem formatting %r with %r" % (i, self.format)
|
208
215
|
)
|
209
216
|
|
210
|
-
def run(self, terms, variables, **kwargs):
|
217
|
+
def run(self, terms, variables=None, **kwargs):
|
211
218
|
results = []
|
212
219
|
|
220
|
+
if kwargs and not terms:
|
221
|
+
# All of the necessary arguments can be provided as keywords, but we still need something to loop over
|
222
|
+
terms = ['']
|
223
|
+
|
213
224
|
for term in terms:
|
214
225
|
try:
|
215
226
|
# set defaults/global
|
@@ -223,10 +234,9 @@ class LookupModule(LookupBase):
|
|
223
234
|
raise AnsibleError("unknown error parsing with_sequence arguments: %r. Error was: %s" % (term, e))
|
224
235
|
|
225
236
|
self.set_fields()
|
226
|
-
self.sanity_check()
|
227
|
-
|
228
|
-
if self.stride != 0:
|
237
|
+
if self.sanity_check():
|
229
238
|
results.extend(self.generate_sequence())
|
239
|
+
|
230
240
|
except AnsibleError:
|
231
241
|
raise
|
232
242
|
except Exception as e:
|
@@ -86,7 +86,6 @@ from ansible.errors import AnsibleError
|
|
86
86
|
from ansible.module_utils.six import string_types
|
87
87
|
from ansible.module_utils.parsing.convert_bool import boolean
|
88
88
|
from ansible.plugins.lookup import LookupBase
|
89
|
-
from ansible.utils.listify import listify_lookup_plugin_terms
|
90
89
|
|
91
90
|
|
92
91
|
FLAGS = ('skip_missing',)
|
@@ -94,14 +93,12 @@ FLAGS = ('skip_missing',)
|
|
94
93
|
|
95
94
|
class LookupModule(LookupBase):
|
96
95
|
|
97
|
-
def run(self, terms, variables, **kwargs):
|
96
|
+
def run(self, terms, variables=None, **kwargs):
|
98
97
|
|
99
98
|
def _raise_terms_error(msg=""):
|
100
99
|
raise AnsibleError(
|
101
100
|
"subelements lookup expects a list of two or three items, " + msg)
|
102
101
|
|
103
|
-
terms[0] = listify_lookup_plugin_terms(terms[0], templar=self._templar)
|
104
|
-
|
105
102
|
# check lookup terms - check number of terms
|
106
103
|
if not isinstance(terms, list) or not 2 <= len(terms) <= 3:
|
107
104
|
_raise_terms_error()
|
@@ -17,9 +17,13 @@ DOCUMENTATION = """
|
|
17
17
|
convert_data:
|
18
18
|
type: bool
|
19
19
|
description:
|
20
|
-
- Whether to convert YAML into data. If False, strings that are YAML will be left untouched.
|
21
|
-
- Mutually exclusive with the jinja2_native option.
|
20
|
+
- Whether to convert YAML into data. If V(False), strings that are YAML will be left untouched.
|
21
|
+
- Mutually exclusive with the O(jinja2_native) option.
|
22
22
|
default: true
|
23
|
+
deprecated:
|
24
|
+
why: This option is no longer used in the Ansible Core code base.
|
25
|
+
version: "2.21"
|
26
|
+
alternatives: Jinja2 native mode is now the default and only option, which is mutually exclusive with this option.
|
23
27
|
variable_start_string:
|
24
28
|
description: The string marking the beginning of a print statement.
|
25
29
|
default: '{{'
|
@@ -33,13 +37,16 @@ DOCUMENTATION = """
|
|
33
37
|
jinja2_native:
|
34
38
|
description:
|
35
39
|
- Controls whether to use Jinja2 native types.
|
36
|
-
- It is off by default even if global jinja2_native is True.
|
37
|
-
- Has no effect if global jinja2_native is False.
|
40
|
+
- It is off by default even if global O(jinja2_native) is V(True).
|
41
|
+
- Has no effect if global O(jinja2_native) is V(False).
|
38
42
|
- This offers more flexibility than the template module which does not use Jinja2 native types at all.
|
39
|
-
|
40
|
-
default: False
|
43
|
+
default: True
|
41
44
|
version_added: '2.11'
|
42
45
|
type: bool
|
46
|
+
deprecated:
|
47
|
+
why: This option is no longer used in the Ansible Core code base.
|
48
|
+
version: "2.21"
|
49
|
+
alternatives: Jinja2 native mode is now the default and only option.
|
43
50
|
template_vars:
|
44
51
|
description: A dictionary, the keys become additional variables available for templating.
|
45
52
|
default: {}
|
@@ -55,6 +62,13 @@ DOCUMENTATION = """
|
|
55
62
|
version_added: '2.12'
|
56
63
|
type: str
|
57
64
|
default: '#}'
|
65
|
+
trim_blocks:
|
66
|
+
description:
|
67
|
+
- Determine when newlines should be removed from blocks.
|
68
|
+
- When set to V(yes) the first newline after a block is removed (block, not variable tag!).
|
69
|
+
type: bool
|
70
|
+
default: yes
|
71
|
+
version_added: '2.19'
|
58
72
|
seealso:
|
59
73
|
- ref: playbook_task_paths
|
60
74
|
description: Search paths used for relative templates.
|
@@ -72,6 +86,11 @@ EXAMPLES = """
|
|
72
86
|
- name: show templating results with different comment start and end string
|
73
87
|
ansible.builtin.debug:
|
74
88
|
msg: "{{ lookup('ansible.builtin.template', './some_template.j2', comment_start_string='[#', comment_end_string='#]') }}"
|
89
|
+
|
90
|
+
- name: show templating results with trim_blocks
|
91
|
+
ansible.builtin.debug:
|
92
|
+
msg: "{{ lookup('ansible.builtin.template', './some_template.j2', trim_blocks=True) }}"
|
93
|
+
|
75
94
|
"""
|
76
95
|
|
77
96
|
RETURN = """
|
@@ -84,14 +103,10 @@ _raw:
|
|
84
103
|
from copy import deepcopy
|
85
104
|
import os
|
86
105
|
|
87
|
-
import ansible.constants as C
|
88
|
-
|
89
106
|
from ansible.errors import AnsibleError
|
90
107
|
from ansible.plugins.lookup import LookupBase
|
91
|
-
from ansible.
|
92
|
-
from ansible.template import generate_ansible_template_vars, AnsibleEnvironment
|
108
|
+
from ansible.template import generate_ansible_template_vars, trust_as_template
|
93
109
|
from ansible.utils.display import Display
|
94
|
-
from ansible.utils.native_jinja import NativeJinjaText
|
95
110
|
|
96
111
|
|
97
112
|
display = Display()
|
@@ -99,25 +114,21 @@ display = Display()
|
|
99
114
|
|
100
115
|
class LookupModule(LookupBase):
|
101
116
|
|
102
|
-
def run(self, terms, variables, **kwargs):
|
117
|
+
def run(self, terms, variables=None, **kwargs):
|
103
118
|
|
104
119
|
ret = []
|
105
120
|
|
106
121
|
self.set_options(var_options=variables, direct=kwargs)
|
107
122
|
|
108
123
|
# capture options
|
109
|
-
convert_data_p = self.get_option('convert_data')
|
110
124
|
lookup_template_vars = self.get_option('template_vars')
|
111
|
-
jinja2_native = self.get_option('jinja2_native') and C.DEFAULT_JINJA2_NATIVE
|
112
125
|
variable_start_string = self.get_option('variable_start_string')
|
113
126
|
variable_end_string = self.get_option('variable_end_string')
|
114
127
|
comment_start_string = self.get_option('comment_start_string')
|
115
128
|
comment_end_string = self.get_option('comment_end_string')
|
129
|
+
trim_blocks = self.get_option('trim_blocks')
|
116
130
|
|
117
|
-
|
118
|
-
templar = self._templar
|
119
|
-
else:
|
120
|
-
templar = self._templar.copy_with_new_env(environment_class=AnsibleEnvironment)
|
131
|
+
templar = self._templar
|
121
132
|
|
122
133
|
for term in terms:
|
123
134
|
display.debug("File lookup term: %s" % term)
|
@@ -125,8 +136,7 @@ class LookupModule(LookupBase):
|
|
125
136
|
lookupfile = self.find_file_in_search_path(variables, 'templates', term)
|
126
137
|
display.vvvv("File lookup using %s as file" % lookupfile)
|
127
138
|
if lookupfile:
|
128
|
-
|
129
|
-
template_data = to_text(b_template_data, errors='surrogate_or_strict')
|
139
|
+
template_data = trust_as_template(self._loader.get_text_file_contents(lookupfile))
|
130
140
|
|
131
141
|
# set jinja2 internal search path for includes
|
132
142
|
searchpath = variables.get('ansible_search_path', [])
|
@@ -145,25 +155,21 @@ class LookupModule(LookupBase):
|
|
145
155
|
# plus some added by ansible (e.g., template_{path,mtime}),
|
146
156
|
# plus anything passed to the lookup with the template_vars=
|
147
157
|
# argument.
|
158
|
+
# FIXME: why isn't this a chainmap with a sacrificial bottom layer?
|
148
159
|
vars = deepcopy(variables)
|
149
|
-
vars.update(generate_ansible_template_vars(term, lookupfile))
|
160
|
+
vars.update(generate_ansible_template_vars(term, fullpath=lookupfile))
|
150
161
|
vars.update(lookup_template_vars)
|
151
162
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
if (C.DEFAULT_JINJA2_NATIVE and not jinja2_native) or not convert_data_p:
|
164
|
-
# jinja2_native is true globally but off for the lookup, we need this text
|
165
|
-
# not to be processed by literal_eval anywhere in Ansible
|
166
|
-
res = NativeJinjaText(res)
|
163
|
+
overrides = dict(
|
164
|
+
variable_start_string=variable_start_string,
|
165
|
+
variable_end_string=variable_end_string,
|
166
|
+
comment_start_string=comment_start_string,
|
167
|
+
comment_end_string=comment_end_string,
|
168
|
+
trim_blocks=trim_blocks,
|
169
|
+
)
|
170
|
+
|
171
|
+
data_templar = templar.copy_with_new_env(available_variables=vars, searchpath=searchpath)
|
172
|
+
res = data_templar.template(template_data, escape_backslashes=False, overrides=overrides)
|
167
173
|
|
168
174
|
ret.append(res)
|
169
175
|
else:
|
@@ -38,7 +38,6 @@ import itertools
|
|
38
38
|
|
39
39
|
from ansible.errors import AnsibleError
|
40
40
|
from ansible.plugins.lookup import LookupBase
|
41
|
-
from ansible.utils.listify import listify_lookup_plugin_terms
|
42
41
|
|
43
42
|
|
44
43
|
class LookupModule(LookupBase):
|
@@ -48,18 +47,7 @@ class LookupModule(LookupBase):
|
|
48
47
|
Replace any empty spots in 2nd array with None:
|
49
48
|
[1, 2], [3] -> [1, 3], [2, None]
|
50
49
|
"""
|
51
|
-
|
52
|
-
def _lookup_variables(self, terms):
|
53
|
-
results = []
|
54
|
-
for x in terms:
|
55
|
-
intermediate = listify_lookup_plugin_terms(x, templar=self._templar)
|
56
|
-
results.append(intermediate)
|
57
|
-
return results
|
58
|
-
|
59
50
|
def run(self, terms, variables=None, **kwargs):
|
60
|
-
|
61
|
-
terms = self._lookup_variables(terms)
|
62
|
-
|
63
51
|
my_list = terms[:]
|
64
52
|
if len(my_list) == 0:
|
65
53
|
raise AnsibleError("with_together requires at least one element in each list")
|
@@ -34,7 +34,6 @@ RETURN = """
|
|
34
34
|
|
35
35
|
from ansible.errors import AnsibleParserError
|
36
36
|
from ansible.plugins.lookup import LookupBase
|
37
|
-
from ansible.module_utils.common.text.converters import to_text
|
38
37
|
from ansible.utils.display import Display
|
39
38
|
|
40
39
|
display = Display()
|
@@ -55,10 +54,7 @@ class LookupModule(LookupBase):
|
|
55
54
|
lookupfile = self.find_file_in_search_path(variables, 'files', term)
|
56
55
|
display.vvvv(u"Unvault lookup found %s" % lookupfile)
|
57
56
|
if lookupfile:
|
58
|
-
|
59
|
-
with open(actual_file, 'rb') as f:
|
60
|
-
b_contents = f.read()
|
61
|
-
ret.append(to_text(b_contents))
|
57
|
+
ret.append(self._loader.get_text_file_contents(lookupfile))
|
62
58
|
else:
|
63
59
|
raise AnsibleParserError('Unable to find file matching "%s" ' % term)
|
64
60
|
|
ansible/plugins/lookup/url.py
CHANGED
@@ -87,7 +87,6 @@ options:
|
|
87
87
|
- section: url_lookup
|
88
88
|
key: force_basic_auth
|
89
89
|
follow_redirects:
|
90
|
-
description: String of urllib2, all/yes, safe, none to determine how redirects are followed
|
91
90
|
type: string
|
92
91
|
version_added: "2.10"
|
93
92
|
default: 'urllib2'
|
@@ -98,13 +97,6 @@ options:
|
|
98
97
|
ini:
|
99
98
|
- section: url_lookup
|
100
99
|
key: follow_redirects
|
101
|
-
choices:
|
102
|
-
all: Will follow all redirects.
|
103
|
-
none: Will not follow any redirects.
|
104
|
-
safe: Only redirects doing GET or HEAD requests will be followed.
|
105
|
-
urllib2: Defer to urllib2 behavior (As of writing this follows HTTP redirects).
|
106
|
-
'no': (DEPRECATED, removed in 2.22) alias of V(none).
|
107
|
-
'yes': (DEPRECATED, removed in 2.22) alias of V(all).
|
108
100
|
use_gssapi:
|
109
101
|
description:
|
110
102
|
- Use GSSAPI handler of requests
|
@@ -185,6 +177,8 @@ options:
|
|
185
177
|
ini:
|
186
178
|
- section: url_lookup
|
187
179
|
key: ciphers
|
180
|
+
extends_documentation_fragment:
|
181
|
+
- url.url_redirect
|
188
182
|
"""
|
189
183
|
|
190
184
|
EXAMPLES = """
|
ansible/plugins/lookup/vars.py
CHANGED
@@ -73,40 +73,32 @@ _value:
|
|
73
73
|
elements: raw
|
74
74
|
"""
|
75
75
|
|
76
|
-
from ansible.errors import
|
77
|
-
from ansible.module_utils.six import string_types
|
76
|
+
from ansible.errors import AnsibleTypeError
|
78
77
|
from ansible.plugins.lookup import LookupBase
|
78
|
+
from ansible.module_utils.datatag import native_type_name
|
79
|
+
from ansible._internal._templating import _jinja_bits
|
79
80
|
|
80
81
|
|
81
82
|
class LookupModule(LookupBase):
|
82
|
-
|
83
|
-
def run(self, terms, variables=None, **kwargs):
|
84
|
-
if variables is not None:
|
85
|
-
self._templar.available_variables = variables
|
86
|
-
myvars = getattr(self._templar, '_available_variables', {})
|
87
|
-
|
83
|
+
def run(self, terms, variables, **kwargs):
|
88
84
|
self.set_options(var_options=variables, direct=kwargs)
|
85
|
+
|
89
86
|
default = self.get_option('default')
|
90
87
|
|
91
88
|
ret = []
|
89
|
+
|
92
90
|
for term in terms:
|
93
|
-
if not isinstance(term,
|
94
|
-
raise
|
91
|
+
if not isinstance(term, str):
|
92
|
+
raise AnsibleTypeError(f'Variable name must be {native_type_name(str)!r} not {native_type_name(term)!r}.', obj=term)
|
95
93
|
|
96
94
|
try:
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
value = myvars['hostvars'][myvars['inventory_hostname']][term]
|
102
|
-
except KeyError:
|
103
|
-
raise AnsibleUndefinedVariable('No variable found with this name: %s' % term)
|
104
|
-
|
105
|
-
ret.append(self._templar.template(value, fail_on_undefined=True))
|
106
|
-
except AnsibleUndefinedVariable:
|
107
|
-
if default is not None:
|
108
|
-
ret.append(default)
|
95
|
+
value = variables[term]
|
96
|
+
except KeyError:
|
97
|
+
if default is None:
|
98
|
+
value = _jinja_bits._undef(f'No variable named {term!r} was found.')
|
109
99
|
else:
|
110
|
-
|
100
|
+
value = default
|
101
|
+
|
102
|
+
ret.append(value)
|
111
103
|
|
112
|
-
return ret
|
104
|
+
return self._templar._engine.template(ret)
|
@@ -164,7 +164,7 @@ class ShellBase(AnsiblePlugin):
|
|
164
164
|
return cmd
|
165
165
|
|
166
166
|
def expand_user(self, user_home_path, username=''):
|
167
|
-
|
167
|
+
""" Return a command to expand tildes in a path
|
168
168
|
|
169
169
|
It can be either "~" or "~username". We just ignore $HOME
|
170
170
|
We use the POSIX definition of a username:
|
@@ -172,7 +172,7 @@ class ShellBase(AnsiblePlugin):
|
|
172
172
|
http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_276
|
173
173
|
|
174
174
|
Falls back to 'current working directory' as we assume 'home is where the remote user ends up'
|
175
|
-
|
175
|
+
"""
|
176
176
|
|
177
177
|
# Check that the user_path to expand is safe
|
178
178
|
if user_home_path != '~':
|
ansible/plugins/shell/cmd.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
DOCUMENTATION =
|
5
|
+
DOCUMENTATION = """
|
6
6
|
name: cmd
|
7
7
|
version_added: '2.8'
|
8
8
|
short_description: Windows Command Prompt
|
@@ -10,7 +10,7 @@ description:
|
|
10
10
|
- Used with the 'ssh' connection plugin and no C(DefaultShell) has been set on the Windows host.
|
11
11
|
extends_documentation_fragment:
|
12
12
|
- shell_windows
|
13
|
-
|
13
|
+
"""
|
14
14
|
|
15
15
|
import re
|
16
16
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
-
DOCUMENTATION =
|
6
|
+
DOCUMENTATION = """
|
7
7
|
name: powershell
|
8
8
|
version_added: historical
|
9
9
|
short_description: Windows PowerShell
|
@@ -12,16 +12,16 @@ description:
|
|
12
12
|
- Can also be used when using 'ssh' as a connection plugin and the C(DefaultShell) has been configured to PowerShell.
|
13
13
|
extends_documentation_fragment:
|
14
14
|
- shell_windows
|
15
|
-
|
15
|
+
"""
|
16
16
|
|
17
17
|
import base64
|
18
18
|
import os
|
19
19
|
import re
|
20
20
|
import shlex
|
21
|
-
import pkgutil
|
22
21
|
import xml.etree.ElementTree as ET
|
23
22
|
import ntpath
|
24
23
|
|
24
|
+
from ansible.executor.powershell.module_manifest import _get_powershell_script
|
25
25
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
26
26
|
from ansible.plugins.shell import ShellBase
|
27
27
|
|
@@ -221,9 +221,9 @@ class ShellModule(ShellBase):
|
|
221
221
|
def remove(self, path, recurse=False):
|
222
222
|
path = self._escape(self._unquote(path))
|
223
223
|
if recurse:
|
224
|
-
return self._encode_script(
|
224
|
+
return self._encode_script("""Remove-Item '%s' -Force -Recurse;""" % path)
|
225
225
|
else:
|
226
|
-
return self._encode_script(
|
226
|
+
return self._encode_script("""Remove-Item '%s' -Force;""" % path)
|
227
227
|
|
228
228
|
def mkdtemp(self, basefile=None, system=False, mode=None, tmpdir=None):
|
229
229
|
# Windows does not have an equivalent for the system temp files, so
|
@@ -233,12 +233,12 @@ class ShellModule(ShellBase):
|
|
233
233
|
basefile = self._escape(self._unquote(basefile))
|
234
234
|
basetmpdir = self._escape(tmpdir if tmpdir else self.get_option('remote_tmp'))
|
235
235
|
|
236
|
-
script = f
|
236
|
+
script = f"""
|
237
237
|
{self._CONSOLE_ENCODING}
|
238
238
|
$tmp_path = [System.Environment]::ExpandEnvironmentVariables('{basetmpdir}')
|
239
239
|
$tmp = New-Item -Type Directory -Path $tmp_path -Name '{basefile}'
|
240
240
|
Write-Output -InputObject $tmp.FullName
|
241
|
-
|
241
|
+
"""
|
242
242
|
return self._encode_script(script.strip())
|
243
243
|
|
244
244
|
def expand_user(self, user_home_path, username=''):
|
@@ -256,7 +256,7 @@ class ShellModule(ShellBase):
|
|
256
256
|
|
257
257
|
def exists(self, path):
|
258
258
|
path = self._escape(self._unquote(path))
|
259
|
-
script =
|
259
|
+
script = """
|
260
260
|
If (Test-Path '%s')
|
261
261
|
{
|
262
262
|
$res = 0;
|
@@ -267,12 +267,12 @@ class ShellModule(ShellBase):
|
|
267
267
|
}
|
268
268
|
Write-Output '$res';
|
269
269
|
Exit $res;
|
270
|
-
|
270
|
+
""" % path
|
271
271
|
return self._encode_script(script)
|
272
272
|
|
273
273
|
def checksum(self, path, *args, **kwargs):
|
274
274
|
path = self._escape(self._unquote(path))
|
275
|
-
script =
|
275
|
+
script = """
|
276
276
|
If (Test-Path -PathType Leaf '%(path)s')
|
277
277
|
{
|
278
278
|
$sp = new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider;
|
@@ -288,11 +288,11 @@ class ShellModule(ShellBase):
|
|
288
288
|
{
|
289
289
|
Write-Output "1";
|
290
290
|
}
|
291
|
-
|
291
|
+
""" % dict(path=path)
|
292
292
|
return self._encode_script(script)
|
293
293
|
|
294
294
|
def build_module_command(self, env_string, shebang, cmd, arg_path=None):
|
295
|
-
bootstrap_wrapper =
|
295
|
+
bootstrap_wrapper = _get_powershell_script("bootstrap_wrapper.ps1")
|
296
296
|
|
297
297
|
# pipelining bypass
|
298
298
|
if cmd == '':
|
@@ -303,18 +303,35 @@ class ShellModule(ShellBase):
|
|
303
303
|
cmd_parts = shlex.split(cmd, posix=False)
|
304
304
|
cmd_parts = list(map(to_text, cmd_parts))
|
305
305
|
if shebang and shebang.lower() == '#!powershell':
|
306
|
-
if
|
307
|
-
#
|
308
|
-
|
309
|
-
|
310
|
-
|
306
|
+
if arg_path:
|
307
|
+
# Running a module without the exec_wrapper and with an argument
|
308
|
+
# file.
|
309
|
+
script_path = self._unquote(cmd_parts[0])
|
310
|
+
if not script_path.lower().endswith('.ps1'):
|
311
|
+
script_path += '.ps1'
|
312
|
+
|
313
|
+
cmd_parts.insert(0, '-File')
|
314
|
+
cmd_parts[1] = f'"{script_path}"'
|
315
|
+
if arg_path:
|
316
|
+
cmd_parts.append(f'"{arg_path}"')
|
317
|
+
|
318
|
+
wrapper_cmd = " ".join(_common_args + cmd_parts)
|
319
|
+
return wrapper_cmd
|
320
|
+
|
321
|
+
else:
|
322
|
+
# Running a module with ANSIBLE_KEEP_REMOTE_FILES=true, the script
|
323
|
+
# arg is actually the input manifest JSON to provide to the bootstrap
|
324
|
+
# wrapper.
|
325
|
+
wrapper_cmd = "type " + cmd_parts[0] + " | " + self._encode_script(script=bootstrap_wrapper, strict_mode=False, preserve_rc=False)
|
326
|
+
return wrapper_cmd
|
327
|
+
|
311
328
|
elif shebang and shebang.startswith('#!'):
|
312
329
|
cmd_parts.insert(0, shebang[2:])
|
313
330
|
elif not shebang:
|
314
331
|
# The module is assumed to be a binary
|
315
332
|
cmd_parts[0] = self._unquote(cmd_parts[0])
|
316
333
|
cmd_parts.append(arg_path)
|
317
|
-
script =
|
334
|
+
script = """
|
318
335
|
Try
|
319
336
|
{
|
320
337
|
%s
|
@@ -349,14 +366,14 @@ class ShellModule(ShellBase):
|
|
349
366
|
Echo $_obj | ConvertTo-Json -Compress -Depth 99
|
350
367
|
Exit 1
|
351
368
|
}
|
352
|
-
|
369
|
+
""" % (env_string, ' '.join(cmd_parts))
|
353
370
|
return self._encode_script(script, preserve_rc=False)
|
354
371
|
|
355
372
|
def wrap_for_exec(self, cmd):
|
356
373
|
return '& %s; exit $LASTEXITCODE' % cmd
|
357
374
|
|
358
375
|
def _unquote(self, value):
|
359
|
-
|
376
|
+
"""Remove any matching quotes that wrap the given value."""
|
360
377
|
value = to_text(value or '')
|
361
378
|
m = re.match(r'^\s*?\'(.*?)\'\s*?$', value)
|
362
379
|
if m:
|
@@ -367,13 +384,13 @@ class ShellModule(ShellBase):
|
|
367
384
|
return value
|
368
385
|
|
369
386
|
def _escape(self, value):
|
370
|
-
|
387
|
+
"""Return value escaped for use in PowerShell single quotes."""
|
371
388
|
# There are 5 chars that need to be escaped in a single quote.
|
372
389
|
# https://github.com/PowerShell/PowerShell/blob/b7cb335f03fe2992d0cbd61699de9d9aafa1d7c1/src/System.Management.Automation/engine/parser/CharTraits.cs#L265-L272
|
373
390
|
return re.compile(u"(['\u2018\u2019\u201a\u201b])").sub(u'\\1\\1', value)
|
374
391
|
|
375
392
|
def _encode_script(self, script, as_list=False, strict_mode=True, preserve_rc=True):
|
376
|
-
|
393
|
+
"""Convert a PowerShell script to a single base64-encoded command."""
|
377
394
|
script = to_text(script)
|
378
395
|
|
379
396
|
if script == u'-':
|