ansible-core 2.18.4rc1__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 +52 -17
- 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 +20 -18
- 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 +7 -7
- 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 +35 -49
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +39 -32
- 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 +8 -7
- 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 +2 -2
- 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.4rc1.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.4rc1.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.4rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
ansible/plugins/filter/core.py
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
6
|
import base64
|
7
|
+
import functools
|
7
8
|
import glob
|
8
9
|
import hashlib
|
9
10
|
import json
|
@@ -11,31 +12,34 @@ import ntpath
|
|
11
12
|
import os.path
|
12
13
|
import re
|
13
14
|
import shlex
|
14
|
-
import sys
|
15
15
|
import time
|
16
16
|
import uuid
|
17
17
|
import yaml
|
18
18
|
import datetime
|
19
|
+
import typing as t
|
19
20
|
|
20
21
|
from collections.abc import Mapping
|
21
22
|
from functools import partial
|
22
23
|
from random import Random, SystemRandom, shuffle
|
23
24
|
|
24
|
-
from jinja2.filters import pass_environment
|
25
|
+
from jinja2.filters import do_map, do_select, do_selectattr, do_reject, do_rejectattr, pass_environment, sync_do_groupby
|
26
|
+
from jinja2.environment import Environment
|
25
27
|
|
26
|
-
from ansible.
|
27
|
-
from ansible.
|
28
|
+
from ansible._internal._templating import _lazy_containers
|
29
|
+
from ansible.errors import AnsibleFilterError, AnsibleTypeError
|
30
|
+
from ansible.module_utils.datatag import native_type_name
|
31
|
+
from ansible.module_utils.common.json import get_encoder, get_decoder
|
32
|
+
from ansible.module_utils.six import string_types, integer_types, text_type
|
28
33
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
29
34
|
from ansible.module_utils.common.collections import is_sequence
|
30
35
|
from ansible.module_utils.common.yaml import yaml_load, yaml_load_all
|
31
|
-
from ansible.parsing.ajson import AnsibleJSONEncoder
|
32
36
|
from ansible.parsing.yaml.dumper import AnsibleDumper
|
33
|
-
from ansible.
|
37
|
+
from ansible.plugins import accept_args_markers, accept_lazy_markers
|
38
|
+
from ansible._internal._templating._jinja_common import MarkerError, UndefinedMarker, validate_arg_type
|
34
39
|
from ansible.utils.display import Display
|
35
40
|
from ansible.utils.encrypt import do_encrypt, PASSLIB_AVAILABLE
|
36
41
|
from ansible.utils.hashing import md5s, checksum_s
|
37
42
|
from ansible.utils.unicode import unicode_wrap
|
38
|
-
from ansible.utils.unsafe_proxy import _is_unsafe
|
39
43
|
from ansible.utils.vars import merge_hash
|
40
44
|
|
41
45
|
display = Display()
|
@@ -43,53 +47,77 @@ display = Display()
|
|
43
47
|
UUID_NAMESPACE_ANSIBLE = uuid.UUID('361E6D51-FAEC-444A-9079-341386DA8E2E')
|
44
48
|
|
45
49
|
|
46
|
-
def to_yaml(a, *
|
47
|
-
|
48
|
-
|
49
|
-
try:
|
50
|
-
transformed = yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, default_flow_style=default_flow_style, **kw)
|
51
|
-
except Exception as e:
|
52
|
-
raise AnsibleFilterError("to_yaml - %s" % to_native(e), orig_exc=e)
|
53
|
-
return to_text(transformed)
|
50
|
+
def to_yaml(a, *_args, default_flow_style: bool | None = None, dump_vault_tags: bool | None = None, **kwargs) -> str:
|
51
|
+
"""Serialize input as terse flow-style YAML."""
|
52
|
+
dumper = partial(AnsibleDumper, dump_vault_tags=dump_vault_tags)
|
54
53
|
|
54
|
+
return yaml.dump(a, Dumper=dumper, allow_unicode=True, default_flow_style=default_flow_style, **kwargs)
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
56
|
+
|
57
|
+
def to_nice_yaml(a, indent=4, *_args, default_flow_style=False, **kwargs) -> str:
|
58
|
+
"""Serialize input as verbose multi-line YAML."""
|
59
|
+
return to_yaml(a, indent=indent, default_flow_style=default_flow_style, **kwargs)
|
60
|
+
|
61
|
+
|
62
|
+
def from_json(a, profile: str | None = None, **kwargs) -> t.Any:
|
63
|
+
"""Deserialize JSON with an optional decoder profile."""
|
64
|
+
cls = get_decoder(profile or "tagless")
|
65
|
+
|
66
|
+
return json.loads(a, cls=cls, **kwargs)
|
63
67
|
|
64
68
|
|
65
|
-
def to_json(a,
|
66
|
-
|
69
|
+
def to_json(a, profile: str | None = None, vault_to_text: t.Any = ..., preprocess_unsafe: t.Any = ..., **kwargs) -> str:
|
70
|
+
"""Serialize as JSON with an optional encoder profile."""
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
kw['vault_to_text'] = True
|
71
|
-
if 'preprocess_unsafe' not in kw:
|
72
|
-
kw['preprocess_unsafe'] = False
|
72
|
+
if profile and vault_to_text is not ...:
|
73
|
+
raise ValueError("Only one of `vault_to_text` or `profile` can be specified.")
|
73
74
|
|
74
|
-
|
75
|
+
if profile and preprocess_unsafe is not ...:
|
76
|
+
raise ValueError("Only one of `preprocess_unsafe` or `profile` can be specified.")
|
75
77
|
|
78
|
+
# deprecated: description='deprecate vault_to_text' core_version='2.23'
|
79
|
+
# deprecated: description='deprecate preprocess_unsafe' core_version='2.23'
|
76
80
|
|
77
|
-
|
78
|
-
|
81
|
+
cls = get_encoder(profile or "tagless")
|
82
|
+
|
83
|
+
return json.dumps(a, cls=cls, **kwargs)
|
84
|
+
|
85
|
+
|
86
|
+
def to_nice_json(a, indent=4, sort_keys=True, **kwargs):
|
87
|
+
"""Make verbose, human-readable JSON."""
|
79
88
|
# TODO separators can be potentially exposed to the user as well
|
80
|
-
|
81
|
-
return to_json(a, indent=indent, sort_keys=sort_keys, separators=(',', ': '),
|
89
|
+
kwargs.pop('separators', None)
|
90
|
+
return to_json(a, indent=indent, sort_keys=sort_keys, separators=(',', ': '), **kwargs)
|
91
|
+
|
82
92
|
|
93
|
+
# CAUTION: Do not put non-string values here since they can have unwanted logical equality, such as 1.0 (equal to 1 and True) or 0.0 (equal to 0 and False).
|
94
|
+
_valid_bool_true = {'yes', 'on', 'true', '1'}
|
95
|
+
_valid_bool_false = {'no', 'off', 'false', '0'}
|
83
96
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
if isinstance(
|
89
|
-
|
90
|
-
|
97
|
+
|
98
|
+
def to_bool(value: object) -> bool:
|
99
|
+
"""Convert well-known input values to a boolean value."""
|
100
|
+
value_to_check: object
|
101
|
+
if isinstance(value, str):
|
102
|
+
value_to_check = value.lower() # accept mixed case variants
|
103
|
+
elif isinstance(value, int): # bool is also an int
|
104
|
+
value_to_check = str(value).lower() # accept int (0, 1) and bool (True, False) -- not just string versions
|
105
|
+
else:
|
106
|
+
value_to_check = value
|
107
|
+
|
108
|
+
if value_to_check in _valid_bool_true:
|
91
109
|
return True
|
92
|
-
|
110
|
+
|
111
|
+
if value_to_check in _valid_bool_false:
|
112
|
+
return False
|
113
|
+
|
114
|
+
# if we're still here, the value is unsupported- always fire a deprecation warning
|
115
|
+
result = value_to_check == 1 # backwards compatibility with the old code which checked: value in ('yes', 'on', '1', 'true', 1)
|
116
|
+
|
117
|
+
# NB: update the doc string to reflect reality once this fallback is removed
|
118
|
+
display.deprecated(f'The `bool` filter coerced invalid value {value!r} ({native_type_name(value)}) to {result!r}.', version='2.23')
|
119
|
+
|
120
|
+
return result
|
93
121
|
|
94
122
|
|
95
123
|
def to_datetime(string, format="%Y-%m-%d %H:%M:%S"):
|
@@ -97,7 +125,7 @@ def to_datetime(string, format="%Y-%m-%d %H:%M:%S"):
|
|
97
125
|
|
98
126
|
|
99
127
|
def strftime(string_format, second=None, utc=False):
|
100
|
-
|
128
|
+
""" return a date string using string. See https://docs.python.org/3/library/time.html#time.strftime for format """
|
101
129
|
if utc:
|
102
130
|
timefn = time.gmtime
|
103
131
|
else:
|
@@ -111,19 +139,19 @@ def strftime(string_format, second=None, utc=False):
|
|
111
139
|
|
112
140
|
|
113
141
|
def quote(a):
|
114
|
-
|
142
|
+
""" return its argument quoted for shell usage """
|
115
143
|
if a is None:
|
116
144
|
a = u''
|
117
145
|
return shlex.quote(to_text(a))
|
118
146
|
|
119
147
|
|
120
148
|
def fileglob(pathname):
|
121
|
-
|
149
|
+
""" return list of matched regular files for glob """
|
122
150
|
return [g for g in glob.glob(pathname) if os.path.isfile(g)]
|
123
151
|
|
124
152
|
|
125
153
|
def regex_replace(value='', pattern='', replacement='', ignorecase=False, multiline=False, count=0, mandatory_count=0):
|
126
|
-
|
154
|
+
""" Perform a `re.sub` returning a string """
|
127
155
|
|
128
156
|
value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
|
129
157
|
|
@@ -141,7 +169,7 @@ def regex_replace(value='', pattern='', replacement='', ignorecase=False, multil
|
|
141
169
|
|
142
170
|
|
143
171
|
def regex_findall(value, regex, multiline=False, ignorecase=False):
|
144
|
-
|
172
|
+
""" Perform re.findall and return the list of matches """
|
145
173
|
|
146
174
|
value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
|
147
175
|
|
@@ -154,7 +182,7 @@ def regex_findall(value, regex, multiline=False, ignorecase=False):
|
|
154
182
|
|
155
183
|
|
156
184
|
def regex_search(value, regex, *args, **kwargs):
|
157
|
-
|
185
|
+
""" Perform re.search and return the list of matches or a backref """
|
158
186
|
|
159
187
|
value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
|
160
188
|
|
@@ -187,7 +215,7 @@ def regex_search(value, regex, *args, **kwargs):
|
|
187
215
|
|
188
216
|
|
189
217
|
def ternary(value, true_val, false_val, none_val=None):
|
190
|
-
|
218
|
+
""" value ? true_val : false_val """
|
191
219
|
if value is None and none_val is not None:
|
192
220
|
return none_val
|
193
221
|
elif bool(value):
|
@@ -220,8 +248,6 @@ def from_yaml(data):
|
|
220
248
|
# The ``text_type`` call here strips any custom
|
221
249
|
# string wrapper class, so that CSafeLoader can
|
222
250
|
# read the data
|
223
|
-
if _is_unsafe(data):
|
224
|
-
data = data._strip_unsafe()
|
225
251
|
return yaml_load(text_type(to_text(data, errors='surrogate_or_strict')))
|
226
252
|
return data
|
227
253
|
|
@@ -231,8 +257,6 @@ def from_yaml_all(data):
|
|
231
257
|
# The ``text_type`` call here strips any custom
|
232
258
|
# string wrapper class, so that CSafeLoader can
|
233
259
|
# read the data
|
234
|
-
if _is_unsafe(data):
|
235
|
-
data = data._strip_unsafe()
|
236
260
|
return yaml_load_all(text_type(to_text(data, errors='surrogate_or_strict')))
|
237
261
|
return data
|
238
262
|
|
@@ -291,26 +315,10 @@ def get_encrypted_password(password, hashtype='sha512', salt=None, salt_size=Non
|
|
291
315
|
|
292
316
|
hashtype = passlib_mapping.get(hashtype, hashtype)
|
293
317
|
|
294
|
-
unknown_passlib_hashtype = False
|
295
318
|
if PASSLIB_AVAILABLE and hashtype not in passlib_mapping and hashtype not in passlib_mapping.values():
|
296
|
-
|
297
|
-
display.deprecated(
|
298
|
-
f"Checking for unsupported password_hash passlib hashtype '{hashtype}'. "
|
299
|
-
"This will be an error in the future as all supported hashtypes must be documented.",
|
300
|
-
version='2.19'
|
301
|
-
)
|
319
|
+
raise AnsibleFilterError(f"{hashtype} is not in the list of supported passlib algorithms: {', '.join(passlib_mapping)}")
|
302
320
|
|
303
|
-
|
304
|
-
return do_encrypt(password, hashtype, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
|
305
|
-
except AnsibleError as e:
|
306
|
-
reraise(AnsibleFilterError, AnsibleFilterError(to_native(e), orig_exc=e), sys.exc_info()[2])
|
307
|
-
except Exception as e:
|
308
|
-
if unknown_passlib_hashtype:
|
309
|
-
# This can occur if passlib.hash has the hashtype attribute, but it has a different signature than the valid choices.
|
310
|
-
# In 2.19 this will replace the deprecation warning above and the extra exception handling can be deleted.
|
311
|
-
choices = ', '.join(passlib_mapping)
|
312
|
-
raise AnsibleFilterError(f"{hashtype} is not in the list of supported passlib algorithms: {choices}") from e
|
313
|
-
raise
|
321
|
+
return do_encrypt(password, hashtype, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
|
314
322
|
|
315
323
|
|
316
324
|
def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
|
@@ -324,19 +332,21 @@ def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
|
|
324
332
|
return to_text(uuid.uuid5(uuid_namespace, to_native(string, errors='surrogate_or_strict')))
|
325
333
|
|
326
334
|
|
327
|
-
|
335
|
+
@accept_args_markers
|
336
|
+
def mandatory(a: object, msg: str | None = None) -> object:
|
328
337
|
"""Make a variable mandatory."""
|
329
|
-
|
338
|
+
# DTFIX-RELEASE: deprecate this filter; there are much better ways via undef, etc...
|
339
|
+
# also remember to remove unit test checking for _undefined_name
|
340
|
+
if isinstance(a, UndefinedMarker):
|
341
|
+
if msg is not None:
|
342
|
+
raise AnsibleFilterError(to_text(msg))
|
330
343
|
|
331
|
-
if isinstance(a, Undefined):
|
332
344
|
if a._undefined_name is not None:
|
333
|
-
name =
|
345
|
+
name = f'{to_text(a._undefined_name)!r} '
|
334
346
|
else:
|
335
347
|
name = ''
|
336
348
|
|
337
|
-
|
338
|
-
raise AnsibleFilterError(to_native(msg))
|
339
|
-
raise AnsibleFilterError("Mandatory variable %s not defined." % name)
|
349
|
+
raise AnsibleFilterError(f"Mandatory variable {name}not defined.")
|
340
350
|
|
341
351
|
return a
|
342
352
|
|
@@ -350,9 +360,6 @@ def combine(*terms, **kwargs):
|
|
350
360
|
# allow the user to do `[dict1, dict2, ...] | combine`
|
351
361
|
dictionaries = flatten(terms, levels=1)
|
352
362
|
|
353
|
-
# recursively check that every elements are defined (for jinja2)
|
354
|
-
recursive_check_defined(dictionaries)
|
355
|
-
|
356
363
|
if not dictionaries:
|
357
364
|
return {}
|
358
365
|
|
@@ -458,7 +465,7 @@ def comment(text, style='plain', **kw):
|
|
458
465
|
|
459
466
|
|
460
467
|
@pass_environment
|
461
|
-
def extract(environment, item, container, morekeys=None):
|
468
|
+
def extract(environment: Environment, item, container, morekeys=None):
|
462
469
|
if morekeys is None:
|
463
470
|
keys = [item]
|
464
471
|
elif isinstance(morekeys, list):
|
@@ -467,18 +474,28 @@ def extract(environment, item, container, morekeys=None):
|
|
467
474
|
keys = [item, morekeys]
|
468
475
|
|
469
476
|
value = container
|
477
|
+
|
470
478
|
for key in keys:
|
471
|
-
|
479
|
+
try:
|
480
|
+
value = environment.getitem(value, key)
|
481
|
+
except MarkerError as ex:
|
482
|
+
value = ex.source
|
472
483
|
|
473
484
|
return value
|
474
485
|
|
475
486
|
|
476
|
-
def b64encode(string, encoding='utf-8'):
|
477
|
-
|
487
|
+
def b64encode(string, encoding='utf-8', urlsafe=False):
|
488
|
+
func = base64.b64encode
|
489
|
+
if urlsafe:
|
490
|
+
func = base64.urlsafe_b64encode
|
491
|
+
return to_text(func(to_bytes(string, encoding=encoding, errors='surrogate_or_strict')))
|
478
492
|
|
479
493
|
|
480
|
-
def b64decode(string, encoding='utf-8'):
|
481
|
-
|
494
|
+
def b64decode(string, encoding='utf-8', urlsafe=False):
|
495
|
+
func = base64.b64decode
|
496
|
+
if urlsafe:
|
497
|
+
func = base64.urlsafe_b64decode
|
498
|
+
return to_text(func(to_bytes(string, errors='surrogate_or_strict')), encoding=encoding)
|
482
499
|
|
483
500
|
|
484
501
|
def flatten(mylist, levels=None, skip_nulls=True):
|
@@ -503,14 +520,14 @@ def flatten(mylist, levels=None, skip_nulls=True):
|
|
503
520
|
|
504
521
|
|
505
522
|
def subelements(obj, subelements, skip_missing=False):
|
506
|
-
|
523
|
+
"""Accepts a dict or list of dicts, and a dotted accessor and produces a product
|
507
524
|
of the element and the results of the dotted accessor
|
508
525
|
|
509
526
|
>>> obj = [{"name": "alice", "groups": ["wheel"], "authorized": ["/tmp/alice/onekey.pub"]}]
|
510
527
|
>>> subelements(obj, 'groups')
|
511
528
|
[({'name': 'alice', 'groups': ['wheel'], 'authorized': ['/tmp/alice/onekey.pub']}, 'wheel')]
|
512
529
|
|
513
|
-
|
530
|
+
"""
|
514
531
|
if isinstance(obj, dict):
|
515
532
|
element_list = list(obj.values())
|
516
533
|
elif isinstance(obj, list):
|
@@ -523,7 +540,7 @@ def subelements(obj, subelements, skip_missing=False):
|
|
523
540
|
elif isinstance(subelements, string_types):
|
524
541
|
subelement_list = subelements.split('.')
|
525
542
|
else:
|
526
|
-
raise
|
543
|
+
raise AnsibleTypeError('subelements must be a list or a string')
|
527
544
|
|
528
545
|
results = []
|
529
546
|
|
@@ -537,10 +554,10 @@ def subelements(obj, subelements, skip_missing=False):
|
|
537
554
|
values = []
|
538
555
|
break
|
539
556
|
raise AnsibleFilterError("could not find %r key in iterated item %r" % (subelement, values))
|
540
|
-
except TypeError:
|
541
|
-
raise
|
557
|
+
except TypeError as ex:
|
558
|
+
raise AnsibleTypeError("the key %s should point to a dictionary, got '%s'" % (subelement, values)) from ex
|
542
559
|
if not isinstance(values, list):
|
543
|
-
raise
|
560
|
+
raise AnsibleTypeError("the key %r should point to a list, got %r" % (subelement, values))
|
544
561
|
|
545
562
|
for value in values:
|
546
563
|
results.append((element, value))
|
@@ -549,11 +566,11 @@ def subelements(obj, subelements, skip_missing=False):
|
|
549
566
|
|
550
567
|
|
551
568
|
def dict_to_list_of_dict_key_value_elements(mydict, key_name='key', value_name='value'):
|
552
|
-
|
553
|
-
with each having a 'key' and 'value' keys that correspond to the keys and values of the original
|
569
|
+
""" takes a dictionary and transforms it into a list of dictionaries,
|
570
|
+
with each having a 'key' and 'value' keys that correspond to the keys and values of the original """
|
554
571
|
|
555
572
|
if not isinstance(mydict, Mapping):
|
556
|
-
raise
|
573
|
+
raise AnsibleTypeError("dict2items requires a dictionary, got %s instead." % type(mydict))
|
557
574
|
|
558
575
|
ret = []
|
559
576
|
for key in mydict:
|
@@ -562,31 +579,31 @@ def dict_to_list_of_dict_key_value_elements(mydict, key_name='key', value_name='
|
|
562
579
|
|
563
580
|
|
564
581
|
def list_of_dict_key_value_elements_to_dict(mylist, key_name='key', value_name='value'):
|
565
|
-
|
566
|
-
effectively as the reverse of dict2items
|
582
|
+
""" takes a list of dicts with each having a 'key' and 'value' keys, and transforms the list into a dictionary,
|
583
|
+
effectively as the reverse of dict2items """
|
567
584
|
|
568
585
|
if not is_sequence(mylist):
|
569
|
-
raise
|
586
|
+
raise AnsibleTypeError("items2dict requires a list, got %s instead." % type(mylist))
|
570
587
|
|
571
588
|
try:
|
572
589
|
return dict((item[key_name], item[value_name]) for item in mylist)
|
573
590
|
except KeyError:
|
574
|
-
raise
|
591
|
+
raise AnsibleTypeError(
|
575
592
|
"items2dict requires each dictionary in the list to contain the keys '%s' and '%s', got %s instead."
|
576
593
|
% (key_name, value_name, mylist)
|
577
594
|
)
|
578
595
|
except TypeError:
|
579
|
-
raise
|
596
|
+
raise AnsibleTypeError("items2dict requires a list of dictionaries, got %s instead." % mylist)
|
580
597
|
|
581
598
|
|
582
599
|
def path_join(paths):
|
583
|
-
|
584
|
-
of the different members
|
600
|
+
""" takes a sequence or a string, and return a concatenation
|
601
|
+
of the different members """
|
585
602
|
if isinstance(paths, string_types):
|
586
603
|
return os.path.join(paths)
|
587
604
|
if is_sequence(paths):
|
588
605
|
return os.path.join(*paths)
|
589
|
-
raise
|
606
|
+
raise AnsibleTypeError("|path_join expects string or sequence, got %s instead." % type(paths))
|
590
607
|
|
591
608
|
|
592
609
|
def commonpath(paths):
|
@@ -599,13 +616,92 @@ def commonpath(paths):
|
|
599
616
|
:rtype: str
|
600
617
|
"""
|
601
618
|
if not is_sequence(paths):
|
602
|
-
raise
|
619
|
+
raise AnsibleTypeError("|commonpath expects sequence, got %s instead." % type(paths))
|
603
620
|
|
604
621
|
return os.path.commonpath(paths)
|
605
622
|
|
606
623
|
|
624
|
+
class GroupTuple(t.NamedTuple):
|
625
|
+
"""
|
626
|
+
Custom named tuple for the groupby filter with a public interface; silently ignored by unknown type checks.
|
627
|
+
This matches the internal implementation of the _GroupTuple returned by Jinja's built-in groupby filter.
|
628
|
+
"""
|
629
|
+
|
630
|
+
grouper: t.Any
|
631
|
+
list: list[t.Any]
|
632
|
+
|
633
|
+
def __repr__(self) -> str:
|
634
|
+
return tuple.__repr__(self)
|
635
|
+
|
636
|
+
|
637
|
+
_lazy_containers.register_known_types(GroupTuple)
|
638
|
+
|
639
|
+
|
640
|
+
@pass_environment
|
641
|
+
def _cleansed_groupby(*args, **kwargs):
|
642
|
+
res = sync_do_groupby(*args, **kwargs)
|
643
|
+
res = [GroupTuple(grouper=g.grouper, list=g.list) for g in res]
|
644
|
+
|
645
|
+
return res
|
646
|
+
|
647
|
+
# DTFIX-RELEASE: make these dumb wrappers more dynamic
|
648
|
+
|
649
|
+
|
650
|
+
@accept_args_markers
|
651
|
+
def ansible_default(
|
652
|
+
value: t.Any,
|
653
|
+
default_value: t.Any = '',
|
654
|
+
boolean: bool = False,
|
655
|
+
) -> t.Any:
|
656
|
+
"""Updated `default` filter that only coalesces classic undefined objects; other Undefined-derived types (eg, ErrorMarker) pass through."""
|
657
|
+
validate_arg_type('boolean', boolean, bool)
|
658
|
+
|
659
|
+
if isinstance(value, UndefinedMarker):
|
660
|
+
return default_value
|
661
|
+
|
662
|
+
if boolean and not value:
|
663
|
+
return default_value
|
664
|
+
|
665
|
+
return value
|
666
|
+
|
667
|
+
|
668
|
+
@accept_lazy_markers
|
669
|
+
@functools.wraps(do_map)
|
670
|
+
def wrapped_map(*args, **kwargs) -> t.Any:
|
671
|
+
return do_map(*args, **kwargs)
|
672
|
+
|
673
|
+
|
674
|
+
@accept_lazy_markers
|
675
|
+
@functools.wraps(do_select)
|
676
|
+
def wrapped_select(*args, **kwargs) -> t.Any:
|
677
|
+
return do_select(*args, **kwargs)
|
678
|
+
|
679
|
+
|
680
|
+
@accept_lazy_markers
|
681
|
+
@functools.wraps(do_selectattr)
|
682
|
+
def wrapped_selectattr(*args, **kwargs) -> t.Any:
|
683
|
+
return do_selectattr(*args, **kwargs)
|
684
|
+
|
685
|
+
|
686
|
+
@accept_lazy_markers
|
687
|
+
@functools.wraps(do_reject)
|
688
|
+
def wrapped_reject(*args, **kwargs) -> t.Any:
|
689
|
+
return do_reject(*args, **kwargs)
|
690
|
+
|
691
|
+
|
692
|
+
@accept_lazy_markers
|
693
|
+
@functools.wraps(do_rejectattr)
|
694
|
+
def wrapped_rejectattr(*args, **kwargs) -> t.Any:
|
695
|
+
return do_rejectattr(*args, **kwargs)
|
696
|
+
|
697
|
+
|
698
|
+
@accept_args_markers
|
699
|
+
def type_debug(obj: object) -> str:
|
700
|
+
return native_type_name(obj)
|
701
|
+
|
702
|
+
|
607
703
|
class FilterModule(object):
|
608
|
-
|
704
|
+
""" Ansible core jinja2 filters """
|
609
705
|
|
610
706
|
def filters(self):
|
611
707
|
return {
|
@@ -619,7 +715,7 @@ class FilterModule(object):
|
|
619
715
|
# json
|
620
716
|
'to_json': to_json,
|
621
717
|
'to_nice_json': to_nice_json,
|
622
|
-
'from_json':
|
718
|
+
'from_json': from_json,
|
623
719
|
|
624
720
|
# yaml
|
625
721
|
'to_yaml': to_yaml,
|
@@ -686,7 +782,7 @@ class FilterModule(object):
|
|
686
782
|
'comment': comment,
|
687
783
|
|
688
784
|
# debug
|
689
|
-
'type_debug':
|
785
|
+
'type_debug': type_debug,
|
690
786
|
|
691
787
|
# Data structures
|
692
788
|
'combine': combine,
|
@@ -696,4 +792,18 @@ class FilterModule(object):
|
|
696
792
|
'items2dict': list_of_dict_key_value_elements_to_dict,
|
697
793
|
'subelements': subelements,
|
698
794
|
'split': partial(unicode_wrap, text_type.split),
|
795
|
+
# FDI038 - replace this with a standard type compat shim
|
796
|
+
'groupby': _cleansed_groupby,
|
797
|
+
|
798
|
+
# Jinja builtins that need special arg handling
|
799
|
+
# DTFIX-RELEASE: document these now that they're overridden, or hide them so they don't show up as undocumented
|
800
|
+
'd': ansible_default, # replaces the implementation instead of wrapping it
|
801
|
+
'default': ansible_default, # replaces the implementation instead of wrapping it
|
802
|
+
'map': wrapped_map,
|
803
|
+
'select': wrapped_select,
|
804
|
+
'selectattr': wrapped_selectattr,
|
805
|
+
'reject': wrapped_reject,
|
806
|
+
'rejectattr': wrapped_rejectattr,
|
699
807
|
}
|
808
|
+
|
809
|
+
# DTFIX-RELEASE: document protomatter plugins, or hide them from ansible-doc/galaxy (not related to this code, but needed some place to put this comment)
|