ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +160 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +198 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +351 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +62 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +153 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +48 -46
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +165 -108
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +136 -76
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +237 -236
- ansible/executor/task_queue_manager.py +62 -38
- ansible/executor/task_result.py +21 -12
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +77 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +154 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +86 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +1 -1
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +4 -4
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +9 -8
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +19 -17
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +32 -27
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +36 -339
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +6 -15
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +4 -5
- ansible/plugins/action/gather_facts.py +7 -6
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +35 -44
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +141 -123
- ansible/plugins/callback/default.py +30 -23
- ansible/plugins/callback/junit.py +28 -24
- ansible/plugins/callback/minimal.py +17 -14
- ansible/plugins/callback/oneline.py +13 -7
- ansible/plugins/callback/tree.py +10 -6
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +6 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +218 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +97 -77
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +86 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +94 -113
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +13 -28
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +31 -33
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +54 -20
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +368 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +428 -58
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +28 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +4 -4
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +205 -264
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/WHEEL +1 -1
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -0
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +1 -0
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +2 -1
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +4 -0
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +1 -0
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +16 -1
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +24 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +2 -0
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/delegation.py +1 -0
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +35 -27
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/utils/jsonify.py +0 -36
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
ansible/_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.plugins 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., WarningMessageDetail, DeprecationMessageDetail, ErrorDetail).
|
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
@@ -7,8 +7,22 @@ from __future__ import annotations
|
|
7
7
|
|
8
8
|
import locale
|
9
9
|
import os
|
10
|
+
import signal
|
10
11
|
import sys
|
11
12
|
|
13
|
+
|
14
|
+
# We overload the ``ansible`` adhoc command to provide the functionality for
|
15
|
+
# ``SSH_ASKPASS``. This code is here, and not in ``adhoc.py`` to bypass
|
16
|
+
# unnecessary code. The program provided to ``SSH_ASKPASS`` can only be invoked
|
17
|
+
# as a singular command, ``python -m`` doesn't work for that use case, and we
|
18
|
+
# aren't adding a new entrypoint at this time. Assume that if we are executing
|
19
|
+
# and there is only a single item in argv plus the executable, and the env var
|
20
|
+
# is set we are in ``SSH_ASKPASS`` mode
|
21
|
+
if 1 <= len(sys.argv) <= 2 and os.path.basename(sys.argv[0]) == "ansible" and os.getenv('_ANSIBLE_SSH_ASKPASS_SHM'):
|
22
|
+
from ansible.cli import _ssh_askpass
|
23
|
+
_ssh_askpass.main()
|
24
|
+
|
25
|
+
|
12
26
|
# Used for determining if the system is running a new enough python version
|
13
27
|
# and should only restrict on our documented minimum versions
|
14
28
|
if sys.version_info < (3, 11):
|
@@ -63,18 +77,7 @@ def initialize_locale():
|
|
63
77
|
initialize_locale()
|
64
78
|
|
65
79
|
|
66
|
-
|
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
|
-
|
80
|
+
import atexit
|
78
81
|
import errno
|
79
82
|
import getpass
|
80
83
|
import subprocess
|
@@ -82,30 +85,36 @@ import traceback
|
|
82
85
|
from abc import ABC, abstractmethod
|
83
86
|
from pathlib import Path
|
84
87
|
|
88
|
+
from ansible import _internal # do not remove or defer; ensures controller-specific state is set early
|
89
|
+
|
90
|
+
_internal.setup()
|
91
|
+
|
85
92
|
try:
|
86
93
|
from ansible import constants as C
|
87
94
|
from ansible.utils.display import Display
|
88
95
|
display = Display()
|
89
|
-
except Exception as
|
90
|
-
print('ERROR:
|
96
|
+
except Exception as ex:
|
97
|
+
print(f'ERROR: {ex}\n\n{"".join(traceback.format_exception(ex))}', file=sys.stderr)
|
91
98
|
sys.exit(5)
|
92
99
|
|
100
|
+
|
93
101
|
from ansible import context
|
94
102
|
from ansible.cli.arguments import option_helpers as opt_help
|
95
|
-
from ansible.errors import AnsibleError,
|
103
|
+
from ansible.errors import AnsibleError, ExitCode
|
96
104
|
from ansible.inventory.manager import InventoryManager
|
97
105
|
from ansible.module_utils.six import string_types
|
98
106
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
99
107
|
from ansible.module_utils.common.collections import is_sequence
|
100
108
|
from ansible.module_utils.common.file import is_executable
|
109
|
+
from ansible.module_utils.common.process import get_bin_path
|
101
110
|
from ansible.parsing.dataloader import DataLoader
|
102
|
-
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret
|
111
|
+
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret, VaultSecretsContext
|
103
112
|
from ansible.plugins.loader import add_all_plugin_dirs, init_plugin_loader
|
104
113
|
from ansible.release import __version__
|
114
|
+
from ansible.utils._ssh_agent import SshAgentClient
|
105
115
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
106
116
|
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path
|
107
117
|
from ansible.utils.path import unfrackpath
|
108
|
-
from ansible.utils.unsafe_proxy import to_unsafe_text
|
109
118
|
from ansible.vars.manager import VariableManager
|
110
119
|
|
111
120
|
try:
|
@@ -115,8 +124,79 @@ except ImportError:
|
|
115
124
|
HAS_ARGCOMPLETE = False
|
116
125
|
|
117
126
|
|
127
|
+
_SSH_AGENT_STDOUT_READ_TIMEOUT = 5 # seconds
|
128
|
+
|
129
|
+
|
130
|
+
def _ssh_agent_timeout_handler(signum, frame):
|
131
|
+
raise TimeoutError
|
132
|
+
|
133
|
+
|
134
|
+
def _launch_ssh_agent() -> None:
|
135
|
+
ssh_agent_cfg = C.config.get_config_value('SSH_AGENT')
|
136
|
+
match ssh_agent_cfg:
|
137
|
+
case 'none':
|
138
|
+
display.debug('SSH_AGENT set to none')
|
139
|
+
return
|
140
|
+
case 'auto':
|
141
|
+
try:
|
142
|
+
ssh_agent_bin = get_bin_path('ssh-agent', required=True)
|
143
|
+
except ValueError as e:
|
144
|
+
raise AnsibleError('SSH_AGENT set to auto, but cannot find ssh-agent binary') from e
|
145
|
+
ssh_agent_dir = os.path.join(C.DEFAULT_LOCAL_TMP, 'ssh_agent')
|
146
|
+
os.mkdir(ssh_agent_dir, 0o700)
|
147
|
+
sock = os.path.join(ssh_agent_dir, 'agent.sock')
|
148
|
+
display.vvv('SSH_AGENT: starting...')
|
149
|
+
try:
|
150
|
+
p = subprocess.Popen(
|
151
|
+
[ssh_agent_bin, '-D', '-s', '-a', sock],
|
152
|
+
stdin=subprocess.PIPE,
|
153
|
+
stdout=subprocess.PIPE,
|
154
|
+
stderr=subprocess.PIPE,
|
155
|
+
)
|
156
|
+
except OSError as e:
|
157
|
+
raise AnsibleError(
|
158
|
+
f'Could not start ssh-agent: {e}'
|
159
|
+
) from e
|
160
|
+
|
161
|
+
if p.poll() is not None:
|
162
|
+
raise AnsibleError(
|
163
|
+
f'Could not start ssh-agent: rc={p.returncode} stderr="{p.stderr.read().decode()}"'
|
164
|
+
)
|
165
|
+
|
166
|
+
old_sigalrm_handler = signal.signal(signal.SIGALRM, _ssh_agent_timeout_handler)
|
167
|
+
signal.alarm(_SSH_AGENT_STDOUT_READ_TIMEOUT)
|
168
|
+
try:
|
169
|
+
stdout = p.stdout.read(13)
|
170
|
+
except TimeoutError:
|
171
|
+
stdout = b''
|
172
|
+
finally:
|
173
|
+
signal.alarm(0)
|
174
|
+
signal.signal(signal.SIGALRM, old_sigalrm_handler)
|
175
|
+
|
176
|
+
if stdout != b'SSH_AUTH_SOCK':
|
177
|
+
display.warning(
|
178
|
+
f'The first 13 characters of stdout did not match the '
|
179
|
+
f'expected SSH_AUTH_SOCK. This may not be the right binary, '
|
180
|
+
f'or an incompatible agent: {stdout.decode()}'
|
181
|
+
)
|
182
|
+
display.vvv(f'SSH_AGENT: ssh-agent[{p.pid}] started and bound to {sock}')
|
183
|
+
atexit.register(p.terminate)
|
184
|
+
case _:
|
185
|
+
sock = ssh_agent_cfg
|
186
|
+
|
187
|
+
try:
|
188
|
+
with SshAgentClient(sock) as client:
|
189
|
+
client.list()
|
190
|
+
except Exception as e:
|
191
|
+
raise AnsibleError(
|
192
|
+
f'Could not communicate with ssh-agent using auth sock {sock}: {e}'
|
193
|
+
) from e
|
194
|
+
|
195
|
+
os.environ['SSH_AUTH_SOCK'] = os.environ['ANSIBLE_SSH_AGENT'] = sock
|
196
|
+
|
197
|
+
|
118
198
|
class CLI(ABC):
|
119
|
-
|
199
|
+
""" code behind bin/ansible* programs """
|
120
200
|
|
121
201
|
PAGER = C.config.get_config_value('PAGER')
|
122
202
|
|
@@ -124,6 +204,7 @@ class CLI(ABC):
|
|
124
204
|
# -S (chop long lines) -X (disable termcap init and de-init)
|
125
205
|
LESS_OPTS = 'FRSX'
|
126
206
|
SKIP_INVENTORY_DEFAULTS = False
|
207
|
+
USES_CONNECTION = False
|
127
208
|
|
128
209
|
def __init__(self, args, callback=None):
|
129
210
|
"""
|
@@ -137,6 +218,9 @@ class CLI(ABC):
|
|
137
218
|
self.parser = None
|
138
219
|
self.callback = callback
|
139
220
|
|
221
|
+
self.show_devel_warning()
|
222
|
+
|
223
|
+
def show_devel_warning(self) -> None:
|
140
224
|
if C.DEVEL_WARNING and __version__.endswith('dev0'):
|
141
225
|
display.warning(
|
142
226
|
'You are running the development version of Ansible. You should only run Ansible from "devel" if '
|
@@ -208,7 +292,7 @@ class CLI(ABC):
|
|
208
292
|
@staticmethod
|
209
293
|
def setup_vault_secrets(loader, vault_ids, vault_password_files=None,
|
210
294
|
ask_vault_pass=None, create_new_password=False,
|
211
|
-
auto_prompt=True):
|
295
|
+
auto_prompt=True, initialize_context=True):
|
212
296
|
# list of tuples
|
213
297
|
vault_secrets = []
|
214
298
|
|
@@ -305,24 +389,22 @@ class CLI(ABC):
|
|
305
389
|
if last_exception and not found_vault_secret:
|
306
390
|
raise last_exception
|
307
391
|
|
392
|
+
if initialize_context:
|
393
|
+
VaultSecretsContext.initialize(VaultSecretsContext(vault_secrets))
|
394
|
+
|
308
395
|
return vault_secrets
|
309
396
|
|
310
397
|
@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
|
398
|
+
def _get_secret(prompt: str) -> str:
|
399
|
+
return getpass.getpass(prompt=prompt)
|
317
400
|
|
318
401
|
@staticmethod
|
319
402
|
def ask_passwords():
|
320
|
-
|
403
|
+
""" prompt for connection and become passwords if needed """
|
321
404
|
|
322
405
|
op = context.CLIARGS
|
323
406
|
sshpass = None
|
324
407
|
becomepass = None
|
325
|
-
become_prompt = ''
|
326
408
|
|
327
409
|
become_prompt_method = "BECOME" if C.AGNOSTIC_BECOME_PROMPT else op['become_method'].upper()
|
328
410
|
|
@@ -344,10 +426,10 @@ class CLI(ABC):
|
|
344
426
|
except EOFError:
|
345
427
|
pass
|
346
428
|
|
347
|
-
return
|
429
|
+
return sshpass, becomepass
|
348
430
|
|
349
431
|
def validate_conflicts(self, op, runas_opts=False, fork_opts=False):
|
350
|
-
|
432
|
+
""" check for conflicting options """
|
351
433
|
|
352
434
|
if fork_opts:
|
353
435
|
if op.forks < 1:
|
@@ -459,7 +541,7 @@ class CLI(ABC):
|
|
459
541
|
|
460
542
|
@staticmethod
|
461
543
|
def version_info(gitinfo=False):
|
462
|
-
|
544
|
+
""" return full ansible version info """
|
463
545
|
if gitinfo:
|
464
546
|
# expensive call, user with care
|
465
547
|
ansible_version_string = opt_help.version()
|
@@ -485,7 +567,7 @@ class CLI(ABC):
|
|
485
567
|
|
486
568
|
@staticmethod
|
487
569
|
def pager(text):
|
488
|
-
|
570
|
+
""" find reasonable way to display text """
|
489
571
|
# this is a much simpler form of what is in pydoc.py
|
490
572
|
if not sys.stdout.isatty():
|
491
573
|
display.display(text, screen_only=True)
|
@@ -504,7 +586,7 @@ class CLI(ABC):
|
|
504
586
|
|
505
587
|
@staticmethod
|
506
588
|
def pager_pipe(text):
|
507
|
-
|
589
|
+
""" pipe text through a pager """
|
508
590
|
if 'less' in CLI.PAGER:
|
509
591
|
os.environ['LESS'] = CLI.LESS_OPTS
|
510
592
|
try:
|
@@ -515,8 +597,7 @@ class CLI(ABC):
|
|
515
597
|
except KeyboardInterrupt:
|
516
598
|
pass
|
517
599
|
|
518
|
-
|
519
|
-
def _play_prereqs():
|
600
|
+
def _play_prereqs(self):
|
520
601
|
# TODO: evaluate moving all of the code that touches ``AnsibleCollectionConfig``
|
521
602
|
# into ``init_plugin_loader`` so that we can specifically remove
|
522
603
|
# ``AnsibleCollectionConfig.playbook_paths`` to make it immutable after instantiation
|
@@ -547,6 +628,12 @@ class CLI(ABC):
|
|
547
628
|
auto_prompt=False)
|
548
629
|
loader.set_vault_secrets(vault_secrets)
|
549
630
|
|
631
|
+
if self.USES_CONNECTION:
|
632
|
+
try:
|
633
|
+
_launch_ssh_agent()
|
634
|
+
except Exception as e:
|
635
|
+
raise AnsibleError('Failed to launch ssh agent', orig_exc=e)
|
636
|
+
|
550
637
|
# create the inventory, and filter it based on the subset specified (if any)
|
551
638
|
inventory = InventoryManager(loader=loader, sources=options['inventory'], cache=(not options.get('flush_cache')))
|
552
639
|
|
@@ -554,8 +641,19 @@ class CLI(ABC):
|
|
554
641
|
# the code, ensuring a consistent view of global variables
|
555
642
|
variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))
|
556
643
|
|
644
|
+
# flush fact cache if requested
|
645
|
+
if options['flush_cache']:
|
646
|
+
CLI._flush_cache(inventory, variable_manager)
|
647
|
+
|
557
648
|
return loader, inventory, variable_manager
|
558
649
|
|
650
|
+
@staticmethod
|
651
|
+
def _flush_cache(inventory, variable_manager):
|
652
|
+
variable_manager.clear_facts('localhost')
|
653
|
+
for host in inventory.list_hosts():
|
654
|
+
hostname = host.get_name()
|
655
|
+
variable_manager.clear_facts(hostname)
|
656
|
+
|
559
657
|
@staticmethod
|
560
658
|
def get_host_list(inventory, subset, pattern='all'):
|
561
659
|
|
@@ -575,10 +673,9 @@ class CLI(ABC):
|
|
575
673
|
return hosts
|
576
674
|
|
577
675
|
@staticmethod
|
578
|
-
def get_password_from_file(pwd_file):
|
579
|
-
|
676
|
+
def get_password_from_file(pwd_file: str) -> str:
|
580
677
|
b_pwd_file = to_bytes(pwd_file)
|
581
|
-
|
678
|
+
|
582
679
|
if b_pwd_file == b'-':
|
583
680
|
# ensure its read as bytes
|
584
681
|
secret = sys.stdin.buffer.read()
|
@@ -598,14 +695,13 @@ class CLI(ABC):
|
|
598
695
|
|
599
696
|
stdout, stderr = p.communicate()
|
600
697
|
if p.returncode != 0:
|
601
|
-
raise AnsibleError("The password script %s returned an error (rc=%s): %s" % (pwd_file, p.returncode, stderr))
|
698
|
+
raise AnsibleError("The password script %s returned an error (rc=%s): %s" % (pwd_file, p.returncode, to_text(stderr)))
|
602
699
|
secret = stdout
|
603
700
|
|
604
701
|
else:
|
605
702
|
try:
|
606
|
-
|
607
|
-
|
608
|
-
f.close()
|
703
|
+
with open(b_pwd_file, "rb") as password_file:
|
704
|
+
secret = password_file.read().strip()
|
609
705
|
except (OSError, IOError) as e:
|
610
706
|
raise AnsibleError("Could not read password file %s: %s" % (pwd_file, e))
|
611
707
|
|
@@ -614,7 +710,7 @@ class CLI(ABC):
|
|
614
710
|
if not secret:
|
615
711
|
raise AnsibleError('Empty password was provided from file (%s)' % pwd_file)
|
616
712
|
|
617
|
-
return
|
713
|
+
return to_text(secret)
|
618
714
|
|
619
715
|
@classmethod
|
620
716
|
def cli_executor(cls, args=None):
|
@@ -635,54 +731,22 @@ class CLI(ABC):
|
|
635
731
|
else:
|
636
732
|
display.debug("Created the '%s' directory" % ansible_dir)
|
637
733
|
|
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
|
734
|
+
cli = cls(args)
|
735
|
+
exit_code = cli.run()
|
736
|
+
except AnsibleError as ex:
|
737
|
+
display.error(ex)
|
738
|
+
exit_code = ex._exit_code
|
665
739
|
except KeyboardInterrupt:
|
666
740
|
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
|
741
|
+
exit_code = ExitCode.KEYBOARD_INTERRUPT
|
742
|
+
except Exception as ex:
|
743
|
+
try:
|
744
|
+
raise AnsibleError("Unexpected Exception, this is probably a bug.") from ex
|
745
|
+
except AnsibleError as ex2:
|
746
|
+
# DTFIX-RELEASE: clean this up so we're not hacking the internals- re-wrap in an AnsibleCLIUnhandledError that always shows TB, or?
|
747
|
+
from ansible.module_utils._internal import _traceback
|
748
|
+
_traceback._is_traceback_enabled = lambda *_args, **_kwargs: True
|
749
|
+
display.error(ex2)
|
750
|
+
exit_code = ExitCode.UNKNOWN_ERROR
|
687
751
|
|
688
752
|
sys.exit(exit_code)
|