ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b1__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/_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 +160 -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 +198 -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 +351 -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 +153 -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 +48 -46
- 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 +165 -108
- 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 +136 -76
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +237 -236
- ansible/executor/task_queue_manager.py +62 -38
- ansible/executor/task_result.py +21 -12
- 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 +77 -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 +154 -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/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 +36 -339
- 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 +6 -15
- 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 +141 -123
- ansible/plugins/callback/default.py +30 -23
- ansible/plugins/callback/junit.py +28 -24
- ansible/plugins/callback/minimal.py +17 -14
- ansible/plugins/callback/oneline.py +13 -7
- ansible/plugins/callback/tree.py +10 -6
- 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 +218 -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 +94 -113
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +13 -28
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +31 -33
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +54 -20
- 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 +368 -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 +428 -58
- 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 +28 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +4 -4
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +205 -264
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.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/utils/jsonify.py +0 -36
- 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.0b1.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
@@ -18,12 +18,9 @@
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
20
|
from ansible.errors import AnsibleActionFail
|
21
|
-
from ansible.module_utils.six import string_types
|
22
21
|
from ansible.module_utils.parsing.convert_bool import boolean
|
23
22
|
from ansible.plugins.action import ActionBase
|
24
|
-
from ansible.utils.vars import
|
25
|
-
|
26
|
-
import ansible.constants as C
|
23
|
+
from ansible.utils.vars import validate_variable_name
|
27
24
|
|
28
25
|
|
29
26
|
class ActionModule(ActionBase):
|
@@ -43,16 +40,10 @@ class ActionModule(ActionBase):
|
|
43
40
|
|
44
41
|
if self._task.args:
|
45
42
|
for (k, v) in self._task.args.items():
|
46
|
-
k = self._templar.template(k)
|
43
|
+
k = self._templar.template(k) # a rare case where key templating is allowed; backward-compatibility for dynamic storage
|
47
44
|
|
48
|
-
|
49
|
-
raise AnsibleActionFail("The variable name '%s' is not valid. Variables must start with a letter or underscore character, "
|
50
|
-
"and contain only letters, numbers and underscores." % k)
|
45
|
+
validate_variable_name(k)
|
51
46
|
|
52
|
-
# NOTE: this should really use BOOLEANS from convert_bool, but only in the k=v case,
|
53
|
-
# right now it converts matching explicit YAML strings also when 'jinja2_native' is disabled.
|
54
|
-
if not C.DEFAULT_JINJA2_NATIVE and isinstance(v, string_types) and v.lower() in ('true', 'false', 'yes', 'no'):
|
55
|
-
v = boolean(v, strict=False)
|
56
47
|
facts[k] = v
|
57
48
|
else:
|
58
49
|
raise AnsibleActionFail('No key/value pairs provided, at least one is required for this action to succeed')
|
@@ -19,7 +19,7 @@ from __future__ import annotations
|
|
19
19
|
|
20
20
|
from ansible.module_utils.parsing.convert_bool import boolean
|
21
21
|
from ansible.plugins.action import ActionBase
|
22
|
-
from ansible.utils.vars import
|
22
|
+
from ansible.utils.vars import validate_variable_name
|
23
23
|
|
24
24
|
|
25
25
|
class ActionModule(ActionBase):
|
@@ -42,7 +42,7 @@ class ActionModule(ActionBase):
|
|
42
42
|
data = self._task.args.get('data', {})
|
43
43
|
|
44
44
|
if not isinstance(data, dict):
|
45
|
-
data = self._templar.template(data
|
45
|
+
data = self._templar.template(data)
|
46
46
|
|
47
47
|
if not isinstance(data, dict):
|
48
48
|
result['failed'] = True
|
@@ -59,14 +59,9 @@ class ActionModule(ActionBase):
|
|
59
59
|
stats[opt] = val
|
60
60
|
|
61
61
|
for (k, v) in data.items():
|
62
|
-
|
63
62
|
k = self._templar.template(k)
|
64
63
|
|
65
|
-
|
66
|
-
result['failed'] = True
|
67
|
-
result['msg'] = ("The variable name '%s' is not valid. Variables must start with a letter or underscore character, and contain only "
|
68
|
-
"letters, numbers and underscores." % k)
|
69
|
-
return result
|
64
|
+
validate_variable_name(k)
|
70
65
|
|
71
66
|
stats['data'][k] = self._templar.template(v)
|
72
67
|
|
@@ -20,12 +20,12 @@ from jinja2.defaults import (
|
|
20
20
|
|
21
21
|
from ansible import constants as C
|
22
22
|
from ansible.config.manager import ensure_type
|
23
|
-
from ansible.errors import AnsibleError,
|
23
|
+
from ansible.errors import AnsibleError, AnsibleAction, AnsibleActionFail
|
24
24
|
from ansible.module_utils.common.text.converters import to_bytes, to_text, to_native
|
25
25
|
from ansible.module_utils.parsing.convert_bool import boolean
|
26
26
|
from ansible.module_utils.six import string_types
|
27
27
|
from ansible.plugins.action import ActionBase
|
28
|
-
from ansible.template import generate_ansible_template_vars,
|
28
|
+
from ansible.template import generate_ansible_template_vars, trust_as_template
|
29
29
|
|
30
30
|
|
31
31
|
class ActionModule(ActionBase):
|
@@ -34,7 +34,7 @@ class ActionModule(ActionBase):
|
|
34
34
|
DEFAULT_NEWLINE_SEQUENCE = "\n"
|
35
35
|
|
36
36
|
def run(self, tmp=None, task_vars=None):
|
37
|
-
|
37
|
+
""" handler for template operations """
|
38
38
|
|
39
39
|
if task_vars is None:
|
40
40
|
task_vars = dict()
|
@@ -98,63 +98,39 @@ class ActionModule(ActionBase):
|
|
98
98
|
if mode == 'preserve':
|
99
99
|
mode = '0%03o' % stat.S_IMODE(os.stat(source).st_mode)
|
100
100
|
|
101
|
-
# Get vault decrypted tmp file
|
102
|
-
try:
|
103
|
-
tmp_source = self._loader.get_real_file(source)
|
104
|
-
except AnsibleFileNotFound as e:
|
105
|
-
raise AnsibleActionFail("could not find src=%s, %s" % (source, to_text(e)))
|
106
|
-
b_tmp_source = to_bytes(tmp_source, errors='surrogate_or_strict')
|
107
|
-
|
108
101
|
# template the source data locally & get ready to transfer
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
overrides = dict(
|
142
|
-
block_start_string=block_start_string,
|
143
|
-
block_end_string=block_end_string,
|
144
|
-
variable_start_string=variable_start_string,
|
145
|
-
variable_end_string=variable_end_string,
|
146
|
-
comment_start_string=comment_start_string,
|
147
|
-
comment_end_string=comment_end_string,
|
148
|
-
trim_blocks=trim_blocks,
|
149
|
-
lstrip_blocks=lstrip_blocks
|
150
|
-
)
|
151
|
-
resultant = templar.do_template(template_data, preserve_trailing_newlines=True, escape_backslashes=False, overrides=overrides)
|
152
|
-
except AnsibleAction:
|
153
|
-
raise
|
154
|
-
except Exception as e:
|
155
|
-
raise AnsibleActionFail("%s: %s" % (type(e).__name__, to_text(e)))
|
156
|
-
finally:
|
157
|
-
self._loader.cleanup_tmp_file(b_tmp_source)
|
102
|
+
template_data = trust_as_template(self._loader.get_text_file_contents(source))
|
103
|
+
|
104
|
+
# set jinja2 internal search path for includes
|
105
|
+
searchpath = task_vars.get('ansible_search_path', [])
|
106
|
+
searchpath.extend([self._loader._basedir, os.path.dirname(source)])
|
107
|
+
|
108
|
+
# We want to search into the 'templates' subdir of each search path in
|
109
|
+
# addition to our original search paths.
|
110
|
+
newsearchpath = []
|
111
|
+
for p in searchpath:
|
112
|
+
newsearchpath.append(os.path.join(p, 'templates'))
|
113
|
+
newsearchpath.append(p)
|
114
|
+
searchpath = newsearchpath
|
115
|
+
|
116
|
+
# add ansible 'template' vars
|
117
|
+
temp_vars = task_vars.copy()
|
118
|
+
temp_vars.update(generate_ansible_template_vars(self._task.args.get('src', None), fullpath=source, dest_path=dest))
|
119
|
+
|
120
|
+
overrides = dict(
|
121
|
+
block_start_string=block_start_string,
|
122
|
+
block_end_string=block_end_string,
|
123
|
+
variable_start_string=variable_start_string,
|
124
|
+
variable_end_string=variable_end_string,
|
125
|
+
comment_start_string=comment_start_string,
|
126
|
+
comment_end_string=comment_end_string,
|
127
|
+
trim_blocks=trim_blocks,
|
128
|
+
lstrip_blocks=lstrip_blocks,
|
129
|
+
newline_sequence=newline_sequence,
|
130
|
+
)
|
131
|
+
|
132
|
+
data_templar = self._templar.copy_with_new_env(searchpath=searchpath, available_variables=temp_vars)
|
133
|
+
resultant = data_templar.template(template_data, escape_backslashes=False, overrides=overrides)
|
158
134
|
|
159
135
|
new_task = self._task.copy()
|
160
136
|
# mode is either the mode from task.args or the mode of the source file if the task.args
|
@@ -10,13 +10,13 @@ from ansible.utils.vars import combine_vars
|
|
10
10
|
|
11
11
|
|
12
12
|
class ActionModule(ActionBase):
|
13
|
-
|
13
|
+
""" Validate an arg spec"""
|
14
14
|
|
15
15
|
TRANSFERS_FILES = False
|
16
16
|
_requires_connection = False
|
17
17
|
|
18
18
|
def get_args_from_task_vars(self, argument_spec, task_vars):
|
19
|
-
|
19
|
+
"""
|
20
20
|
Get any arguments that may come from `task_vars`.
|
21
21
|
|
22
22
|
Expand templated variables so we can validate the actual values.
|
@@ -25,7 +25,7 @@ class ActionModule(ActionBase):
|
|
25
25
|
:param task_vars: A dict of task variables.
|
26
26
|
|
27
27
|
:returns: A dict of values that can be validated against the arg spec.
|
28
|
-
|
28
|
+
"""
|
29
29
|
args = {}
|
30
30
|
|
31
31
|
for argument_name, argument_attrs in argument_spec.items():
|
@@ -35,7 +35,7 @@ class ActionModule(ActionBase):
|
|
35
35
|
return args
|
36
36
|
|
37
37
|
def run(self, tmp=None, task_vars=None):
|
38
|
-
|
38
|
+
"""
|
39
39
|
Validate an argument specification against a provided set of data.
|
40
40
|
|
41
41
|
The `validate_argument_spec` module expects to receive the arguments:
|
@@ -48,7 +48,7 @@ class ActionModule(ActionBase):
|
|
48
48
|
:param task_vars: A dict of task variables.
|
49
49
|
:return: An action result dict, including a 'argument_errors' key with a
|
50
50
|
list of validation errors found.
|
51
|
-
|
51
|
+
"""
|
52
52
|
if task_vars is None:
|
53
53
|
task_vars = dict()
|
54
54
|
|
@@ -76,7 +76,7 @@ class ActionModule(ActionBase):
|
|
76
76
|
del tmp # tmp no longer has any effect
|
77
77
|
|
78
78
|
def ping_module_test(connect_timeout):
|
79
|
-
|
79
|
+
""" Test ping module, if available """
|
80
80
|
display.vvv("wait_for_connection: attempting ping module test")
|
81
81
|
# re-run interpreter discovery if we ran it in the first iteration
|
82
82
|
if self._discovered_interpreter_key:
|
@@ -3,6 +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
|
+
import re
|
6
7
|
import shlex
|
7
8
|
|
8
9
|
from abc import abstractmethod
|
@@ -13,10 +14,11 @@ from gettext import dgettext
|
|
13
14
|
from ansible.errors import AnsibleError
|
14
15
|
from ansible.module_utils.common.text.converters import to_bytes
|
15
16
|
from ansible.plugins import AnsiblePlugin
|
17
|
+
from ansible.utils import display as _display
|
16
18
|
|
17
19
|
|
18
20
|
def _gen_id(length=32):
|
19
|
-
|
21
|
+
""" return random string used to identify the current privilege escalation """
|
20
22
|
return ''.join(choice(ascii_lowercase) for x in range(length))
|
21
23
|
|
22
24
|
|
@@ -32,6 +34,9 @@ class BecomeBase(AnsiblePlugin):
|
|
32
34
|
# plugin requires a tty, i.e su
|
33
35
|
require_tty = False
|
34
36
|
|
37
|
+
# plugin allows for pipelining execution
|
38
|
+
pipelining = True
|
39
|
+
|
35
40
|
# prompt to match
|
36
41
|
prompt = ''
|
37
42
|
|
@@ -53,11 +58,11 @@ class BecomeBase(AnsiblePlugin):
|
|
53
58
|
|
54
59
|
return getattr(playcontext, option, None)
|
55
60
|
|
56
|
-
def expect_prompt(self):
|
61
|
+
def expect_prompt(self) -> bool:
|
57
62
|
"""This function assists connection plugins in determining if they need to wait for
|
58
63
|
a prompt. Both a prompt and a password are required.
|
59
64
|
"""
|
60
|
-
return self.prompt and self.get_option('become_pass')
|
65
|
+
return bool(self.prompt and self.get_option('become_pass'))
|
61
66
|
|
62
67
|
def _build_success_command(self, cmd, shell, noexe=False):
|
63
68
|
if not all((cmd, shell, self.success)):
|
@@ -65,9 +70,8 @@ class BecomeBase(AnsiblePlugin):
|
|
65
70
|
|
66
71
|
try:
|
67
72
|
cmd = shlex.quote('%s %s %s %s' % (shell.ECHO, self.success, shell.COMMAND_SEP, cmd))
|
68
|
-
except AttributeError:
|
69
|
-
|
70
|
-
raise AnsibleError('The %s shell family is incompatible with the %s become plugin' % (shell.SHELL_FAMILY, self.name))
|
73
|
+
except AttributeError as ex:
|
74
|
+
raise AnsibleError(f'The {shell._load_name!r} shell plugin does not support become. It is missing the {ex.name!r} attribute.')
|
71
75
|
exe = getattr(shell, 'executable', None)
|
72
76
|
if exe and not noexe:
|
73
77
|
cmd = '%s -c %s' % (exe, cmd)
|
@@ -78,19 +82,38 @@ class BecomeBase(AnsiblePlugin):
|
|
78
82
|
self._id = _gen_id()
|
79
83
|
self.success = 'BECOME-SUCCESS-%s' % self._id
|
80
84
|
|
85
|
+
def strip_become_prompt(self, data: bytes) -> bytes:
|
86
|
+
"""
|
87
|
+
Strips the first found configured become prompt from `data`, trailing whitespace and anything that precedes the prompt, then returns the result.
|
88
|
+
If no prompt is expected, or the prompt is not `str` or `bytes`, `data` will be returned as-is.
|
89
|
+
"""
|
90
|
+
if not self.prompt or not isinstance(self.prompt, (str, bytes)) or not self.expect_prompt():
|
91
|
+
return data
|
92
|
+
|
93
|
+
return self._strip_through_prefix(self.prompt, data)
|
94
|
+
|
95
|
+
def strip_become_success(self, data: bytes) -> bytes:
|
96
|
+
"""Strips the first found success marker from `data`, trailing whitespace and anything that precedes the success marker, then returns the result."""
|
97
|
+
return self._strip_through_prefix(self.success, data)
|
98
|
+
|
99
|
+
@staticmethod
|
100
|
+
def _strip_through_prefix(match: str | bytes, data: bytes) -> bytes:
|
101
|
+
"""Strips the first occurrence of `match` from `data`, trailing whitespace and anything that precedes `match`, then returns the result."""
|
102
|
+
return re.sub(br'^.*?' + re.escape(to_bytes(match)) + br'\s*', b'', data, count=1, flags=re.DOTALL)
|
103
|
+
|
81
104
|
def check_success(self, b_output):
|
82
105
|
b_success = to_bytes(self.success)
|
83
106
|
return any(b_success in l.rstrip() for l in b_output.splitlines(True))
|
84
107
|
|
85
108
|
def check_password_prompt(self, b_output):
|
86
|
-
|
109
|
+
""" checks if the expected password prompt exists in b_output """
|
87
110
|
if self.prompt:
|
88
111
|
b_prompt = to_bytes(self.prompt).strip()
|
89
112
|
return any(l.strip().startswith(b_prompt) for l in b_output.splitlines())
|
90
113
|
return False
|
91
114
|
|
92
115
|
def _check_password_error(self, b_out, msg):
|
93
|
-
|
116
|
+
""" returns True/False if domain specific i18n version of msg is found in b_out """
|
94
117
|
b_fail = to_bytes(dgettext(self.name, msg))
|
95
118
|
return b_fail and b_fail in b_out
|
96
119
|
|
ansible/plugins/become/runas.py
CHANGED
@@ -61,6 +61,8 @@ DOCUMENTATION = """
|
|
61
61
|
- The Secondary Logon service (seclogon) must be running to use runas
|
62
62
|
"""
|
63
63
|
|
64
|
+
from ansible.errors import AnsibleError
|
65
|
+
from ansible.parsing.splitter import split_args
|
64
66
|
from ansible.plugins.become import BecomeBase
|
65
67
|
|
66
68
|
|
@@ -72,3 +74,72 @@ class BecomeModule(BecomeBase):
|
|
72
74
|
# this is a noop, the 'real' runas is implemented
|
73
75
|
# inside the windows powershell execution subsystem
|
74
76
|
return cmd
|
77
|
+
|
78
|
+
def _build_powershell_wrapper_action(self) -> tuple[str, dict[str, object], dict[str, object]]:
|
79
|
+
# See ansible.executor.powershell.become_wrapper.ps1 for the
|
80
|
+
# parameter names
|
81
|
+
params = {
|
82
|
+
'BecomeUser': self.get_option('become_user'),
|
83
|
+
}
|
84
|
+
secure_params = {}
|
85
|
+
|
86
|
+
password = self.get_option('become_pass')
|
87
|
+
if password:
|
88
|
+
secure_params['BecomePassword'] = password
|
89
|
+
|
90
|
+
flags = self.get_option('become_flags')
|
91
|
+
if flags:
|
92
|
+
split_flags = split_args(flags)
|
93
|
+
for flag in split_flags:
|
94
|
+
if '=' not in flag:
|
95
|
+
raise ValueError(f"become_flags entry '{flag}' is in an invalid format, must be a key=value pair")
|
96
|
+
|
97
|
+
k, v = flag.split('=', 1)
|
98
|
+
|
99
|
+
param_name, param_value = self._parse_flag(k, v)
|
100
|
+
params[param_name] = param_value
|
101
|
+
|
102
|
+
return 'become_wrapper.ps1', params, secure_params
|
103
|
+
|
104
|
+
def _parse_flag(self, name: str, value: str) -> tuple[str, str]:
|
105
|
+
logon_types = {
|
106
|
+
'interactive': 'Interactive',
|
107
|
+
'network': 'Network',
|
108
|
+
'batch': 'Batch',
|
109
|
+
'service': 'Service',
|
110
|
+
'unlock': 'Unlock',
|
111
|
+
'network_cleartext': 'NetworkCleartext',
|
112
|
+
'new_credentials': 'NewCredentials',
|
113
|
+
}
|
114
|
+
logon_flags = {
|
115
|
+
'none': 'None',
|
116
|
+
'with_profile': 'WithProfile',
|
117
|
+
'netcredentials_only': 'NetCredentialsOnly',
|
118
|
+
}
|
119
|
+
|
120
|
+
match name.lower():
|
121
|
+
case 'logon_type':
|
122
|
+
param_name = 'LogonType'
|
123
|
+
if param_value := logon_types.get(value.lower(), None):
|
124
|
+
return param_name, param_value
|
125
|
+
else:
|
126
|
+
raise AnsibleError(f"become_flags logon_type value '{value}' is not valid, valid values are: {', '.join(logon_types.keys())}")
|
127
|
+
|
128
|
+
case 'logon_flags':
|
129
|
+
param_name = 'LogonFlags'
|
130
|
+
flags = value.split(',')
|
131
|
+
|
132
|
+
param_values: list[str] = []
|
133
|
+
for flag in flags:
|
134
|
+
if not flag:
|
135
|
+
continue
|
136
|
+
|
137
|
+
if flag_value := logon_flags.get(flag.lower(), None):
|
138
|
+
param_values.append(flag_value)
|
139
|
+
else:
|
140
|
+
raise AnsibleError(f"become_flags logon_flags value '{flag}' is not valid, valid values are: {', '.join(logon_flags.keys())}")
|
141
|
+
|
142
|
+
return param_name, ", ".join(param_values)
|
143
|
+
|
144
|
+
case _:
|
145
|
+
raise AnsibleError(f"become_flags key '{name}' is not a valid runas flag, must be 'logon_type' or 'logon_flags'")
|
ansible/plugins/become/su.py
CHANGED
@@ -93,7 +93,7 @@ DOCUMENTATION = """
|
|
93
93
|
import re
|
94
94
|
import shlex
|
95
95
|
|
96
|
-
from ansible.module_utils.common.text.converters import
|
96
|
+
from ansible.module_utils.common.text.converters import to_text
|
97
97
|
from ansible.plugins.become import BecomeBase
|
98
98
|
|
99
99
|
|
@@ -101,6 +101,8 @@ class BecomeModule(BecomeBase):
|
|
101
101
|
|
102
102
|
name = 'su'
|
103
103
|
|
104
|
+
pipelining = False
|
105
|
+
|
104
106
|
# messages for detecting prompted password issues
|
105
107
|
fail = ('Authentication failure',)
|
106
108
|
|
@@ -139,15 +141,18 @@ class BecomeModule(BecomeBase):
|
|
139
141
|
'口令',
|
140
142
|
]
|
141
143
|
|
142
|
-
def check_password_prompt(self, b_output):
|
143
|
-
|
144
|
-
|
144
|
+
def check_password_prompt(self, b_output: bytes) -> bool:
|
145
|
+
""" checks if the expected password prompt exists in b_output """
|
145
146
|
prompts = self.get_option('prompt_l10n') or self.SU_PROMPT_LOCALIZATIONS
|
146
|
-
|
147
|
+
password_prompt_strings = "|".join(re.escape(p) for p in prompts)
|
147
148
|
# Colon or unicode fullwidth colon
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
prompt_pattern = rf"(?:{password_prompt_strings})\s*[::]"
|
150
|
+
match = re.search(prompt_pattern, to_text(b_output), flags=re.IGNORECASE)
|
151
|
+
|
152
|
+
if match:
|
153
|
+
self.prompt = match.group(0) # preserve the actual matched string so we can scrub the output
|
154
|
+
|
155
|
+
return bool(match)
|
151
156
|
|
152
157
|
def build_become_command(self, cmd, shell):
|
153
158
|
super(BecomeModule, self).build_become_command(cmd, shell)
|
ansible/plugins/become/sudo.py
CHANGED
@@ -72,12 +72,25 @@ DOCUMENTATION = """
|
|
72
72
|
ini:
|
73
73
|
- section: sudo_become_plugin
|
74
74
|
key: password
|
75
|
+
sudo_chdir:
|
76
|
+
description: Directory to change to before invoking sudo; can avoid permission errors when dropping privileges.
|
77
|
+
type: string
|
78
|
+
required: False
|
79
|
+
version_added: '2.19'
|
80
|
+
vars:
|
81
|
+
- name: ansible_sudo_chdir
|
82
|
+
env:
|
83
|
+
- name: ANSIBLE_SUDO_CHDIR
|
84
|
+
ini:
|
85
|
+
- section: sudo_become_plugin
|
86
|
+
key: chdir
|
75
87
|
"""
|
76
88
|
|
77
89
|
import re
|
78
90
|
import shlex
|
79
91
|
|
80
92
|
from ansible.plugins.become import BecomeBase
|
93
|
+
from ansible.errors import AnsibleError
|
81
94
|
|
82
95
|
|
83
96
|
class BecomeModule(BecomeBase):
|
@@ -117,4 +130,10 @@ class BecomeModule(BecomeBase):
|
|
117
130
|
if user:
|
118
131
|
user = '-u %s' % (user)
|
119
132
|
|
133
|
+
if chdir := self.get_option('sudo_chdir'):
|
134
|
+
try:
|
135
|
+
becomecmd = f'{shell.CD} {shlex.quote(chdir)} {shell._SHELL_AND} {becomecmd}'
|
136
|
+
except AttributeError as ex:
|
137
|
+
raise AnsibleError(f'The {shell._load_name!r} shell plugin does not support sudo chdir. It is missing the {ex.name!r} attribute.')
|
138
|
+
|
120
139
|
return ' '.join([becomecmd, flags, prompt, user, self._build_success_command(cmd, shell)])
|