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
ansible/playbook/base.py
CHANGED
@@ -9,24 +9,27 @@ import itertools
|
|
9
9
|
import operator
|
10
10
|
import os
|
11
11
|
|
12
|
+
import typing as t
|
13
|
+
|
12
14
|
from copy import copy as shallowcopy
|
13
15
|
from functools import cache
|
14
16
|
|
15
|
-
from jinja2.exceptions import UndefinedError
|
16
|
-
|
17
17
|
from ansible import constants as C
|
18
18
|
from ansible import context
|
19
|
-
from ansible.errors import AnsibleError, AnsibleParserError,
|
19
|
+
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleAssertionError, AnsibleValueOmittedError, AnsibleFieldAttributeError
|
20
|
+
from ansible.module_utils.datatag import native_type_name
|
21
|
+
from ansible._internal._datatag._tags import Origin
|
20
22
|
from ansible.module_utils.six import string_types
|
21
23
|
from ansible.module_utils.parsing.convert_bool import boolean
|
24
|
+
from ansible.module_utils.common.sentinel import Sentinel
|
22
25
|
from ansible.module_utils.common.text.converters import to_text
|
23
26
|
from ansible.parsing.dataloader import DataLoader
|
24
27
|
from ansible.playbook.attribute import Attribute, FieldAttribute, ConnectionFieldAttribute, NonInheritableFieldAttribute
|
25
28
|
from ansible.plugins.loader import module_loader, action_loader
|
26
29
|
from ansible.utils.collection_loader._collection_finder import _get_collection_metadata, AnsibleCollectionRef
|
27
30
|
from ansible.utils.display import Display
|
28
|
-
from ansible.utils.
|
29
|
-
from ansible.
|
31
|
+
from ansible.utils.vars import combine_vars, get_unique_id, validate_variable_name
|
32
|
+
from ansible._internal._templating._engine import TemplateEngine
|
30
33
|
|
31
34
|
display = Display()
|
32
35
|
|
@@ -96,12 +99,13 @@ class FieldAttributeBase:
|
|
96
99
|
fattributes[attr.alias] = attr
|
97
100
|
return fattributes
|
98
101
|
|
99
|
-
def __init__(self):
|
102
|
+
def __init__(self) -> None:
|
100
103
|
|
101
104
|
# initialize the data loader and variable manager, which will be provided
|
102
105
|
# later when the object is actually loaded
|
103
106
|
self._loader = None
|
104
107
|
self._variable_manager = None
|
108
|
+
self._origin: Origin | None = None
|
105
109
|
|
106
110
|
# other internal params
|
107
111
|
self._validated = False
|
@@ -111,15 +115,12 @@ class FieldAttributeBase:
|
|
111
115
|
# every object gets a random uuid:
|
112
116
|
self._uuid = get_unique_id()
|
113
117
|
|
114
|
-
# init vars, avoid using defaults in field declaration as it lives across plays
|
115
|
-
self.vars = dict()
|
116
|
-
|
117
118
|
@property
|
118
119
|
def finalized(self):
|
119
120
|
return self._finalized
|
120
121
|
|
121
122
|
def dump_me(self, depth=0):
|
122
|
-
|
123
|
+
""" this is never called from production code, it is here to be used when debugging as a 'complex print' """
|
123
124
|
if depth == 0:
|
124
125
|
display.debug("DUMPING OBJECT ------------------------------------------------------")
|
125
126
|
display.debug("%s- %s (%s, id=%s)" % (" " * depth, self.__class__.__name__, self, id(self)))
|
@@ -133,11 +134,11 @@ class FieldAttributeBase:
|
|
133
134
|
self._play.dump_me(depth + 2)
|
134
135
|
|
135
136
|
def preprocess_data(self, ds):
|
136
|
-
|
137
|
+
""" infrequently used method to do some pre-processing of legacy terms """
|
137
138
|
return ds
|
138
139
|
|
139
140
|
def load_data(self, ds, variable_manager=None, loader=None):
|
140
|
-
|
141
|
+
""" walk the input datastructure and assign any values """
|
141
142
|
|
142
143
|
if ds is None:
|
143
144
|
raise AnsibleAssertionError('ds (%s) should not be None but it is.' % ds)
|
@@ -148,6 +149,7 @@ class FieldAttributeBase:
|
|
148
149
|
# the variable manager class is used to manage and merge variables
|
149
150
|
# down to a single dictionary for reference in templating, etc.
|
150
151
|
self._variable_manager = variable_manager
|
152
|
+
self._origin = Origin.get_tag(ds)
|
151
153
|
|
152
154
|
# the data loader class is used to parse data from strings and files
|
153
155
|
if loader is not None:
|
@@ -191,25 +193,29 @@ class FieldAttributeBase:
|
|
191
193
|
return self._variable_manager
|
192
194
|
|
193
195
|
def _post_validate_debugger(self, attr, value, templar):
|
194
|
-
|
196
|
+
try:
|
197
|
+
value = templar.template(value)
|
198
|
+
except AnsibleValueOmittedError:
|
199
|
+
value = self.set_to_context(attr.name)
|
200
|
+
|
195
201
|
valid_values = frozenset(('always', 'on_failed', 'on_unreachable', 'on_skipped', 'never'))
|
196
202
|
if value and isinstance(value, string_types) and value not in valid_values:
|
197
203
|
raise AnsibleParserError("'%s' is not a valid value for debugger. Must be one of %s" % (value, ', '.join(valid_values)), obj=self.get_ds())
|
198
204
|
return value
|
199
205
|
|
200
206
|
def _validate_attributes(self, ds):
|
201
|
-
|
207
|
+
"""
|
202
208
|
Ensures that there are no keys in the datastructure which do
|
203
209
|
not map to attributes for this object.
|
204
|
-
|
210
|
+
"""
|
205
211
|
|
206
212
|
valid_attrs = frozenset(self.fattributes)
|
207
213
|
for key in ds:
|
208
214
|
if key not in valid_attrs:
|
209
|
-
raise AnsibleParserError("'%s' is not a valid attribute for a %s" % (key, self.__class__.__name__), obj=
|
215
|
+
raise AnsibleParserError("'%s' is not a valid attribute for a %s" % (key, self.__class__.__name__), obj=key)
|
210
216
|
|
211
217
|
def validate(self, all_vars=None):
|
212
|
-
|
218
|
+
""" validation that is done at parse time, not load time """
|
213
219
|
all_vars = {} if all_vars is None else all_vars
|
214
220
|
|
215
221
|
if not self._validated:
|
@@ -244,7 +250,8 @@ class FieldAttributeBase:
|
|
244
250
|
raise AnsibleParserError(
|
245
251
|
"The field 'module_defaults' is supposed to be a dictionary or list of dictionaries, "
|
246
252
|
"the keys of which must be static action, module, or group names. Only the values may contain "
|
247
|
-
"templates. For example: {'ping': \"{{ ping_defaults }}\"}"
|
253
|
+
"templates. For example: {'ping': \"{{ ping_defaults }}\"}",
|
254
|
+
obj=defaults_dict,
|
248
255
|
)
|
249
256
|
|
250
257
|
validated_defaults_dict = {}
|
@@ -402,31 +409,32 @@ class FieldAttributeBase:
|
|
402
409
|
display.vvvvv("Could not resolve action %s in module_defaults" % action_name)
|
403
410
|
|
404
411
|
def squash(self):
|
405
|
-
|
412
|
+
"""
|
406
413
|
Evaluates all attributes and sets them to the evaluated version,
|
407
414
|
so that all future accesses of attributes do not need to evaluate
|
408
415
|
parent attributes.
|
409
|
-
|
416
|
+
"""
|
410
417
|
if not self._squashed:
|
411
418
|
for name in self.fattributes:
|
412
419
|
setattr(self, name, getattr(self, name))
|
413
420
|
self._squashed = True
|
414
421
|
|
415
422
|
def copy(self):
|
416
|
-
|
423
|
+
"""
|
417
424
|
Create a copy of this object and return it.
|
418
|
-
|
425
|
+
"""
|
419
426
|
|
420
427
|
try:
|
421
428
|
new_me = self.__class__()
|
422
|
-
except
|
423
|
-
raise AnsibleError("Exceeded maximum object depth. This may have been caused by excessive role recursion"
|
429
|
+
except RecursionError as ex:
|
430
|
+
raise AnsibleError("Exceeded maximum object depth. This may have been caused by excessive role recursion.") from ex
|
424
431
|
|
425
432
|
for name in self.fattributes:
|
426
433
|
setattr(new_me, name, shallowcopy(getattr(self, f'_{name}', Sentinel)))
|
427
434
|
|
428
435
|
new_me._loader = self._loader
|
429
436
|
new_me._variable_manager = self._variable_manager
|
437
|
+
new_me._origin = self._origin
|
430
438
|
new_me._validated = self._validated
|
431
439
|
new_me._finalized = self._finalized
|
432
440
|
new_me._uuid = self._uuid
|
@@ -438,6 +446,12 @@ class FieldAttributeBase:
|
|
438
446
|
return new_me
|
439
447
|
|
440
448
|
def get_validated_value(self, name, attribute, value, templar):
|
449
|
+
try:
|
450
|
+
return self._get_validated_value(name, attribute, value, templar)
|
451
|
+
except (TypeError, ValueError):
|
452
|
+
raise AnsibleError(f"The value {value!r} could not be converted to {attribute.isa!r}.", obj=value)
|
453
|
+
|
454
|
+
def _get_validated_value(self, name, attribute, value, templar):
|
441
455
|
if attribute.isa == 'string':
|
442
456
|
value = to_text(value)
|
443
457
|
elif attribute.isa == 'int':
|
@@ -466,28 +480,23 @@ class FieldAttributeBase:
|
|
466
480
|
if attribute.listof is not None:
|
467
481
|
for item in value:
|
468
482
|
if not isinstance(item, attribute.listof):
|
469
|
-
|
470
|
-
|
471
|
-
|
483
|
+
type_names = ' or '.join(f'{native_type_name(attribute_type)!r}' for attribute_type in attribute.listof)
|
484
|
+
|
485
|
+
raise AnsibleParserError(
|
486
|
+
message=f"Keyword {name!r} items must be of type {type_names}, not {native_type_name(item)!r}.",
|
487
|
+
obj=Origin.first_tagged_on(item, value, self.get_ds()),
|
488
|
+
)
|
489
|
+
elif attribute.required and attribute.listof == (str,):
|
472
490
|
if item is None or item.strip() == "":
|
473
|
-
raise AnsibleParserError(
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
elif not isinstance(value, (list, set)):
|
478
|
-
if isinstance(value, string_types):
|
479
|
-
value = value.split(',')
|
480
|
-
else:
|
481
|
-
# Making a list like this handles strings of
|
482
|
-
# text and bytes properly
|
483
|
-
value = [value]
|
484
|
-
if not isinstance(value, set):
|
485
|
-
value = set(value)
|
491
|
+
raise AnsibleParserError(
|
492
|
+
message=f"Keyword {name!r} is required, and cannot have empty values.",
|
493
|
+
obj=Origin.first_tagged_on(item, value, self.get_ds()),
|
494
|
+
)
|
486
495
|
elif attribute.isa == 'dict':
|
487
496
|
if value is None:
|
488
497
|
value = dict()
|
489
498
|
elif not isinstance(value, dict):
|
490
|
-
raise
|
499
|
+
raise AnsibleError(f"{value!r} is not a dictionary")
|
491
500
|
elif attribute.isa == 'class':
|
492
501
|
if not isinstance(value, attribute.class_type):
|
493
502
|
raise TypeError("%s is not a valid %s (got a %s instead)" % (name, attribute.class_type, type(value)))
|
@@ -496,119 +505,132 @@ class FieldAttributeBase:
|
|
496
505
|
raise AnsibleAssertionError(f"Unknown value for attribute.isa: {attribute.isa}")
|
497
506
|
return value
|
498
507
|
|
499
|
-
def set_to_context(self, name):
|
500
|
-
|
508
|
+
def set_to_context(self, name: str) -> t.Any:
|
509
|
+
""" set to parent inherited value or Sentinel as appropriate"""
|
501
510
|
|
502
511
|
attribute = self.fattributes[name]
|
503
512
|
if isinstance(attribute, NonInheritableFieldAttribute):
|
504
513
|
# setting to sentinel will trigger 'default/default()' on getter
|
505
|
-
|
514
|
+
value = Sentinel
|
506
515
|
else:
|
507
516
|
try:
|
508
|
-
|
517
|
+
value = self._get_parent_attribute(name, omit=True)
|
509
518
|
except AttributeError:
|
510
519
|
# mostly playcontext as only tasks/handlers/blocks really resolve parent
|
511
|
-
|
520
|
+
value = Sentinel
|
521
|
+
|
522
|
+
setattr(self, name, value)
|
523
|
+
return value
|
512
524
|
|
513
525
|
def post_validate(self, templar):
|
514
|
-
|
526
|
+
"""
|
515
527
|
we can't tell that everything is of the right type until we have
|
516
528
|
all the variables. Run basic types (from isa) as well as
|
517
529
|
any _post_validate_<foo> functions.
|
518
|
-
|
530
|
+
"""
|
519
531
|
|
520
|
-
|
521
|
-
|
532
|
+
for name in self.fattributes:
|
533
|
+
value = self.post_validate_attribute(name, templar=templar)
|
522
534
|
|
523
|
-
|
524
|
-
|
525
|
-
|
535
|
+
if value is not Sentinel:
|
536
|
+
# and assign the massaged value back to the attribute field
|
537
|
+
setattr(self, name, value)
|
526
538
|
|
527
|
-
|
528
|
-
if name not in ('vars',) and templar.is_template(value):
|
529
|
-
display.warning('"%s" is not templatable, but we found: %s, '
|
530
|
-
'it will not be templated and will be used "as is".' % (name, value))
|
531
|
-
continue
|
539
|
+
self._finalized = True
|
532
540
|
|
533
|
-
|
534
|
-
|
535
|
-
continue
|
536
|
-
else:
|
537
|
-
raise AnsibleParserError("the field '%s' is required but was not set" % name)
|
538
|
-
elif not attribute.always_post_validate and self.__class__.__name__ not in ('Task', 'Handler', 'PlayContext'):
|
539
|
-
# Intermediate objects like Play() won't have their fields validated by
|
540
|
-
# default, as their values are often inherited by other objects and validated
|
541
|
-
# later, so we don't want them to fail out early
|
542
|
-
continue
|
541
|
+
def post_validate_attribute(self, name: str, *, templar: TemplateEngine):
|
542
|
+
attribute: FieldAttribute = self.fattributes[name]
|
543
543
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
544
|
+
# DTFIX-FUTURE: this can probably be used in many getattr cases below, but the value may be out-of-date in some cases
|
545
|
+
original_value = getattr(self, name) # we save this original (likely Origin-tagged) value to pass as `obj` for errors
|
546
|
+
|
547
|
+
if attribute.static:
|
548
|
+
value = getattr(self, name)
|
549
|
+
|
550
|
+
# we don't template 'vars' but allow template as values for later use
|
551
|
+
if name not in ('vars',) and templar.is_template(value):
|
552
|
+
display.warning('"%s" is not templatable, but we found: %s, '
|
553
|
+
'it will not be templated and will be used "as is".' % (name, value))
|
554
|
+
return Sentinel
|
555
|
+
|
556
|
+
if getattr(self, name) is None:
|
557
|
+
if not attribute.required:
|
558
|
+
return Sentinel
|
559
|
+
|
560
|
+
raise AnsibleFieldAttributeError(f'The field {name!r} is required but was not set.', obj=self.get_ds())
|
561
|
+
|
562
|
+
from .role_include import IncludeRole
|
563
|
+
|
564
|
+
if not attribute.always_post_validate and isinstance(self, IncludeRole) and self.statically_loaded: # import_role
|
565
|
+
# normal field attributes should not go through post validation on import_role/import_tasks
|
566
|
+
# only import_role is checked here because import_tasks never reaches this point
|
567
|
+
return Sentinel
|
568
|
+
|
569
|
+
# FIXME: compare types, not strings
|
570
|
+
if not attribute.always_post_validate and self.__class__.__name__ not in ('Task', 'Handler', 'PlayContext', 'IncludeRole', 'TaskInclude'):
|
571
|
+
# Intermediate objects like Play() won't have their fields validated by
|
572
|
+
# default, as their values are often inherited by other objects and validated
|
573
|
+
# later, so we don't want them to fail out early
|
574
|
+
return Sentinel
|
575
|
+
|
576
|
+
try:
|
577
|
+
# Run the post-validator if present. These methods are responsible for
|
578
|
+
# using the given templar to template the values, if required.
|
579
|
+
method = getattr(self, '_post_validate_%s' % name, None)
|
580
|
+
|
581
|
+
if method:
|
582
|
+
value = method(attribute, getattr(self, name), templar)
|
583
|
+
elif attribute.isa == 'class':
|
584
|
+
value = getattr(self, name)
|
585
|
+
else:
|
586
|
+
try:
|
553
587
|
# if the attribute contains a variable, template it now
|
554
588
|
value = templar.template(getattr(self, name))
|
589
|
+
except AnsibleValueOmittedError:
|
590
|
+
# If this evaluated to the omit value, set the value back to inherited by context
|
591
|
+
# or default specified in the FieldAttribute and move on
|
592
|
+
value = self.set_to_context(name)
|
555
593
|
|
556
|
-
|
557
|
-
|
558
|
-
if omit_value is not None and value == omit_value:
|
559
|
-
self.set_to_context(name)
|
560
|
-
continue
|
594
|
+
if value is Sentinel:
|
595
|
+
return value
|
561
596
|
|
562
|
-
|
563
|
-
|
564
|
-
|
597
|
+
# and make sure the attribute is of the type it should be
|
598
|
+
if value is not None:
|
599
|
+
value = self.get_validated_value(name, attribute, value, templar)
|
565
600
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
raise
|
571
|
-
obj=self.get_ds(), orig_exc=e)
|
572
|
-
except (AnsibleUndefinedVariable, UndefinedError) as e:
|
573
|
-
if templar._fail_on_undefined_errors and name != 'name':
|
574
|
-
if name == 'args':
|
575
|
-
msg = "The task includes an option with an undefined variable."
|
576
|
-
else:
|
577
|
-
msg = f"The field '{name}' has an invalid value, which includes an undefined variable."
|
578
|
-
raise AnsibleParserError(msg, obj=self.get_ds(), orig_exc=e)
|
601
|
+
# returning the value results in assigning the massaged value back to the attribute field
|
602
|
+
return value
|
603
|
+
except Exception as ex:
|
604
|
+
if name == 'args':
|
605
|
+
raise # no useful information to contribute, raise the original exception
|
579
606
|
|
580
|
-
|
607
|
+
raise AnsibleFieldAttributeError(f'Error processing keyword {name!r}.', obj=original_value) from ex
|
581
608
|
|
582
609
|
def _load_vars(self, attr, ds):
|
583
|
-
|
610
|
+
"""
|
584
611
|
Vars in a play must be specified as a dictionary.
|
585
|
-
|
586
|
-
|
587
|
-
def _validate_variable_keys(ds):
|
588
|
-
for key in ds:
|
589
|
-
if not isidentifier(key):
|
590
|
-
raise TypeError("'%s' is not a valid variable name" % key)
|
612
|
+
"""
|
591
613
|
|
592
614
|
try:
|
593
615
|
if isinstance(ds, dict):
|
594
|
-
|
616
|
+
for key in ds:
|
617
|
+
validate_variable_name(key)
|
595
618
|
return combine_vars(self.vars, ds)
|
596
619
|
elif ds is None:
|
597
620
|
return {}
|
598
621
|
else:
|
599
622
|
raise ValueError
|
600
|
-
except ValueError as
|
601
|
-
raise AnsibleParserError("Vars in a
|
602
|
-
|
603
|
-
|
604
|
-
raise AnsibleParserError("Invalid variable name in vars specified for %s: %s" % (self.__class__.__name__, e), obj=ds, orig_exc=e)
|
623
|
+
except ValueError as ex:
|
624
|
+
raise AnsibleParserError(f"Vars in a {self.__class__.__name__} must be specified as a dictionary.", obj=ds) from ex
|
625
|
+
except TypeError as ex:
|
626
|
+
raise AnsibleParserError(f"Invalid variable name in vars specified for {self.__class__.__name__}.", obj=ds) from ex
|
605
627
|
|
606
628
|
def _extend_value(self, value, new_value, prepend=False):
|
607
|
-
|
629
|
+
"""
|
608
630
|
Will extend the value given with new_value (and will turn both
|
609
631
|
into lists if they are not so already). The values are run through
|
610
632
|
a set to remove duplicate values.
|
611
|
-
|
633
|
+
"""
|
612
634
|
|
613
635
|
if not isinstance(value, list):
|
614
636
|
value = [value]
|
@@ -629,9 +651,9 @@ class FieldAttributeBase:
|
|
629
651
|
return [i for i, dummy in itertools.groupby(combined) if i is not None]
|
630
652
|
|
631
653
|
def dump_attrs(self):
|
632
|
-
|
654
|
+
"""
|
633
655
|
Dumps all attributes to a dictionary
|
634
|
-
|
656
|
+
"""
|
635
657
|
attrs = {}
|
636
658
|
for (name, attribute) in self.fattributes.items():
|
637
659
|
attr = getattr(self, name)
|
@@ -642,9 +664,9 @@ class FieldAttributeBase:
|
|
642
664
|
return attrs
|
643
665
|
|
644
666
|
def from_attrs(self, attrs):
|
645
|
-
|
667
|
+
"""
|
646
668
|
Loads attributes from a dictionary
|
647
|
-
|
669
|
+
"""
|
648
670
|
for (attr, value) in attrs.items():
|
649
671
|
if attr in self.fattributes:
|
650
672
|
attribute = self.fattributes[attr]
|
@@ -654,6 +676,8 @@ class FieldAttributeBase:
|
|
654
676
|
setattr(self, attr, obj)
|
655
677
|
else:
|
656
678
|
setattr(self, attr, value)
|
679
|
+
else:
|
680
|
+
setattr(self, attr, value) # overridden dump_attrs in derived types may dump attributes which are not field attributes
|
657
681
|
|
658
682
|
# from_attrs is only used to create a finalized task
|
659
683
|
# from attrs from the Worker/TaskExecutor
|
@@ -663,13 +687,13 @@ class FieldAttributeBase:
|
|
663
687
|
self._squashed = True
|
664
688
|
|
665
689
|
def serialize(self):
|
666
|
-
|
690
|
+
"""
|
667
691
|
Serializes the object derived from the base object into
|
668
692
|
a dictionary of values. This only serializes the field
|
669
693
|
attributes for the object, so this may need to be overridden
|
670
694
|
for any classes which wish to add additional items not stored
|
671
695
|
as field attributes.
|
672
|
-
|
696
|
+
"""
|
673
697
|
|
674
698
|
repr = self.dump_attrs()
|
675
699
|
|
@@ -681,12 +705,12 @@ class FieldAttributeBase:
|
|
681
705
|
return repr
|
682
706
|
|
683
707
|
def deserialize(self, data):
|
684
|
-
|
708
|
+
"""
|
685
709
|
Given a dictionary of values, load up the field attributes for
|
686
710
|
this object. As with serialize(), if there are any non-field
|
687
711
|
attribute data members, this method will need to be overridden
|
688
712
|
and extended.
|
689
|
-
|
713
|
+
"""
|
690
714
|
|
691
715
|
if not isinstance(data, dict):
|
692
716
|
raise AnsibleAssertionError('data (%s) should be a dict but is a %s' % (data, type(data)))
|
@@ -713,7 +737,7 @@ class Base(FieldAttributeBase):
|
|
713
737
|
remote_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('remote_user'))
|
714
738
|
|
715
739
|
# variables
|
716
|
-
vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True)
|
740
|
+
vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True, default=dict)
|
717
741
|
|
718
742
|
# module default params
|
719
743
|
module_defaults = FieldAttribute(isa='list', extend=True, prepend=True)
|
@@ -743,17 +767,43 @@ class Base(FieldAttributeBase):
|
|
743
767
|
# used to hold sudo/su stuff
|
744
768
|
DEPRECATED_ATTRIBUTES = [] # type: list[str]
|
745
769
|
|
746
|
-
def
|
747
|
-
|
770
|
+
def update_result_no_log(self, templar: TemplateEngine, result: dict[str, t.Any]) -> None:
|
771
|
+
"""Set the post-validated no_log value for the result, falling back to a default on validation/templating failure with a warning."""
|
748
772
|
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
except AttributeError:
|
773
|
+
if self.finalized:
|
774
|
+
no_log = self.no_log
|
775
|
+
else:
|
753
776
|
try:
|
754
|
-
|
777
|
+
no_log = self.post_validate_attribute('no_log', templar=templar)
|
778
|
+
except Exception as ex:
|
779
|
+
display.error_as_warning('Invalid no_log value for task, output will be masked.', exception=ex)
|
780
|
+
no_log = True
|
781
|
+
|
782
|
+
result_no_log = result.get('_ansible_no_log', False)
|
783
|
+
|
784
|
+
if not isinstance(result_no_log, bool):
|
785
|
+
display.warning(f'Invalid _ansible_no_log value of type {type(result_no_log).__name__!r} in task result, output will be masked.')
|
786
|
+
no_log = True
|
787
|
+
|
788
|
+
no_log = no_log or result_no_log
|
789
|
+
|
790
|
+
result.update(_ansible_no_log=no_log)
|
791
|
+
|
792
|
+
def get_path(self) -> str:
|
793
|
+
""" return the absolute path of the playbook object and its line number """
|
794
|
+
origin = self._origin
|
795
|
+
|
796
|
+
if not origin:
|
797
|
+
try:
|
798
|
+
origin = self._parent._play._origin
|
755
799
|
except AttributeError:
|
756
800
|
pass
|
801
|
+
|
802
|
+
if origin and origin.path:
|
803
|
+
path = f"{origin.path}:{origin.line_num or 1}"
|
804
|
+
else:
|
805
|
+
path = ""
|
806
|
+
|
757
807
|
return path
|
758
808
|
|
759
809
|
def get_dep_chain(self):
|
@@ -764,10 +814,10 @@ class Base(FieldAttributeBase):
|
|
764
814
|
return None
|
765
815
|
|
766
816
|
def get_search_path(self):
|
767
|
-
|
817
|
+
"""
|
768
818
|
Return the list of paths you should search for files, in order.
|
769
819
|
This follows role/playbook dependency chain.
|
770
|
-
|
820
|
+
"""
|
771
821
|
path_stack = []
|
772
822
|
|
773
823
|
dep_chain = self.get_dep_chain()
|