ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__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.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz/__init__.py +0 -0
- ansible/_internal/_ansiballz/_builder.py +101 -0
- ansible/_internal/_ansiballz/_wrapper.py +262 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_alarm_timeout.py +66 -0
- ansible/_internal/_errors/_captured.py +123 -0
- ansible/_internal/_errors/_error_factory.py +89 -0
- ansible/_internal/_errors/_error_utils.py +240 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_task_timeout.py +28 -0
- ansible/_internal/_event_formatting.py +127 -0
- ansible/_internal/_json/__init__.py +214 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +189 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_ssh/__init__.py +0 -0
- ansible/_internal/_ssh/_agent_launch.py +91 -0
- ansible/_internal/_ssh/_ssh_agent.py +619 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +12 -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 +592 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1106 -0
- ansible/_internal/_templating/_jinja_common.py +323 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +375 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_template_vars.py +72 -0
- ansible/_internal/_templating/_transform.py +70 -0
- ansible/_internal/_templating/_utils.py +108 -0
- ansible/_internal/_testing.py +26 -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 +70 -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 +27 -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 +93 -104
- ansible/cli/_ssh_askpass.py +54 -0
- ansible/cli/adhoc.py +20 -10
- ansible/cli/arguments/option_helpers.py +163 -10
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +13 -11
- ansible/cli/doc.py +134 -77
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -28
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +6 -3
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/compat/importlib_resources.py +9 -12
- ansible/config/base.yml +218 -133
- ansible/config/manager.py +220 -159
- ansible/constants.py +2 -65
- ansible/errors/__init__.py +350 -256
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +480 -514
- 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 +204 -153
- ansible/executor/powershell/become_wrapper.ps1 +107 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
- ansible/executor/powershell/exec_wrapper.ps1 +675 -196
- ansible/executor/powershell/module_manifest.py +469 -265
- ansible/executor/powershell/module_wrapper.ps1 +195 -186
- ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
- ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
- 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 +139 -149
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +270 -297
- ansible/executor/task_queue_manager.py +135 -137
- ansible/executor/task_result.py +182 -79
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +26 -25
- ansible/galaxy/collection/__init__.py +6 -14
- ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +4 -4
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +6 -10
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +50 -73
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +37 -54
- ansible/inventory/manager.py +79 -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/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
- ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
- ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
- ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +961 -0
- ansible/module_utils/_internal/_datatag/_tags.py +16 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_deprecator.py +157 -0
- ansible/module_utils/_internal/_errors.py +101 -0
- ansible/module_utils/_internal/_event_utils.py +61 -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 +428 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -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 +52 -0
- ansible/module_utils/_internal/_messages.py +130 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -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_info.py +38 -0
- ansible/module_utils/_internal/_stack.py +22 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_text_utils.py +6 -0
- ansible/module_utils/_internal/_traceback.py +92 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +303 -202
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/collections.py +7 -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/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -3
- ansible/module_utils/common/respawn.py +11 -33
- 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 +143 -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 +10 -13
- ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +49 -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 +2 -2
- 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 +5 -5
- 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 +2 -3
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/sysctl.py +4 -6
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +3 -3
- 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 +27 -13
- 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 +2 -3
- 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/linux.py +3 -3
- 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 +7 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/service.py +21 -31
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +64 -35
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +69 -49
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +32 -51
- ansible/modules/assemble.py +16 -14
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +24 -24
- ansible/modules/async_wrapper.py +20 -25
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +13 -20
- ansible/modules/copy.py +60 -147
- ansible/modules/cron.py +24 -21
- 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 +13 -15
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +184 -144
- ansible/modules/find.py +22 -20
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +77 -54
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +38 -38
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +15 -32
- 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 +22 -24
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +10 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +21 -26
- ansible/modules/raw.py +6 -6
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +10 -14
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +10 -17
- 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 +16 -19
- ansible/modules/stat.py +15 -31
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +7 -7
- ansible/modules/systemd_service.py +7 -7
- ansible/modules/sysvinit.py +9 -9
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +38 -17
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +45 -32
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +70 -60
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +10 -9
- ansible/parsing/ajson.py +17 -37
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +62 -60
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +327 -99
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +187 -134
- 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 +32 -26
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +14 -17
- ansible/playbook/playbook_include.py +27 -62
- ansible/playbook/role/__init__.py +64 -49
- 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 +28 -12
- ansible/playbook/task.py +192 -121
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +58 -26
- ansible/plugins/action/__init__.py +188 -186
- ansible/plugins/action/add_host.py +2 -2
- ansible/plugins/action/assemble.py +11 -18
- ansible/plugins/action/assert.py +55 -67
- ansible/plugins/action/async_status.py +7 -2
- ansible/plugins/action/copy.py +14 -17
- 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 +7 -8
- ansible/plugins/action/gather_facts.py +13 -14
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +8 -14
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +27 -38
- ansible/plugins/action/service.py +9 -18
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +47 -67
- ansible/plugins/action/unarchive.py +6 -16
- ansible/plugins/action/uri.py +9 -20
- 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 +52 -63
- 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 +294 -201
- ansible/plugins/callback/default.py +99 -95
- ansible/plugins/callback/junit.py +44 -43
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +34 -21
- ansible/plugins/callback/tree.py +27 -16
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +156 -60
- ansible/plugins/connection/paramiko_ssh.py +34 -24
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +326 -86
- ansible/plugins/connection/winrm.py +62 -141
- 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 +8 -4
- 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 +245 -120
- ansible/plugins/filter/encryption.py +42 -34
- 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/pow.yml +1 -1
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/strftime.yml +3 -3
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_uuid.yml +1 -1
- 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 +107 -86
- 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 +190 -120
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +72 -19
- ansible/plugins/loader.py +383 -198
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +19 -73
- 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 +87 -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 +47 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +4 -10
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +58 -4
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +106 -31
- ansible/plugins/shell/sh.py +13 -7
- ansible/plugins/strategy/__init__.py +168 -193
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +75 -35
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/finished.yml +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +5 -8
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +353 -943
- ansible/utils/__init__.py +0 -18
- ansible/utils/collection_loader/__init__.py +54 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +82 -96
- ansible/utils/collection_loader/_collection_meta.py +15 -8
- ansible/utils/display.py +485 -73
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/galaxy.py +2 -2
- ansible/utils/hashing.py +8 -10
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +10 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +10 -12
- ansible/utils/plugin_docs.py +16 -14
- ansible/utils/py3compat.py +2 -7
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +6 -2
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +55 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +220 -285
- ansible/vars/plugins.py +4 -4
- ansible/vars/reserved.py +13 -12
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
- ansible_core-2.19.0.dist-info/RECORD +1097 -0
- ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
- 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 +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- 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 +6 -0
- ansible_test/_internal/ansible_util.py +3 -1
- 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 -5
- 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 +52 -5
- 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 +3 -2
- 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 +22 -5
- 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 +3 -2
- 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 +8 -2
- 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 +19 -2
- 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 +12 -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 +25 -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 +44 -4
- ansible_test/_internal/commands/units/__init__.py +5 -1
- 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 +23 -13
- 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/debugging.py +166 -0
- ansible_test/_internal/delegation.py +22 -13
- 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 +260 -16
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +39 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +95 -4
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/processes.py +80 -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 +11 -4
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +28 -0
- ansible_test/_internal/ssh.py +2 -5
- ansible_test/_internal/target.py +9 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +3 -1
- ansible_test/_internal/timeout.py +2 -1
- ansible_test/_internal/util.py +41 -12
- ansible_test/_internal/util_common.py +18 -5
- 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 +8 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- 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/injector/python.py +8 -0
- 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 +38 -36
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.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
|
|
|
@@ -80,6 +83,11 @@ class _ClassProperty:
|
|
|
80
83
|
|
|
81
84
|
class FieldAttributeBase:
|
|
82
85
|
|
|
86
|
+
_post_validate_object = False
|
|
87
|
+
"""
|
|
88
|
+
`False` skips FieldAttribute post-validation on intermediate objects and mixins for attributes without `always_post_validate`.
|
|
89
|
+
Leaf objects (e.g., `Task`) should set this attribute `True` to opt-in to post-validation.
|
|
90
|
+
"""
|
|
83
91
|
fattributes = _ClassProperty()
|
|
84
92
|
|
|
85
93
|
@classmethod
|
|
@@ -96,12 +104,13 @@ class FieldAttributeBase:
|
|
|
96
104
|
fattributes[attr.alias] = attr
|
|
97
105
|
return fattributes
|
|
98
106
|
|
|
99
|
-
def __init__(self):
|
|
107
|
+
def __init__(self) -> None:
|
|
100
108
|
|
|
101
109
|
# initialize the data loader and variable manager, which will be provided
|
|
102
110
|
# later when the object is actually loaded
|
|
103
111
|
self._loader = None
|
|
104
112
|
self._variable_manager = None
|
|
113
|
+
self._origin: Origin | None = None
|
|
105
114
|
|
|
106
115
|
# other internal params
|
|
107
116
|
self._validated = False
|
|
@@ -111,15 +120,12 @@ class FieldAttributeBase:
|
|
|
111
120
|
# every object gets a random uuid:
|
|
112
121
|
self._uuid = get_unique_id()
|
|
113
122
|
|
|
114
|
-
# init vars, avoid using defaults in field declaration as it lives across plays
|
|
115
|
-
self.vars = dict()
|
|
116
|
-
|
|
117
123
|
@property
|
|
118
124
|
def finalized(self):
|
|
119
125
|
return self._finalized
|
|
120
126
|
|
|
121
127
|
def dump_me(self, depth=0):
|
|
122
|
-
|
|
128
|
+
""" this is never called from production code, it is here to be used when debugging as a 'complex print' """
|
|
123
129
|
if depth == 0:
|
|
124
130
|
display.debug("DUMPING OBJECT ------------------------------------------------------")
|
|
125
131
|
display.debug("%s- %s (%s, id=%s)" % (" " * depth, self.__class__.__name__, self, id(self)))
|
|
@@ -133,11 +139,11 @@ class FieldAttributeBase:
|
|
|
133
139
|
self._play.dump_me(depth + 2)
|
|
134
140
|
|
|
135
141
|
def preprocess_data(self, ds):
|
|
136
|
-
|
|
142
|
+
""" infrequently used method to do some pre-processing of legacy terms """
|
|
137
143
|
return ds
|
|
138
144
|
|
|
139
145
|
def load_data(self, ds, variable_manager=None, loader=None):
|
|
140
|
-
|
|
146
|
+
""" walk the input datastructure and assign any values """
|
|
141
147
|
|
|
142
148
|
if ds is None:
|
|
143
149
|
raise AnsibleAssertionError('ds (%s) should not be None but it is.' % ds)
|
|
@@ -148,6 +154,7 @@ class FieldAttributeBase:
|
|
|
148
154
|
# the variable manager class is used to manage and merge variables
|
|
149
155
|
# down to a single dictionary for reference in templating, etc.
|
|
150
156
|
self._variable_manager = variable_manager
|
|
157
|
+
self._origin = Origin.get_tag(ds)
|
|
151
158
|
|
|
152
159
|
# the data loader class is used to parse data from strings and files
|
|
153
160
|
if loader is not None:
|
|
@@ -191,27 +198,29 @@ class FieldAttributeBase:
|
|
|
191
198
|
return self._variable_manager
|
|
192
199
|
|
|
193
200
|
def _post_validate_debugger(self, attr, value, templar):
|
|
194
|
-
|
|
201
|
+
try:
|
|
202
|
+
value = templar.template(value)
|
|
203
|
+
except AnsibleValueOmittedError:
|
|
204
|
+
value = self.set_to_context(attr.name)
|
|
205
|
+
|
|
195
206
|
valid_values = frozenset(('always', 'on_failed', 'on_unreachable', 'on_skipped', 'never'))
|
|
196
207
|
if value and isinstance(value, string_types) and value not in valid_values:
|
|
197
208
|
raise AnsibleParserError("'%s' is not a valid value for debugger. Must be one of %s" % (value, ', '.join(valid_values)), obj=self.get_ds())
|
|
198
209
|
return value
|
|
199
210
|
|
|
200
211
|
def _validate_attributes(self, ds):
|
|
201
|
-
|
|
212
|
+
"""
|
|
202
213
|
Ensures that there are no keys in the datastructure which do
|
|
203
214
|
not map to attributes for this object.
|
|
204
|
-
|
|
215
|
+
"""
|
|
205
216
|
|
|
206
217
|
valid_attrs = frozenset(self.fattributes)
|
|
207
218
|
for key in ds:
|
|
208
219
|
if key not in valid_attrs:
|
|
209
|
-
raise AnsibleParserError("'%s' is not a valid attribute for a %s" % (key, self.__class__.__name__), obj=
|
|
220
|
+
raise AnsibleParserError("'%s' is not a valid attribute for a %s" % (key, self.__class__.__name__), obj=key)
|
|
210
221
|
|
|
211
222
|
def validate(self, all_vars=None):
|
|
212
|
-
|
|
213
|
-
all_vars = {} if all_vars is None else all_vars
|
|
214
|
-
|
|
223
|
+
""" validation that is done at parse time, not load time """
|
|
215
224
|
if not self._validated:
|
|
216
225
|
# walk all fields in the object
|
|
217
226
|
for (name, attribute) in self.fattributes.items():
|
|
@@ -244,7 +253,8 @@ class FieldAttributeBase:
|
|
|
244
253
|
raise AnsibleParserError(
|
|
245
254
|
"The field 'module_defaults' is supposed to be a dictionary or list of dictionaries, "
|
|
246
255
|
"the keys of which must be static action, module, or group names. Only the values may contain "
|
|
247
|
-
"templates. For example: {'ping': \"{{ ping_defaults }}\"}"
|
|
256
|
+
"templates. For example: {'ping': \"{{ ping_defaults }}\"}",
|
|
257
|
+
obj=defaults_dict,
|
|
248
258
|
)
|
|
249
259
|
|
|
250
260
|
validated_defaults_dict = {}
|
|
@@ -402,31 +412,32 @@ class FieldAttributeBase:
|
|
|
402
412
|
display.vvvvv("Could not resolve action %s in module_defaults" % action_name)
|
|
403
413
|
|
|
404
414
|
def squash(self):
|
|
405
|
-
|
|
415
|
+
"""
|
|
406
416
|
Evaluates all attributes and sets them to the evaluated version,
|
|
407
417
|
so that all future accesses of attributes do not need to evaluate
|
|
408
418
|
parent attributes.
|
|
409
|
-
|
|
419
|
+
"""
|
|
410
420
|
if not self._squashed:
|
|
411
421
|
for name in self.fattributes:
|
|
412
422
|
setattr(self, name, getattr(self, name))
|
|
413
423
|
self._squashed = True
|
|
414
424
|
|
|
415
425
|
def copy(self):
|
|
416
|
-
|
|
426
|
+
"""
|
|
417
427
|
Create a copy of this object and return it.
|
|
418
|
-
|
|
428
|
+
"""
|
|
419
429
|
|
|
420
430
|
try:
|
|
421
431
|
new_me = self.__class__()
|
|
422
|
-
except
|
|
423
|
-
raise AnsibleError("Exceeded maximum object depth. This may have been caused by excessive role recursion"
|
|
432
|
+
except RecursionError as ex:
|
|
433
|
+
raise AnsibleError("Exceeded maximum object depth. This may have been caused by excessive role recursion.") from ex
|
|
424
434
|
|
|
425
435
|
for name in self.fattributes:
|
|
426
436
|
setattr(new_me, name, shallowcopy(getattr(self, f'_{name}', Sentinel)))
|
|
427
437
|
|
|
428
438
|
new_me._loader = self._loader
|
|
429
439
|
new_me._variable_manager = self._variable_manager
|
|
440
|
+
new_me._origin = self._origin
|
|
430
441
|
new_me._validated = self._validated
|
|
431
442
|
new_me._finalized = self._finalized
|
|
432
443
|
new_me._uuid = self._uuid
|
|
@@ -438,6 +449,12 @@ class FieldAttributeBase:
|
|
|
438
449
|
return new_me
|
|
439
450
|
|
|
440
451
|
def get_validated_value(self, name, attribute, value, templar):
|
|
452
|
+
try:
|
|
453
|
+
return self._get_validated_value(name, attribute, value, templar)
|
|
454
|
+
except (TypeError, ValueError):
|
|
455
|
+
raise AnsibleError(f"The value {value!r} could not be converted to {attribute.isa!r}.", obj=value)
|
|
456
|
+
|
|
457
|
+
def _get_validated_value(self, name, attribute, value, templar):
|
|
441
458
|
if attribute.isa == 'string':
|
|
442
459
|
value = to_text(value)
|
|
443
460
|
elif attribute.isa == 'int':
|
|
@@ -466,28 +483,23 @@ class FieldAttributeBase:
|
|
|
466
483
|
if attribute.listof is not None:
|
|
467
484
|
for item in value:
|
|
468
485
|
if not isinstance(item, attribute.listof):
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
486
|
+
type_names = ' or '.join(f'{native_type_name(attribute_type)!r}' for attribute_type in attribute.listof)
|
|
487
|
+
|
|
488
|
+
raise AnsibleParserError(
|
|
489
|
+
message=f"Keyword {name!r} items must be of type {type_names}, not {native_type_name(item)!r}.",
|
|
490
|
+
obj=Origin.first_tagged_on(item, value, self.get_ds()),
|
|
491
|
+
)
|
|
492
|
+
elif attribute.required and attribute.listof == (str,):
|
|
472
493
|
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)
|
|
494
|
+
raise AnsibleParserError(
|
|
495
|
+
message=f"Keyword {name!r} is required, and cannot have empty values.",
|
|
496
|
+
obj=Origin.first_tagged_on(item, value, self.get_ds()),
|
|
497
|
+
)
|
|
486
498
|
elif attribute.isa == 'dict':
|
|
487
499
|
if value is None:
|
|
488
500
|
value = dict()
|
|
489
501
|
elif not isinstance(value, dict):
|
|
490
|
-
raise
|
|
502
|
+
raise AnsibleError(f"{value!r} is not a dictionary")
|
|
491
503
|
elif attribute.isa == 'class':
|
|
492
504
|
if not isinstance(value, attribute.class_type):
|
|
493
505
|
raise TypeError("%s is not a valid %s (got a %s instead)" % (name, attribute.class_type, type(value)))
|
|
@@ -496,119 +508,132 @@ class FieldAttributeBase:
|
|
|
496
508
|
raise AnsibleAssertionError(f"Unknown value for attribute.isa: {attribute.isa}")
|
|
497
509
|
return value
|
|
498
510
|
|
|
499
|
-
def set_to_context(self, name):
|
|
500
|
-
|
|
511
|
+
def set_to_context(self, name: str) -> t.Any:
|
|
512
|
+
""" set to parent inherited value or Sentinel as appropriate"""
|
|
501
513
|
|
|
502
514
|
attribute = self.fattributes[name]
|
|
503
515
|
if isinstance(attribute, NonInheritableFieldAttribute):
|
|
504
516
|
# setting to sentinel will trigger 'default/default()' on getter
|
|
505
|
-
|
|
517
|
+
value = Sentinel
|
|
506
518
|
else:
|
|
507
519
|
try:
|
|
508
|
-
|
|
520
|
+
value = self._get_parent_attribute(name, omit=True)
|
|
509
521
|
except AttributeError:
|
|
510
522
|
# mostly playcontext as only tasks/handlers/blocks really resolve parent
|
|
511
|
-
|
|
523
|
+
value = Sentinel
|
|
524
|
+
|
|
525
|
+
setattr(self, name, value)
|
|
526
|
+
return value
|
|
512
527
|
|
|
513
528
|
def post_validate(self, templar):
|
|
514
|
-
|
|
529
|
+
"""
|
|
515
530
|
we can't tell that everything is of the right type until we have
|
|
516
531
|
all the variables. Run basic types (from isa) as well as
|
|
517
532
|
any _post_validate_<foo> functions.
|
|
518
|
-
|
|
533
|
+
"""
|
|
519
534
|
|
|
520
|
-
|
|
521
|
-
|
|
535
|
+
for name in self.fattributes:
|
|
536
|
+
value = self.post_validate_attribute(name, templar=templar)
|
|
522
537
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
538
|
+
if value is not Sentinel:
|
|
539
|
+
# and assign the massaged value back to the attribute field
|
|
540
|
+
setattr(self, name, value)
|
|
526
541
|
|
|
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
|
|
542
|
+
self._finalized = True
|
|
532
543
|
|
|
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
|
|
544
|
+
def post_validate_attribute(self, name: str, *, templar: TemplateEngine):
|
|
545
|
+
attribute: FieldAttribute = self.fattributes[name]
|
|
543
546
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
547
|
+
# DTFIX-FUTURE: this can probably be used in many getattr cases below, but the value may be out-of-date in some cases
|
|
548
|
+
original_value = getattr(self, name) # we save this original (likely Origin-tagged) value to pass as `obj` for errors
|
|
549
|
+
|
|
550
|
+
if attribute.static:
|
|
551
|
+
value = getattr(self, name)
|
|
552
|
+
|
|
553
|
+
# we don't template 'vars' but allow template as values for later use
|
|
554
|
+
if name not in ('vars',) and templar.is_template(value):
|
|
555
|
+
display.warning('"%s" is not templatable, but we found: %s, '
|
|
556
|
+
'it will not be templated and will be used "as is".' % (name, value))
|
|
557
|
+
return Sentinel
|
|
558
|
+
|
|
559
|
+
if getattr(self, name) is None:
|
|
560
|
+
if not attribute.required:
|
|
561
|
+
return Sentinel
|
|
562
|
+
|
|
563
|
+
raise AnsibleFieldAttributeError(f'The field {name!r} is required but was not set.', obj=self.get_ds())
|
|
564
|
+
|
|
565
|
+
from .role_include import IncludeRole
|
|
566
|
+
|
|
567
|
+
if not attribute.always_post_validate and isinstance(self, IncludeRole) and self.statically_loaded: # import_role
|
|
568
|
+
# normal field attributes should not go through post validation on import_role/import_tasks
|
|
569
|
+
# only import_role is checked here because import_tasks never reaches this point
|
|
570
|
+
return Sentinel
|
|
571
|
+
|
|
572
|
+
# Skip post validation unless always_post_validate is True, or the object requires post validation.
|
|
573
|
+
if not attribute.always_post_validate and not self._post_validate_object:
|
|
574
|
+
# Intermediate objects like Play() won't have their fields validated by
|
|
575
|
+
# default, as their values are often inherited by other objects and validated
|
|
576
|
+
# later, so we don't want them to fail out early
|
|
577
|
+
return Sentinel
|
|
578
|
+
|
|
579
|
+
try:
|
|
580
|
+
# Run the post-validator if present. These methods are responsible for
|
|
581
|
+
# using the given templar to template the values, if required.
|
|
582
|
+
method = getattr(self, '_post_validate_%s' % name, None)
|
|
583
|
+
|
|
584
|
+
if method:
|
|
585
|
+
value = method(attribute, getattr(self, name), templar)
|
|
586
|
+
elif attribute.isa == 'class':
|
|
587
|
+
value = getattr(self, name)
|
|
588
|
+
else:
|
|
589
|
+
try:
|
|
553
590
|
# if the attribute contains a variable, template it now
|
|
554
591
|
value = templar.template(getattr(self, name))
|
|
592
|
+
except AnsibleValueOmittedError:
|
|
593
|
+
# If this evaluated to the omit value, set the value back to inherited by context
|
|
594
|
+
# or default specified in the FieldAttribute and move on
|
|
595
|
+
value = self.set_to_context(name)
|
|
555
596
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
if omit_value is not None and value == omit_value:
|
|
559
|
-
self.set_to_context(name)
|
|
560
|
-
continue
|
|
597
|
+
if value is Sentinel:
|
|
598
|
+
return value
|
|
561
599
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
600
|
+
# and make sure the attribute is of the type it should be
|
|
601
|
+
if value is not None:
|
|
602
|
+
value = self.get_validated_value(name, attribute, value, templar)
|
|
565
603
|
|
|
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)
|
|
604
|
+
# returning the value results in assigning the massaged value back to the attribute field
|
|
605
|
+
return value
|
|
606
|
+
except Exception as ex:
|
|
607
|
+
if name == 'args':
|
|
608
|
+
raise # no useful information to contribute, raise the original exception
|
|
579
609
|
|
|
580
|
-
|
|
610
|
+
raise AnsibleFieldAttributeError(f'Error processing keyword {name!r}.', obj=original_value) from ex
|
|
581
611
|
|
|
582
612
|
def _load_vars(self, attr, ds):
|
|
583
|
-
|
|
613
|
+
"""
|
|
584
614
|
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)
|
|
615
|
+
"""
|
|
591
616
|
|
|
592
617
|
try:
|
|
593
618
|
if isinstance(ds, dict):
|
|
594
|
-
|
|
619
|
+
for key in ds:
|
|
620
|
+
validate_variable_name(key)
|
|
595
621
|
return combine_vars(self.vars, ds)
|
|
596
622
|
elif ds is None:
|
|
597
623
|
return {}
|
|
598
624
|
else:
|
|
599
625
|
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)
|
|
626
|
+
except ValueError as ex:
|
|
627
|
+
raise AnsibleParserError(f"Vars in a {self.__class__.__name__} must be specified as a dictionary.", obj=ds) from ex
|
|
628
|
+
except TypeError as ex:
|
|
629
|
+
raise AnsibleParserError(f"Invalid variable name in vars specified for {self.__class__.__name__}.", obj=ds) from ex
|
|
605
630
|
|
|
606
631
|
def _extend_value(self, value, new_value, prepend=False):
|
|
607
|
-
|
|
632
|
+
"""
|
|
608
633
|
Will extend the value given with new_value (and will turn both
|
|
609
634
|
into lists if they are not so already). The values are run through
|
|
610
635
|
a set to remove duplicate values.
|
|
611
|
-
|
|
636
|
+
"""
|
|
612
637
|
|
|
613
638
|
if not isinstance(value, list):
|
|
614
639
|
value = [value]
|
|
@@ -629,9 +654,9 @@ class FieldAttributeBase:
|
|
|
629
654
|
return [i for i, dummy in itertools.groupby(combined) if i is not None]
|
|
630
655
|
|
|
631
656
|
def dump_attrs(self):
|
|
632
|
-
|
|
657
|
+
"""
|
|
633
658
|
Dumps all attributes to a dictionary
|
|
634
|
-
|
|
659
|
+
"""
|
|
635
660
|
attrs = {}
|
|
636
661
|
for (name, attribute) in self.fattributes.items():
|
|
637
662
|
attr = getattr(self, name)
|
|
@@ -642,9 +667,9 @@ class FieldAttributeBase:
|
|
|
642
667
|
return attrs
|
|
643
668
|
|
|
644
669
|
def from_attrs(self, attrs):
|
|
645
|
-
|
|
670
|
+
"""
|
|
646
671
|
Loads attributes from a dictionary
|
|
647
|
-
|
|
672
|
+
"""
|
|
648
673
|
for (attr, value) in attrs.items():
|
|
649
674
|
if attr in self.fattributes:
|
|
650
675
|
attribute = self.fattributes[attr]
|
|
@@ -654,6 +679,8 @@ class FieldAttributeBase:
|
|
|
654
679
|
setattr(self, attr, obj)
|
|
655
680
|
else:
|
|
656
681
|
setattr(self, attr, value)
|
|
682
|
+
else:
|
|
683
|
+
setattr(self, attr, value) # overridden dump_attrs in derived types may dump attributes which are not field attributes
|
|
657
684
|
|
|
658
685
|
# from_attrs is only used to create a finalized task
|
|
659
686
|
# from attrs from the Worker/TaskExecutor
|
|
@@ -663,13 +690,13 @@ class FieldAttributeBase:
|
|
|
663
690
|
self._squashed = True
|
|
664
691
|
|
|
665
692
|
def serialize(self):
|
|
666
|
-
|
|
693
|
+
"""
|
|
667
694
|
Serializes the object derived from the base object into
|
|
668
695
|
a dictionary of values. This only serializes the field
|
|
669
696
|
attributes for the object, so this may need to be overridden
|
|
670
697
|
for any classes which wish to add additional items not stored
|
|
671
698
|
as field attributes.
|
|
672
|
-
|
|
699
|
+
"""
|
|
673
700
|
|
|
674
701
|
repr = self.dump_attrs()
|
|
675
702
|
|
|
@@ -681,12 +708,12 @@ class FieldAttributeBase:
|
|
|
681
708
|
return repr
|
|
682
709
|
|
|
683
710
|
def deserialize(self, data):
|
|
684
|
-
|
|
711
|
+
"""
|
|
685
712
|
Given a dictionary of values, load up the field attributes for
|
|
686
713
|
this object. As with serialize(), if there are any non-field
|
|
687
714
|
attribute data members, this method will need to be overridden
|
|
688
715
|
and extended.
|
|
689
|
-
|
|
716
|
+
"""
|
|
690
717
|
|
|
691
718
|
if not isinstance(data, dict):
|
|
692
719
|
raise AnsibleAssertionError('data (%s) should be a dict but is a %s' % (data, type(data)))
|
|
@@ -713,7 +740,7 @@ class Base(FieldAttributeBase):
|
|
|
713
740
|
remote_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('remote_user'))
|
|
714
741
|
|
|
715
742
|
# variables
|
|
716
|
-
vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True)
|
|
743
|
+
vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True, default=dict)
|
|
717
744
|
|
|
718
745
|
# module default params
|
|
719
746
|
module_defaults = FieldAttribute(isa='list', extend=True, prepend=True)
|
|
@@ -743,17 +770,43 @@ class Base(FieldAttributeBase):
|
|
|
743
770
|
# used to hold sudo/su stuff
|
|
744
771
|
DEPRECATED_ATTRIBUTES = [] # type: list[str]
|
|
745
772
|
|
|
746
|
-
def
|
|
747
|
-
|
|
773
|
+
def update_result_no_log(self, templar: TemplateEngine, result: dict[str, t.Any]) -> None:
|
|
774
|
+
"""Set the post-validated no_log value for the result, falling back to a default on validation/templating failure with a warning."""
|
|
748
775
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
except AttributeError:
|
|
776
|
+
if self.finalized:
|
|
777
|
+
no_log = self.no_log
|
|
778
|
+
else:
|
|
753
779
|
try:
|
|
754
|
-
|
|
780
|
+
no_log = self.post_validate_attribute('no_log', templar=templar)
|
|
781
|
+
except Exception as ex:
|
|
782
|
+
display.error_as_warning('Invalid no_log value for task, output will be masked.', exception=ex)
|
|
783
|
+
no_log = True
|
|
784
|
+
|
|
785
|
+
result_no_log = result.get('_ansible_no_log', False)
|
|
786
|
+
|
|
787
|
+
if not isinstance(result_no_log, bool):
|
|
788
|
+
display.warning(f'Invalid _ansible_no_log value of type {type(result_no_log).__name__!r} in task result, output will be masked.')
|
|
789
|
+
no_log = True
|
|
790
|
+
|
|
791
|
+
no_log = no_log or result_no_log
|
|
792
|
+
|
|
793
|
+
result.update(_ansible_no_log=no_log)
|
|
794
|
+
|
|
795
|
+
def get_path(self) -> str:
|
|
796
|
+
""" return the absolute path of the playbook object and its line number """
|
|
797
|
+
origin = self._origin
|
|
798
|
+
|
|
799
|
+
if not origin:
|
|
800
|
+
try:
|
|
801
|
+
origin = self._parent._play._origin
|
|
755
802
|
except AttributeError:
|
|
756
803
|
pass
|
|
804
|
+
|
|
805
|
+
if origin and origin.path:
|
|
806
|
+
path = f"{origin.path}:{origin.line_num or 1}"
|
|
807
|
+
else:
|
|
808
|
+
path = ""
|
|
809
|
+
|
|
757
810
|
return path
|
|
758
811
|
|
|
759
812
|
def get_dep_chain(self):
|
|
@@ -764,10 +817,10 @@ class Base(FieldAttributeBase):
|
|
|
764
817
|
return None
|
|
765
818
|
|
|
766
819
|
def get_search_path(self):
|
|
767
|
-
|
|
820
|
+
"""
|
|
768
821
|
Return the list of paths you should search for files, in order.
|
|
769
822
|
This follows role/playbook dependency chain.
|
|
770
|
-
|
|
823
|
+
"""
|
|
771
824
|
path_stack = []
|
|
772
825
|
|
|
773
826
|
dep_chain = self.get_dep_chain()
|