ansible-core 2.18.7__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.7.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.7.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import ast
|
|
4
|
+
|
|
5
|
+
from ansible.errors import AnsibleTypeError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def python_literal_eval(value: object, ignore_errors=False) -> object:
|
|
9
|
+
try:
|
|
10
|
+
if isinstance(value, str):
|
|
11
|
+
return ast.literal_eval(value)
|
|
12
|
+
|
|
13
|
+
raise AnsibleTypeError("The `value` to eval must be a string.", obj=value)
|
|
14
|
+
except Exception:
|
|
15
|
+
if ignore_errors:
|
|
16
|
+
return value
|
|
17
|
+
|
|
18
|
+
raise
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class FilterModule(object):
|
|
22
|
+
@staticmethod
|
|
23
|
+
def filters():
|
|
24
|
+
return dict(python_literal_eval=python_literal_eval)
|
ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
DOCUMENTATION:
|
|
2
|
+
name: python_literal_eval
|
|
3
|
+
version_added: "2.19"
|
|
4
|
+
short_description: evaluate a Python literal expression string
|
|
5
|
+
description:
|
|
6
|
+
- Evaluates the input string as a Python literal expression, returning the resulting data structure.
|
|
7
|
+
- Previous versions of Ansible applied this behavior to all template results in non-native Jinja mode.
|
|
8
|
+
- This filter provides a way to emulate the previous behavior.
|
|
9
|
+
notes:
|
|
10
|
+
- Directly calls Python's C(ast.literal_eval).
|
|
11
|
+
positional: _input
|
|
12
|
+
options:
|
|
13
|
+
_input:
|
|
14
|
+
description: Python literal string expression.
|
|
15
|
+
type: str
|
|
16
|
+
required: true
|
|
17
|
+
ignore_errors:
|
|
18
|
+
description: Whether to silently ignore all errors resulting from the literal_eval operation. If true, the input is silently returned unmodified when an error occurs.
|
|
19
|
+
type: bool
|
|
20
|
+
default: false
|
|
21
|
+
|
|
22
|
+
EXAMPLES: |
|
|
23
|
+
- name: evaluate an expression comprised only of Python literals
|
|
24
|
+
assert:
|
|
25
|
+
that: (another_var | ansible._protomatter.python_literal_eval)[1] == 2 # in 2.19 and later, the explicit python_literal_eval emulates the old templating behavior
|
|
26
|
+
vars:
|
|
27
|
+
another_var: "{{ some_var }}" # in 2.18 and earlier, indirection through templating caused implicit literal_eval, converting the value to a list
|
|
28
|
+
some_var: "[1, 2]" # a value that looks like a Python list literal embedded in a string
|
|
29
|
+
|
|
30
|
+
RETURN:
|
|
31
|
+
_value:
|
|
32
|
+
description: Resulting data structure.
|
|
33
|
+
type: raw
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ansible.module_utils._internal._datatag import AnsibleTagHelper
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def tag_names(value: object) -> list[str]:
|
|
9
|
+
"""Return a list of tag type names (if any) present on the given object."""
|
|
10
|
+
return sorted(tag_type.__name__ for tag_type in AnsibleTagHelper.tag_types(value))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FilterModule:
|
|
14
|
+
@staticmethod
|
|
15
|
+
def filters() -> dict[str, t.Callable]:
|
|
16
|
+
return dict(tag_names=tag_names)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ansible.template import accept_args_markers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@accept_args_markers
|
|
9
|
+
def true_type(obj: object) -> str:
|
|
10
|
+
"""Internal filter to show the true type name of the given object, not just the base type name like the `debug` filter."""
|
|
11
|
+
return obj.__class__.__name__
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FilterModule(object):
|
|
15
|
+
@staticmethod
|
|
16
|
+
def filters() -> dict[str, t.Callable]:
|
|
17
|
+
return dict(true_type=true_type)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import copy
|
|
4
|
+
import dataclasses
|
|
5
|
+
import typing as t
|
|
6
|
+
|
|
7
|
+
from ansible._internal._templating._jinja_common import validate_arg_type
|
|
8
|
+
from ansible._internal._templating._lazy_containers import _AnsibleLazyTemplateMixin
|
|
9
|
+
from ansible._internal._templating._transform import _type_transform_mapping
|
|
10
|
+
from ansible.errors import AnsibleError
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def unmask(value: object, type_names: str | list[str]) -> object:
|
|
14
|
+
"""
|
|
15
|
+
Internal filter to suppress automatic type transformation in Jinja (e.g., WarningSummary, DeprecationSummary, ErrorSummary).
|
|
16
|
+
Lazy collection caching is in play - the first attempt to access a value in a given lazy container must be with unmasking in place, or the transformed value
|
|
17
|
+
will already be cached.
|
|
18
|
+
"""
|
|
19
|
+
validate_arg_type("type_names", type_names, (str, list))
|
|
20
|
+
|
|
21
|
+
if isinstance(type_names, str):
|
|
22
|
+
check_type_names = [type_names]
|
|
23
|
+
else:
|
|
24
|
+
check_type_names = type_names
|
|
25
|
+
|
|
26
|
+
valid_type_names = {key.__name__ for key in _type_transform_mapping}
|
|
27
|
+
invalid_type_names = [type_name for type_name in check_type_names if type_name not in valid_type_names]
|
|
28
|
+
|
|
29
|
+
if invalid_type_names:
|
|
30
|
+
raise AnsibleError(f'Unknown type name(s): {", ".join(invalid_type_names)}', obj=type_names)
|
|
31
|
+
|
|
32
|
+
result: object
|
|
33
|
+
|
|
34
|
+
if isinstance(value, _AnsibleLazyTemplateMixin):
|
|
35
|
+
result = copy.copy(value)
|
|
36
|
+
result._lazy_options = dataclasses.replace(
|
|
37
|
+
result._lazy_options,
|
|
38
|
+
unmask_type_names=result._lazy_options.unmask_type_names | frozenset(check_type_names),
|
|
39
|
+
)
|
|
40
|
+
else:
|
|
41
|
+
result = value
|
|
42
|
+
|
|
43
|
+
return result
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class FilterModule(object):
|
|
47
|
+
@staticmethod
|
|
48
|
+
def filters() -> dict[str, t.Callable]:
|
|
49
|
+
return dict(unmask=unmask)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ansible.plugins.lookup import LookupBase
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LookupModule(LookupBase):
|
|
7
|
+
"""Specialized config lookup that applies data transformations on values that config cannot."""
|
|
8
|
+
|
|
9
|
+
def run(self, terms, variables=None, **kwargs):
|
|
10
|
+
if not terms or not (config_name := terms[0]):
|
|
11
|
+
raise ValueError("config name is required")
|
|
12
|
+
|
|
13
|
+
match config_name:
|
|
14
|
+
case 'DISPLAY_TRACEBACK':
|
|
15
|
+
# since config can't expand this yet, we need the post-processed version
|
|
16
|
+
from ansible.module_utils._internal._traceback import traceback_for
|
|
17
|
+
|
|
18
|
+
return traceback_for()
|
|
19
|
+
# DTFIX-FUTURE: plumb through normal config fallback
|
|
20
|
+
case _:
|
|
21
|
+
raise ValueError(f"Unknown config name {config_name!r}.")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ansible.module_utils._internal import _datatag
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def tagged(value: t.Any) -> bool:
|
|
9
|
+
return bool(_datatag.AnsibleTagHelper.tag_types(value))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestModule:
|
|
13
|
+
@staticmethod
|
|
14
|
+
def tests() -> dict[str, t.Callable]:
|
|
15
|
+
return dict(tagged=tagged)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
DOCUMENTATION:
|
|
2
|
+
name: tagged
|
|
3
|
+
author: Ansible Core
|
|
4
|
+
version_added: "2.19"
|
|
5
|
+
short_description: does the value have a data tag
|
|
6
|
+
description:
|
|
7
|
+
- Check if the provided value has a data tag.
|
|
8
|
+
options:
|
|
9
|
+
_input:
|
|
10
|
+
description: A value.
|
|
11
|
+
type: raw
|
|
12
|
+
|
|
13
|
+
EXAMPLES: |
|
|
14
|
+
is_data_tagged: "{{ my_variable is ansible._protomatter.tagged }}"
|
|
15
|
+
|
|
16
|
+
RETURN:
|
|
17
|
+
_value:
|
|
18
|
+
description: Returns C(True) if the value has one or more data tags, otherwise C(False).
|
|
19
|
+
type: boolean
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ansible.module_utils._internal import _datatag
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def tagged_with(value: t.Any, tag_name: str) -> bool:
|
|
9
|
+
if tag_type := _datatag._known_tag_type_map.get(tag_name):
|
|
10
|
+
return tag_type.is_tagged_on(value)
|
|
11
|
+
|
|
12
|
+
raise ValueError(f"Unknown tag name {tag_name!r}.")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestModule:
|
|
16
|
+
@staticmethod
|
|
17
|
+
def tests() -> dict[str, t.Callable]:
|
|
18
|
+
return dict(tagged_with=tagged_with)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
DOCUMENTATION:
|
|
2
|
+
name: tagged_with
|
|
3
|
+
author: Ansible Core
|
|
4
|
+
version_added: "2.19"
|
|
5
|
+
short_description: does the value have the specified data tag
|
|
6
|
+
description:
|
|
7
|
+
- Check if the provided value has the specified data tag.
|
|
8
|
+
options:
|
|
9
|
+
_input:
|
|
10
|
+
description: A value.
|
|
11
|
+
type: raw
|
|
12
|
+
|
|
13
|
+
EXAMPLES: |
|
|
14
|
+
is_data_tagged: "{{ my_variable is ansible._protomatter.tagged_with('Origin') }}"
|
|
15
|
+
|
|
16
|
+
RETURN:
|
|
17
|
+
_value:
|
|
18
|
+
description: Returns C(True) if the value has the specified data tag, otherwise C(False).
|
|
19
|
+
type: boolean
|
ansible/cli/__init__.py
CHANGED
|
@@ -9,6 +9,18 @@ import locale
|
|
|
9
9
|
import os
|
|
10
10
|
import sys
|
|
11
11
|
|
|
12
|
+
# We overload the ``ansible`` adhoc command to provide the functionality for
|
|
13
|
+
# ``SSH_ASKPASS``. This code is here, and not in ``adhoc.py`` to bypass
|
|
14
|
+
# unnecessary code. The program provided to ``SSH_ASKPASS`` can only be invoked
|
|
15
|
+
# as a singular command, ``python -m`` doesn't work for that use case, and we
|
|
16
|
+
# aren't adding a new entrypoint at this time. Assume that if we are executing
|
|
17
|
+
# and there is only a single item in argv plus the executable, and the env var
|
|
18
|
+
# is set we are in ``SSH_ASKPASS`` mode
|
|
19
|
+
if 1 <= len(sys.argv) <= 2 and os.path.basename(sys.argv[0]) == "ansible" and os.getenv('_ANSIBLE_SSH_ASKPASS_SHM'):
|
|
20
|
+
from ansible.cli import _ssh_askpass
|
|
21
|
+
_ssh_askpass.main()
|
|
22
|
+
|
|
23
|
+
|
|
12
24
|
# Used for determining if the system is running a new enough python version
|
|
13
25
|
# and should only restrict on our documented minimum versions
|
|
14
26
|
if sys.version_info < (3, 11):
|
|
@@ -63,50 +75,51 @@ def initialize_locale():
|
|
|
63
75
|
initialize_locale()
|
|
64
76
|
|
|
65
77
|
|
|
66
|
-
from importlib.metadata import version
|
|
67
|
-
from ansible.module_utils.compat.version import LooseVersion
|
|
68
|
-
|
|
69
|
-
# Used for determining if the system is running a new enough Jinja2 version
|
|
70
|
-
# and should only restrict on our documented minimum versions
|
|
71
|
-
jinja2_version = version('jinja2')
|
|
72
|
-
if jinja2_version < LooseVersion('3.0'):
|
|
73
|
-
raise SystemExit(
|
|
74
|
-
'ERROR: Ansible requires Jinja2 3.0 or newer on the controller. '
|
|
75
|
-
'Current version: %s' % jinja2_version
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
import errno
|
|
79
78
|
import getpass
|
|
80
79
|
import subprocess
|
|
81
80
|
import traceback
|
|
82
81
|
from abc import ABC, abstractmethod
|
|
83
82
|
from pathlib import Path
|
|
84
83
|
|
|
84
|
+
from ansible import _internal # do not remove or defer; ensures controller-specific state is set early
|
|
85
|
+
|
|
86
|
+
_internal.setup()
|
|
87
|
+
|
|
88
|
+
from ansible.errors import AnsibleError, ExitCode
|
|
89
|
+
|
|
85
90
|
try:
|
|
86
91
|
from ansible import constants as C
|
|
87
92
|
from ansible.utils.display import Display
|
|
88
93
|
display = Display()
|
|
89
|
-
except Exception as
|
|
90
|
-
|
|
94
|
+
except Exception as ex:
|
|
95
|
+
if isinstance(ex, AnsibleError):
|
|
96
|
+
ex_msg = ' '.join((ex.message, ex._help_text or '')).strip()
|
|
97
|
+
else:
|
|
98
|
+
ex_msg = str(ex)
|
|
99
|
+
|
|
100
|
+
print(f'ERROR: {ex_msg}\n\n{"".join(traceback.format_exception(ex))}', file=sys.stderr)
|
|
91
101
|
sys.exit(5)
|
|
92
102
|
|
|
103
|
+
|
|
93
104
|
from ansible import context
|
|
105
|
+
from ansible.utils import display as _display
|
|
94
106
|
from ansible.cli.arguments import option_helpers as opt_help
|
|
95
|
-
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
|
|
96
107
|
from ansible.inventory.manager import InventoryManager
|
|
97
108
|
from ansible.module_utils.six import string_types
|
|
98
109
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
99
110
|
from ansible.module_utils.common.collections import is_sequence
|
|
100
111
|
from ansible.module_utils.common.file import is_executable
|
|
101
112
|
from ansible.parsing.dataloader import DataLoader
|
|
102
|
-
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret
|
|
113
|
+
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret, VaultSecretsContext
|
|
103
114
|
from ansible.plugins.loader import add_all_plugin_dirs, init_plugin_loader
|
|
104
115
|
from ansible.release import __version__
|
|
105
116
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
|
106
117
|
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path
|
|
107
118
|
from ansible.utils.path import unfrackpath
|
|
108
|
-
from ansible.utils.unsafe_proxy import to_unsafe_text
|
|
109
119
|
from ansible.vars.manager import VariableManager
|
|
120
|
+
from ansible.module_utils._internal import _deprecator
|
|
121
|
+
from ansible._internal._ssh import _agent_launch
|
|
122
|
+
|
|
110
123
|
|
|
111
124
|
try:
|
|
112
125
|
import argcomplete
|
|
@@ -116,7 +129,7 @@ except ImportError:
|
|
|
116
129
|
|
|
117
130
|
|
|
118
131
|
class CLI(ABC):
|
|
119
|
-
|
|
132
|
+
""" code behind bin/ansible* programs """
|
|
120
133
|
|
|
121
134
|
PAGER = C.config.get_config_value('PAGER')
|
|
122
135
|
|
|
@@ -124,6 +137,7 @@ class CLI(ABC):
|
|
|
124
137
|
# -S (chop long lines) -X (disable termcap init and de-init)
|
|
125
138
|
LESS_OPTS = 'FRSX'
|
|
126
139
|
SKIP_INVENTORY_DEFAULTS = False
|
|
140
|
+
USES_CONNECTION = False
|
|
127
141
|
|
|
128
142
|
def __init__(self, args, callback=None):
|
|
129
143
|
"""
|
|
@@ -137,6 +151,9 @@ class CLI(ABC):
|
|
|
137
151
|
self.parser = None
|
|
138
152
|
self.callback = callback
|
|
139
153
|
|
|
154
|
+
self.show_devel_warning()
|
|
155
|
+
|
|
156
|
+
def show_devel_warning(self) -> None:
|
|
140
157
|
if C.DEVEL_WARNING and __version__.endswith('dev0'):
|
|
141
158
|
display.warning(
|
|
142
159
|
'You are running the development version of Ansible. You should only run Ansible from "devel" if '
|
|
@@ -167,7 +184,7 @@ class CLI(ABC):
|
|
|
167
184
|
else:
|
|
168
185
|
display.v(u"No config file found; using defaults")
|
|
169
186
|
|
|
170
|
-
|
|
187
|
+
_display._report_config_warnings(_deprecator.ANSIBLE_CORE_DEPRECATOR)
|
|
171
188
|
|
|
172
189
|
@staticmethod
|
|
173
190
|
def split_vault_id(vault_id):
|
|
@@ -195,9 +212,9 @@ class CLI(ABC):
|
|
|
195
212
|
# used by --vault-id and --vault-password-file
|
|
196
213
|
vault_ids.append(id_slug)
|
|
197
214
|
|
|
198
|
-
# if an action needs an encrypt password (create_new_password=True) and we
|
|
215
|
+
# if an action needs an encrypt password (create_new_password=True) and we don't
|
|
199
216
|
# have other secrets setup, then automatically add a password prompt as well.
|
|
200
|
-
# prompts
|
|
217
|
+
# prompts can't/shouldn't work without a tty, so don't add prompt secrets
|
|
201
218
|
if ask_vault_pass or (not vault_ids and auto_prompt):
|
|
202
219
|
|
|
203
220
|
id_slug = u'%s@%s' % (C.DEFAULT_VAULT_IDENTITY, u'prompt_ask_vault_pass')
|
|
@@ -208,7 +225,7 @@ class CLI(ABC):
|
|
|
208
225
|
@staticmethod
|
|
209
226
|
def setup_vault_secrets(loader, vault_ids, vault_password_files=None,
|
|
210
227
|
ask_vault_pass=None, create_new_password=False,
|
|
211
|
-
auto_prompt=True):
|
|
228
|
+
auto_prompt=True, initialize_context=True):
|
|
212
229
|
# list of tuples
|
|
213
230
|
vault_secrets = []
|
|
214
231
|
|
|
@@ -305,24 +322,22 @@ class CLI(ABC):
|
|
|
305
322
|
if last_exception and not found_vault_secret:
|
|
306
323
|
raise last_exception
|
|
307
324
|
|
|
325
|
+
if initialize_context:
|
|
326
|
+
VaultSecretsContext.initialize(VaultSecretsContext(vault_secrets))
|
|
327
|
+
|
|
308
328
|
return vault_secrets
|
|
309
329
|
|
|
310
330
|
@staticmethod
|
|
311
|
-
def _get_secret(prompt):
|
|
312
|
-
|
|
313
|
-
secret = getpass.getpass(prompt=prompt)
|
|
314
|
-
if secret:
|
|
315
|
-
secret = to_unsafe_text(secret)
|
|
316
|
-
return secret
|
|
331
|
+
def _get_secret(prompt: str) -> str:
|
|
332
|
+
return getpass.getpass(prompt=prompt)
|
|
317
333
|
|
|
318
334
|
@staticmethod
|
|
319
335
|
def ask_passwords():
|
|
320
|
-
|
|
336
|
+
""" prompt for connection and become passwords if needed """
|
|
321
337
|
|
|
322
338
|
op = context.CLIARGS
|
|
323
339
|
sshpass = None
|
|
324
340
|
becomepass = None
|
|
325
|
-
become_prompt = ''
|
|
326
341
|
|
|
327
342
|
become_prompt_method = "BECOME" if C.AGNOSTIC_BECOME_PROMPT else op['become_method'].upper()
|
|
328
343
|
|
|
@@ -344,10 +359,10 @@ class CLI(ABC):
|
|
|
344
359
|
except EOFError:
|
|
345
360
|
pass
|
|
346
361
|
|
|
347
|
-
return
|
|
362
|
+
return sshpass, becomepass
|
|
348
363
|
|
|
349
364
|
def validate_conflicts(self, op, runas_opts=False, fork_opts=False):
|
|
350
|
-
|
|
365
|
+
""" check for conflicting options """
|
|
351
366
|
|
|
352
367
|
if fork_opts:
|
|
353
368
|
if op.forks < 1:
|
|
@@ -459,7 +474,7 @@ class CLI(ABC):
|
|
|
459
474
|
|
|
460
475
|
@staticmethod
|
|
461
476
|
def version_info(gitinfo=False):
|
|
462
|
-
|
|
477
|
+
""" return full ansible version info """
|
|
463
478
|
if gitinfo:
|
|
464
479
|
# expensive call, user with care
|
|
465
480
|
ansible_version_string = opt_help.version()
|
|
@@ -485,7 +500,7 @@ class CLI(ABC):
|
|
|
485
500
|
|
|
486
501
|
@staticmethod
|
|
487
502
|
def pager(text):
|
|
488
|
-
|
|
503
|
+
""" find reasonable way to display text """
|
|
489
504
|
# this is a much simpler form of what is in pydoc.py
|
|
490
505
|
if not sys.stdout.isatty():
|
|
491
506
|
display.display(text, screen_only=True)
|
|
@@ -504,19 +519,16 @@ class CLI(ABC):
|
|
|
504
519
|
|
|
505
520
|
@staticmethod
|
|
506
521
|
def pager_pipe(text):
|
|
507
|
-
|
|
522
|
+
""" pipe text through a pager """
|
|
508
523
|
if 'less' in CLI.PAGER:
|
|
509
524
|
os.environ['LESS'] = CLI.LESS_OPTS
|
|
510
525
|
try:
|
|
511
526
|
cmd = subprocess.Popen(CLI.PAGER, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout)
|
|
512
527
|
cmd.communicate(input=to_bytes(text))
|
|
513
|
-
except
|
|
514
|
-
pass
|
|
515
|
-
except KeyboardInterrupt:
|
|
528
|
+
except (OSError, KeyboardInterrupt):
|
|
516
529
|
pass
|
|
517
530
|
|
|
518
|
-
|
|
519
|
-
def _play_prereqs():
|
|
531
|
+
def _play_prereqs(self):
|
|
520
532
|
# TODO: evaluate moving all of the code that touches ``AnsibleCollectionConfig``
|
|
521
533
|
# into ``init_plugin_loader`` so that we can specifically remove
|
|
522
534
|
# ``AnsibleCollectionConfig.playbook_paths`` to make it immutable after instantiation
|
|
@@ -547,6 +559,9 @@ class CLI(ABC):
|
|
|
547
559
|
auto_prompt=False)
|
|
548
560
|
loader.set_vault_secrets(vault_secrets)
|
|
549
561
|
|
|
562
|
+
if self.USES_CONNECTION:
|
|
563
|
+
_agent_launch.launch_ssh_agent()
|
|
564
|
+
|
|
550
565
|
# create the inventory, and filter it based on the subset specified (if any)
|
|
551
566
|
inventory = InventoryManager(loader=loader, sources=options['inventory'], cache=(not options.get('flush_cache')))
|
|
552
567
|
|
|
@@ -554,8 +569,19 @@ class CLI(ABC):
|
|
|
554
569
|
# the code, ensuring a consistent view of global variables
|
|
555
570
|
variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))
|
|
556
571
|
|
|
572
|
+
# flush fact cache if requested
|
|
573
|
+
if options['flush_cache']:
|
|
574
|
+
CLI._flush_cache(inventory, variable_manager)
|
|
575
|
+
|
|
557
576
|
return loader, inventory, variable_manager
|
|
558
577
|
|
|
578
|
+
@staticmethod
|
|
579
|
+
def _flush_cache(inventory, variable_manager):
|
|
580
|
+
variable_manager.clear_facts('localhost')
|
|
581
|
+
for host in inventory.list_hosts():
|
|
582
|
+
hostname = host.get_name()
|
|
583
|
+
variable_manager.clear_facts(hostname)
|
|
584
|
+
|
|
559
585
|
@staticmethod
|
|
560
586
|
def get_host_list(inventory, subset, pattern='all'):
|
|
561
587
|
|
|
@@ -575,10 +601,9 @@ class CLI(ABC):
|
|
|
575
601
|
return hosts
|
|
576
602
|
|
|
577
603
|
@staticmethod
|
|
578
|
-
def get_password_from_file(pwd_file):
|
|
579
|
-
|
|
604
|
+
def get_password_from_file(pwd_file: str) -> str:
|
|
580
605
|
b_pwd_file = to_bytes(pwd_file)
|
|
581
|
-
|
|
606
|
+
|
|
582
607
|
if b_pwd_file == b'-':
|
|
583
608
|
# ensure its read as bytes
|
|
584
609
|
secret = sys.stdin.buffer.read()
|
|
@@ -598,23 +623,22 @@ class CLI(ABC):
|
|
|
598
623
|
|
|
599
624
|
stdout, stderr = p.communicate()
|
|
600
625
|
if p.returncode != 0:
|
|
601
|
-
raise AnsibleError("The password script %s returned an error (rc=%s): %s" % (pwd_file, p.returncode, stderr))
|
|
626
|
+
raise AnsibleError("The password script %s returned an error (rc=%s): %s" % (pwd_file, p.returncode, to_text(stderr)))
|
|
602
627
|
secret = stdout
|
|
603
628
|
|
|
604
629
|
else:
|
|
605
630
|
try:
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
raise AnsibleError("Could not read password file %s: %s" % (pwd_file, e))
|
|
631
|
+
with open(b_pwd_file, "rb") as password_file:
|
|
632
|
+
secret = password_file.read().strip()
|
|
633
|
+
except OSError as ex:
|
|
634
|
+
raise AnsibleError(f"Could not read password file {pwd_file!r}.") from ex
|
|
611
635
|
|
|
612
636
|
secret = secret.strip(b'\r\n')
|
|
613
637
|
|
|
614
638
|
if not secret:
|
|
615
639
|
raise AnsibleError('Empty password was provided from file (%s)' % pwd_file)
|
|
616
640
|
|
|
617
|
-
return
|
|
641
|
+
return to_text(secret)
|
|
618
642
|
|
|
619
643
|
@classmethod
|
|
620
644
|
def cli_executor(cls, args=None):
|
|
@@ -626,63 +650,28 @@ class CLI(ABC):
|
|
|
626
650
|
|
|
627
651
|
ansible_dir = Path(C.ANSIBLE_HOME).expanduser()
|
|
628
652
|
try:
|
|
629
|
-
ansible_dir.mkdir(mode=0o700)
|
|
630
|
-
except OSError as
|
|
631
|
-
|
|
632
|
-
display.warning(
|
|
633
|
-
"Failed to create the directory '%s': %s" % (ansible_dir, to_text(exc, errors='surrogate_or_replace'))
|
|
634
|
-
)
|
|
653
|
+
ansible_dir.mkdir(mode=0o700, exist_ok=True)
|
|
654
|
+
except OSError as ex:
|
|
655
|
+
display.error_as_warning(f"Failed to create the directory {ansible_dir!r}.", ex)
|
|
635
656
|
else:
|
|
636
657
|
display.debug("Created the '%s' directory" % ansible_dir)
|
|
637
658
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
exit_code = 6
|
|
644
|
-
else:
|
|
645
|
-
cli = cls(args)
|
|
646
|
-
exit_code = cli.run()
|
|
647
|
-
|
|
648
|
-
except AnsibleOptionsError as e:
|
|
649
|
-
cli.parser.print_help()
|
|
650
|
-
display.error(to_text(e), wrap_text=False)
|
|
651
|
-
exit_code = 5
|
|
652
|
-
except AnsibleParserError as e:
|
|
653
|
-
display.error(to_text(e), wrap_text=False)
|
|
654
|
-
exit_code = 4
|
|
655
|
-
# TQM takes care of these, but leaving comment to reserve the exit codes
|
|
656
|
-
# except AnsibleHostUnreachable as e:
|
|
657
|
-
# display.error(str(e))
|
|
658
|
-
# exit_code = 3
|
|
659
|
-
# except AnsibleHostFailed as e:
|
|
660
|
-
# display.error(str(e))
|
|
661
|
-
# exit_code = 2
|
|
662
|
-
except AnsibleError as e:
|
|
663
|
-
display.error(to_text(e), wrap_text=False)
|
|
664
|
-
exit_code = 1
|
|
659
|
+
cli = cls(args)
|
|
660
|
+
exit_code = cli.run()
|
|
661
|
+
except AnsibleError as ex:
|
|
662
|
+
display.error(ex)
|
|
663
|
+
exit_code = ex._exit_code
|
|
665
664
|
except KeyboardInterrupt:
|
|
666
665
|
display.error("User interrupted execution")
|
|
667
|
-
exit_code =
|
|
668
|
-
except Exception as
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
if hasattr(e, 'orig_exc'):
|
|
678
|
-
display.vvv('\nexception type: %s' % to_text(type(e.orig_exc)))
|
|
679
|
-
why = to_text(e.orig_exc)
|
|
680
|
-
if to_text(e) != why:
|
|
681
|
-
display.vvv('\noriginal msg: %s' % why)
|
|
682
|
-
else:
|
|
683
|
-
display.display("to see the full traceback, use -vvv")
|
|
684
|
-
log_only = True
|
|
685
|
-
display.display(u"the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only)
|
|
686
|
-
exit_code = 250
|
|
666
|
+
exit_code = ExitCode.KEYBOARD_INTERRUPT
|
|
667
|
+
except Exception as ex:
|
|
668
|
+
try:
|
|
669
|
+
raise AnsibleError("Unexpected Exception, this is probably a bug.") from ex
|
|
670
|
+
except AnsibleError as ex2:
|
|
671
|
+
# DTFIX-FUTURE: clean this up so we're not hacking the internals- re-wrap in an AnsibleCLIUnhandledError that always shows TB, or?
|
|
672
|
+
from ansible.module_utils._internal import _traceback
|
|
673
|
+
_traceback._is_traceback_enabled = lambda *_args, **_kwargs: True
|
|
674
|
+
display.error(ex2)
|
|
675
|
+
exit_code = ExitCode.UNKNOWN_ERROR
|
|
687
676
|
|
|
688
677
|
sys.exit(exit_code)
|