ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b2__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/_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/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +203 -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 +197 -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 +345 -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 +159 -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 +62 -53
- 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 +166 -112
- 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 +161 -96
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +268 -258
- ansible/executor/task_queue_manager.py +124 -90
- ansible/executor/task_result.py +183 -78
- 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 +78 -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 +152 -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/jsonify.py +5 -1
- 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 +43 -335
- 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 +31 -27
- 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 +284 -179
- ansible/plugins/callback/default.py +99 -92
- ansible/plugins/callback/junit.py +44 -39
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +28 -21
- ansible/plugins/callback/tree.py +16 -11
- 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 +225 -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 +159 -184
- 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 +55 -21
- 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 +370 -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 +433 -63
- 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 +51 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +206 -282
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.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/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.0b2.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
# Copyright: Contributors to the Ansible project
|
2
|
+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import json
|
6
|
+
import os
|
7
|
+
import re
|
8
|
+
import sys
|
9
|
+
import typing as t
|
10
|
+
from multiprocessing.shared_memory import SharedMemory
|
11
|
+
|
12
|
+
HOST_KEY_RE = re.compile(
|
13
|
+
r'(The authenticity of host |differs from the key for the IP address)',
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
def main() -> t.Never:
|
18
|
+
try:
|
19
|
+
if HOST_KEY_RE.search(sys.argv[1]):
|
20
|
+
sys.stdout.buffer.write(b'no')
|
21
|
+
sys.stdout.flush()
|
22
|
+
sys.exit(0)
|
23
|
+
except IndexError:
|
24
|
+
pass
|
25
|
+
|
26
|
+
kwargs: dict[str, bool] = {}
|
27
|
+
if sys.version_info[:2] >= (3, 13):
|
28
|
+
# deprecated: description='unneeded due to track argument for SharedMemory' python_version='3.12'
|
29
|
+
kwargs['track'] = False
|
30
|
+
try:
|
31
|
+
shm = SharedMemory(name=os.environ['_ANSIBLE_SSH_ASKPASS_SHM'], **kwargs)
|
32
|
+
except FileNotFoundError:
|
33
|
+
# We must be running after the ansible fork is shutting down
|
34
|
+
sys.exit(1)
|
35
|
+
cfg = json.loads(shm.buf.tobytes().rstrip(b'\x00'))
|
36
|
+
|
37
|
+
try:
|
38
|
+
if cfg['prompt'] not in sys.argv[1]:
|
39
|
+
sys.exit(1)
|
40
|
+
except IndexError:
|
41
|
+
sys.exit(1)
|
42
|
+
|
43
|
+
sys.stdout.buffer.write(cfg['password'].encode('utf-8'))
|
44
|
+
sys.stdout.flush()
|
45
|
+
shm.buf[:] = b'\x00' * shm.size
|
46
|
+
shm.close()
|
47
|
+
sys.exit(0)
|
ansible/cli/adhoc.py
CHANGED
@@ -6,6 +6,8 @@
|
|
6
6
|
|
7
7
|
from __future__ import annotations
|
8
8
|
|
9
|
+
import json
|
10
|
+
|
9
11
|
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
|
10
12
|
from ansible.cli import CLI
|
11
13
|
from ansible import constants as C
|
@@ -15,23 +17,26 @@ from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
|
|
15
17
|
from ansible.executor.task_queue_manager import TaskQueueManager
|
16
18
|
from ansible.module_utils.common.text.converters import to_text
|
17
19
|
from ansible.parsing.splitter import parse_kv
|
18
|
-
from ansible.parsing.utils.yaml import from_yaml
|
19
20
|
from ansible.playbook import Playbook
|
20
21
|
from ansible.playbook.play import Play
|
22
|
+
from ansible._internal._datatag._tags import Origin
|
21
23
|
from ansible.utils.display import Display
|
24
|
+
from ansible._internal._json._profiles import _legacy
|
22
25
|
|
23
26
|
display = Display()
|
24
27
|
|
25
28
|
|
26
29
|
class AdHocCLI(CLI):
|
27
|
-
|
30
|
+
""" is an extra-simple tool/framework/API for doing 'remote things'.
|
28
31
|
this command allows you to define and run a single task 'playbook' against a set of hosts
|
29
|
-
|
32
|
+
"""
|
30
33
|
|
31
34
|
name = 'ansible'
|
32
35
|
|
36
|
+
USES_CONNECTION = True
|
37
|
+
|
33
38
|
def init_parser(self):
|
34
|
-
|
39
|
+
""" create an options parser for bin/ansible """
|
35
40
|
super(AdHocCLI, self).init_parser(usage='%prog <host-pattern> [options]',
|
36
41
|
desc="Define and run a single task 'playbook' against a set of hosts",
|
37
42
|
epilog="Some actions do not make sense in Ad-Hoc (include, meta, etc)")
|
@@ -60,7 +65,7 @@ class AdHocCLI(CLI):
|
|
60
65
|
self.parser.add_argument('args', metavar='pattern', help='host pattern')
|
61
66
|
|
62
67
|
def post_process_args(self, options):
|
63
|
-
|
68
|
+
"""Post process and validate options for bin/ansible """
|
64
69
|
|
65
70
|
options = super(AdHocCLI, self).post_process_args(options)
|
66
71
|
|
@@ -76,7 +81,7 @@ class AdHocCLI(CLI):
|
|
76
81
|
module_args = None
|
77
82
|
if module_args_raw and module_args_raw.startswith('{') and module_args_raw.endswith('}'):
|
78
83
|
try:
|
79
|
-
module_args =
|
84
|
+
module_args = json.loads(module_args_raw, cls=_legacy.Decoder)
|
80
85
|
except AnsibleParserError:
|
81
86
|
pass
|
82
87
|
|
@@ -86,6 +91,8 @@ class AdHocCLI(CLI):
|
|
86
91
|
mytask = {'action': {'module': context.CLIARGS['module_name'], 'args': module_args},
|
87
92
|
'timeout': context.CLIARGS['task_timeout']}
|
88
93
|
|
94
|
+
mytask = Origin(description=f'<adhoc {context.CLIARGS["module_name"]!r} task>').tag(mytask)
|
95
|
+
|
89
96
|
# avoid adding to tasks that don't support it, unless set, then give user an error
|
90
97
|
if context.CLIARGS['module_name'] not in C._ACTION_ALL_INCLUDE_ROLE_TASKS and any(frozenset((async_val, poll))):
|
91
98
|
mytask['async_val'] = async_val
|
@@ -98,7 +105,7 @@ class AdHocCLI(CLI):
|
|
98
105
|
tasks=[mytask])
|
99
106
|
|
100
107
|
def run(self):
|
101
|
-
|
108
|
+
""" create and execute the single task playbook """
|
102
109
|
|
103
110
|
super(AdHocCLI, self).run()
|
104
111
|
|
@@ -4,12 +4,17 @@
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
6
|
import copy
|
7
|
+
import dataclasses
|
8
|
+
import inspect
|
7
9
|
import operator
|
8
10
|
import argparse
|
9
11
|
import os
|
10
12
|
import os.path
|
11
13
|
import sys
|
12
14
|
import time
|
15
|
+
import typing as t
|
16
|
+
|
17
|
+
import yaml
|
13
18
|
|
14
19
|
from jinja2 import __version__ as j2_version
|
15
20
|
|
@@ -20,6 +25,8 @@ from ansible.module_utils.common.yaml import HAS_LIBYAML, yaml_load
|
|
20
25
|
from ansible.release import __version__
|
21
26
|
from ansible.utils.path import unfrackpath
|
22
27
|
|
28
|
+
from ansible._internal._datatag._tags import TrustedAsTemplate, Origin
|
29
|
+
|
23
30
|
|
24
31
|
#
|
25
32
|
# Special purpose OptionParsers
|
@@ -30,13 +37,115 @@ class SortingHelpFormatter(argparse.HelpFormatter):
|
|
30
37
|
super(SortingHelpFormatter, self).add_arguments(actions)
|
31
38
|
|
32
39
|
|
40
|
+
@dataclasses.dataclass(frozen=True, kw_only=True)
|
41
|
+
class DeprecatedArgument:
|
42
|
+
version: str
|
43
|
+
"""The Ansible version that will remove the deprecated argument."""
|
44
|
+
|
45
|
+
option: str | None = None
|
46
|
+
"""The specific option string that is deprecated; None applies to all options for this argument."""
|
47
|
+
|
48
|
+
def is_deprecated(self, option: str) -> bool:
|
49
|
+
"""Return True if the given option is deprecated, otherwise False."""
|
50
|
+
return self.option is None or option == self.option
|
51
|
+
|
52
|
+
def check(self, option: str) -> None:
|
53
|
+
"""Display a deprecation warning if the given option is deprecated."""
|
54
|
+
if not self.is_deprecated(option):
|
55
|
+
return
|
56
|
+
|
57
|
+
from ansible.utils.display import Display
|
58
|
+
|
59
|
+
Display().deprecated(f'The {option!r} argument is deprecated.', version=self.version)
|
60
|
+
|
61
|
+
|
33
62
|
class ArgumentParser(argparse.ArgumentParser):
|
34
|
-
def
|
63
|
+
def __init__(self, *args, **kwargs) -> None:
|
64
|
+
self.__actions: dict[str | None, type[argparse.Action]] = {}
|
65
|
+
|
66
|
+
super().__init__(*args, **kwargs)
|
67
|
+
|
68
|
+
def register(self, registry_name, value, object):
|
69
|
+
"""Track registration of actions so that they can be resolved later by name, without depending on the internals of ArgumentParser."""
|
70
|
+
if registry_name == 'action':
|
71
|
+
self.__actions[value] = object
|
72
|
+
|
73
|
+
super().register(registry_name, value, object)
|
74
|
+
|
75
|
+
def _patch_argument(self, args: tuple[str, ...], kwargs: dict[str, t.Any]) -> None:
|
76
|
+
"""
|
77
|
+
Patch `kwargs` for an `add_argument` call using the given `args` and `kwargs`.
|
78
|
+
This is used to apply tags to entire categories of CLI arguments.
|
79
|
+
"""
|
80
|
+
name = args[0]
|
81
|
+
action = kwargs.get('action')
|
82
|
+
resolved_action = self.__actions.get(action, action) # get the action by name, or use as-is (assume it's a subclass of argparse.Action)
|
83
|
+
action_signature = inspect.signature(resolved_action.__init__)
|
84
|
+
|
85
|
+
if action_signature.parameters.get('type'):
|
86
|
+
arg_type = kwargs.get('type', str)
|
87
|
+
|
88
|
+
if not callable(arg_type):
|
89
|
+
raise ValueError(f'Argument {name!r} requires a callable for the {"type"!r} parameter, not {arg_type!r}.')
|
90
|
+
|
91
|
+
wrapped_arg_type = _tagged_type_factory(name, arg_type)
|
92
|
+
|
93
|
+
kwargs.update(type=wrapped_arg_type)
|
94
|
+
|
95
|
+
def _patch_parser(self, parser):
|
96
|
+
"""Patch and return the given parser to intercept the `add_argument` method for further patching."""
|
97
|
+
parser_add_argument = parser.add_argument
|
98
|
+
|
99
|
+
def add_argument(*ag_args, **ag_kwargs):
|
100
|
+
self._patch_argument(ag_args, ag_kwargs)
|
101
|
+
|
102
|
+
parser_add_argument(*ag_args, **ag_kwargs)
|
103
|
+
|
104
|
+
parser.add_argument = add_argument
|
105
|
+
|
106
|
+
return parser
|
107
|
+
|
108
|
+
def add_subparsers(self, *args, **kwargs):
|
109
|
+
sub = super().add_subparsers(*args, **kwargs)
|
110
|
+
sub_add_parser = sub.add_parser
|
111
|
+
|
112
|
+
def add_parser(*sub_args, **sub_kwargs):
|
113
|
+
return self._patch_parser(sub_add_parser(*sub_args, **sub_kwargs))
|
114
|
+
|
115
|
+
sub.add_parser = add_parser
|
116
|
+
|
117
|
+
return sub
|
118
|
+
|
119
|
+
def add_argument_group(self, *args, **kwargs):
|
120
|
+
return self._patch_parser(super().add_argument_group(*args, **kwargs))
|
121
|
+
|
122
|
+
def add_mutually_exclusive_group(self, *args, **kwargs):
|
123
|
+
return self._patch_parser(super().add_mutually_exclusive_group(*args, **kwargs))
|
124
|
+
|
125
|
+
def add_argument(self, *args, **kwargs) -> argparse.Action:
|
35
126
|
action = kwargs.get('action')
|
36
127
|
help = kwargs.get('help')
|
37
128
|
if help and action in {'append', 'append_const', 'count', 'extend', PrependListAction}:
|
38
129
|
help = f'{help.rstrip(".")}. This argument may be specified multiple times.'
|
39
130
|
kwargs['help'] = help
|
131
|
+
|
132
|
+
self._patch_argument(args, kwargs)
|
133
|
+
|
134
|
+
deprecated: DeprecatedArgument | None
|
135
|
+
|
136
|
+
if deprecated := kwargs.pop('deprecated', None):
|
137
|
+
action_type = self.__actions.get(action, action)
|
138
|
+
|
139
|
+
class DeprecatedAction(action_type): # type: ignore[misc, valid-type]
|
140
|
+
"""A wrapper around an action which handles deprecation warnings."""
|
141
|
+
|
142
|
+
def __call__(self, parser, namespace, values, option_string=None) -> t.Any:
|
143
|
+
deprecated.check(option_string)
|
144
|
+
|
145
|
+
return super().__call__(parser, namespace, values, option_string)
|
146
|
+
|
147
|
+
kwargs['action'] = DeprecatedAction
|
148
|
+
|
40
149
|
return super().add_argument(*args, **kwargs)
|
41
150
|
|
42
151
|
|
@@ -182,13 +291,28 @@ def version(prog=None):
|
|
182
291
|
cpath = "Default w/o overrides"
|
183
292
|
else:
|
184
293
|
cpath = C.DEFAULT_MODULE_PATH
|
294
|
+
|
295
|
+
if HAS_LIBYAML:
|
296
|
+
libyaml_fragment = "with libyaml"
|
297
|
+
|
298
|
+
# noinspection PyBroadException
|
299
|
+
try:
|
300
|
+
from yaml._yaml import get_version_string
|
301
|
+
|
302
|
+
libyaml_fragment += f" v{get_version_string()}"
|
303
|
+
except Exception: # pylint: disable=broad-except
|
304
|
+
libyaml_fragment += ", version unknown"
|
305
|
+
else:
|
306
|
+
libyaml_fragment = "without libyaml"
|
307
|
+
|
185
308
|
result.append(" configured module search path = %s" % cpath)
|
186
309
|
result.append(" ansible python module location = %s" % ':'.join(ansible.__path__))
|
187
310
|
result.append(" ansible collection location = %s" % ':'.join(C.COLLECTIONS_PATHS))
|
188
311
|
result.append(" executable location = %s" % sys.argv[0])
|
189
312
|
result.append(" python version = %s (%s)" % (''.join(sys.version.splitlines()), to_native(sys.executable)))
|
190
313
|
result.append(" jinja version = %s" % j2_version)
|
191
|
-
result.append("
|
314
|
+
result.append(f" pyyaml version = {yaml.__version__} ({libyaml_fragment})")
|
315
|
+
|
192
316
|
return "\n".join(result)
|
193
317
|
|
194
318
|
|
@@ -292,19 +416,20 @@ def add_fork_options(parser):
|
|
292
416
|
def add_inventory_options(parser):
|
293
417
|
"""Add options for commands that utilize inventory"""
|
294
418
|
parser.add_argument('-i', '--inventory', '--inventory-file', dest='inventory', action="append",
|
295
|
-
help="specify inventory host path or comma separated host list
|
419
|
+
help="specify inventory host path or comma separated host list",
|
420
|
+
deprecated=DeprecatedArgument(version='2.23', option='--inventory-file'))
|
296
421
|
parser.add_argument('--list-hosts', dest='listhosts', action='store_true',
|
297
422
|
help='outputs a list of matching hosts; does not execute anything else')
|
298
423
|
parser.add_argument('-l', '--limit', default=C.DEFAULT_SUBSET, dest='subset',
|
299
424
|
help='further limit selected hosts to an additional pattern')
|
425
|
+
parser.add_argument('--flush-cache', dest='flush_cache', action='store_true',
|
426
|
+
help="clear the fact cache for every host in inventory")
|
300
427
|
|
301
428
|
|
302
429
|
def add_meta_options(parser):
|
303
430
|
"""Add options for commands which can launch meta tasks from the command line"""
|
304
431
|
parser.add_argument('--force-handlers', default=C.DEFAULT_FORCE_HANDLERS, dest='force_handlers', action='store_true',
|
305
432
|
help="run handlers even if a task fails")
|
306
|
-
parser.add_argument('--flush-cache', dest='flush_cache', action='store_true',
|
307
|
-
help="clear the fact cache for every host in inventory")
|
308
433
|
|
309
434
|
|
310
435
|
def add_module_options(parser):
|
@@ -318,9 +443,9 @@ def add_module_options(parser):
|
|
318
443
|
def add_output_options(parser):
|
319
444
|
"""Add options for commands which can change their output"""
|
320
445
|
parser.add_argument('-o', '--one-line', dest='one_line', action='store_true',
|
321
|
-
help='condense output')
|
446
|
+
help='condense output', deprecated=DeprecatedArgument(version='2.23'))
|
322
447
|
parser.add_argument('-t', '--tree', dest='tree', default=None,
|
323
|
-
help='log output to this directory')
|
448
|
+
help='log output to this directory', deprecated=DeprecatedArgument(version='2.23'))
|
324
449
|
|
325
450
|
|
326
451
|
def add_runas_options(parser):
|
@@ -396,3 +521,25 @@ def add_vault_options(parser):
|
|
396
521
|
help='ask for vault password')
|
397
522
|
base_group.add_argument('--vault-password-file', '--vault-pass-file', default=[], dest='vault_password_files',
|
398
523
|
help="vault password file", type=unfrack_path(follow=False), action='append')
|
524
|
+
|
525
|
+
|
526
|
+
def _tagged_type_factory(name: str, func: t.Callable[[str], object], /) -> t.Callable[[str], object]:
|
527
|
+
"""
|
528
|
+
Return a callable that wraps the given function.
|
529
|
+
The result of the wrapped function will be tagged with Origin.
|
530
|
+
It will also be tagged with TrustedAsTemplate if it is equal to the original input string.
|
531
|
+
"""
|
532
|
+
def tag_value(value: str) -> object:
|
533
|
+
result = func(value)
|
534
|
+
|
535
|
+
if result is value:
|
536
|
+
# Values which are not mutated are automatically trusted for templating.
|
537
|
+
# The `is` reference equality is critically important, as other types may only alter the tags, so object equality is
|
538
|
+
# not sufficient to prevent them being tagged as trusted when they should not.
|
539
|
+
result = TrustedAsTemplate().tag(result)
|
540
|
+
|
541
|
+
return Origin(description=f'<CLI option {name!r}>').tag(result)
|
542
|
+
|
543
|
+
tag_value._name = name # simplify debugging by attaching the argument name to the function
|
544
|
+
|
545
|
+
return tag_value
|
ansible/cli/config.py
CHANGED
@@ -10,7 +10,6 @@ from ansible.cli import CLI
|
|
10
10
|
|
11
11
|
import os
|
12
12
|
import shlex
|
13
|
-
import subprocess
|
14
13
|
import sys
|
15
14
|
import yaml
|
16
15
|
|
@@ -21,10 +20,10 @@ import ansible.plugins.loader as plugin_loader
|
|
21
20
|
|
22
21
|
from ansible import constants as C
|
23
22
|
from ansible.cli.arguments import option_helpers as opt_help
|
24
|
-
from ansible.config.manager import ConfigManager
|
23
|
+
from ansible.config.manager import ConfigManager
|
25
24
|
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleRequiredOptionError
|
26
25
|
from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
|
27
|
-
from ansible.
|
26
|
+
from ansible._internal import _json
|
28
27
|
from ansible.module_utils.six import string_types
|
29
28
|
from ansible.parsing.quoting import is_quoted
|
30
29
|
from ansible.parsing.yaml.dumper import AnsibleDumper
|
@@ -47,14 +46,14 @@ def yaml_short(data):
|
|
47
46
|
|
48
47
|
|
49
48
|
def get_constants():
|
50
|
-
|
49
|
+
""" helper method to ensure we can template based on existing constants """
|
51
50
|
if not hasattr(get_constants, 'cvars'):
|
52
51
|
get_constants.cvars = {k: getattr(C, k) for k in dir(C) if not k.startswith('__')}
|
53
52
|
return get_constants.cvars
|
54
53
|
|
55
54
|
|
56
55
|
def _ansible_env_vars(varname):
|
57
|
-
|
56
|
+
""" return true or false depending if variable name is possibly a 'configurable' ansible env variable """
|
58
57
|
return all(
|
59
58
|
[
|
60
59
|
varname.startswith("ANSIBLE_"),
|
@@ -178,8 +177,6 @@ class ConfigCLI(CLI):
|
|
178
177
|
except Exception:
|
179
178
|
if context.CLIARGS['action'] in ['view']:
|
180
179
|
raise
|
181
|
-
elif context.CLIARGS['action'] in ['edit', 'update']:
|
182
|
-
display.warning("File does not exist, used empty file: %s" % self.config_file)
|
183
180
|
|
184
181
|
elif context.CLIARGS['action'] == 'view':
|
185
182
|
raise AnsibleError('Invalid or no config file was supplied')
|
@@ -187,54 +184,16 @@ class ConfigCLI(CLI):
|
|
187
184
|
# run the requested action
|
188
185
|
context.CLIARGS['func']()
|
189
186
|
|
190
|
-
def execute_update(self):
|
191
|
-
'''
|
192
|
-
Updates a single setting in the specified ansible.cfg
|
193
|
-
'''
|
194
|
-
raise AnsibleError("Option not implemented yet")
|
195
|
-
|
196
|
-
# pylint: disable=unreachable
|
197
|
-
if context.CLIARGS['setting'] is None:
|
198
|
-
raise AnsibleOptionsError("update option requires a setting to update")
|
199
|
-
|
200
|
-
(entry, value) = context.CLIARGS['setting'].split('=')
|
201
|
-
if '.' in entry:
|
202
|
-
(section, option) = entry.split('.')
|
203
|
-
else:
|
204
|
-
section = 'defaults'
|
205
|
-
option = entry
|
206
|
-
subprocess.call([
|
207
|
-
'ansible',
|
208
|
-
'-m', 'ini_file',
|
209
|
-
'localhost',
|
210
|
-
'-c', 'local',
|
211
|
-
'-a', '"dest=%s section=%s option=%s value=%s backup=yes"' % (self.config_file, section, option, value)
|
212
|
-
])
|
213
|
-
|
214
187
|
def execute_view(self):
|
215
|
-
|
188
|
+
"""
|
216
189
|
Displays the current config file
|
217
|
-
|
190
|
+
"""
|
218
191
|
try:
|
219
192
|
with open(self.config_file, 'rb') as f:
|
220
193
|
self.pager(to_text(f.read(), errors='surrogate_or_strict'))
|
221
194
|
except Exception as e:
|
222
195
|
raise AnsibleError("Failed to open config file: %s" % to_native(e))
|
223
196
|
|
224
|
-
def execute_edit(self):
|
225
|
-
'''
|
226
|
-
Opens ansible.cfg in the default EDITOR
|
227
|
-
'''
|
228
|
-
raise AnsibleError("Option not implemented yet")
|
229
|
-
|
230
|
-
# pylint: disable=unreachable
|
231
|
-
try:
|
232
|
-
editor = shlex.split(C.config.get_config_value('EDITOR'))
|
233
|
-
editor.append(self.config_file)
|
234
|
-
subprocess.call(editor)
|
235
|
-
except Exception as e:
|
236
|
-
raise AnsibleError("Failed to open editor: %s" % to_native(e))
|
237
|
-
|
238
197
|
def _list_plugin_settings(self, ptype, plugins=None):
|
239
198
|
entries = {}
|
240
199
|
loader = getattr(plugin_loader, '%s_loader' % ptype)
|
@@ -266,9 +225,9 @@ class ConfigCLI(CLI):
|
|
266
225
|
return entries
|
267
226
|
|
268
227
|
def _list_entries_from_args(self):
|
269
|
-
|
228
|
+
"""
|
270
229
|
build a dict with the list requested configs
|
271
|
-
|
230
|
+
"""
|
272
231
|
|
273
232
|
config_entries = {}
|
274
233
|
if context.CLIARGS['type'] in ('base', 'all'):
|
@@ -294,15 +253,15 @@ class ConfigCLI(CLI):
|
|
294
253
|
return config_entries
|
295
254
|
|
296
255
|
def execute_list(self):
|
297
|
-
|
256
|
+
"""
|
298
257
|
list and output available configs
|
299
|
-
|
258
|
+
"""
|
300
259
|
|
301
260
|
config_entries = self._list_entries_from_args()
|
302
261
|
if context.CLIARGS['format'] == 'yaml':
|
303
262
|
output = yaml_dump(config_entries)
|
304
263
|
elif context.CLIARGS['format'] == 'json':
|
305
|
-
output =
|
264
|
+
output = _json.json_dumps_formatted(config_entries)
|
306
265
|
|
307
266
|
self.pager(to_text(output, errors='surrogate_or_strict'))
|
308
267
|
|
@@ -458,21 +417,21 @@ class ConfigCLI(CLI):
|
|
458
417
|
|
459
418
|
entries = []
|
460
419
|
for setting in sorted(config):
|
461
|
-
changed = (config[setting]
|
420
|
+
changed = (config[setting]['origin'] not in ('default', 'REQUIRED') and setting not in _IGNORE_CHANGED)
|
462
421
|
|
463
422
|
if context.CLIARGS['format'] == 'display':
|
464
|
-
if isinstance(config[setting],
|
423
|
+
if isinstance(config[setting], dict):
|
465
424
|
# proceed normally
|
466
|
-
value = config[setting]
|
467
|
-
if config[setting]
|
425
|
+
value = config[setting]['value']
|
426
|
+
if config[setting]['origin'] == 'default' or setting in _IGNORE_CHANGED:
|
468
427
|
color = 'green'
|
469
428
|
value = self.config.template_default(value, get_constants())
|
470
|
-
elif config[setting]
|
429
|
+
elif config[setting]['origin'] == 'REQUIRED':
|
471
430
|
# should include '_terms', '_input', etc
|
472
431
|
color = 'red'
|
473
432
|
else:
|
474
433
|
color = 'yellow'
|
475
|
-
msg = "%s(%s) = %s" % (setting, config[setting]
|
434
|
+
msg = "%s(%s) = %s" % (setting, config[setting]['origin'], value)
|
476
435
|
else:
|
477
436
|
color = 'green'
|
478
437
|
msg = "%s(%s) = %s" % (setting, 'default', config[setting].get('default'))
|
@@ -480,10 +439,10 @@ class ConfigCLI(CLI):
|
|
480
439
|
entry = stringc(msg, color)
|
481
440
|
else:
|
482
441
|
entry = {}
|
483
|
-
for key in config[setting].
|
442
|
+
for key in config[setting].keys():
|
484
443
|
if key == 'type':
|
485
444
|
continue
|
486
|
-
entry[key] =
|
445
|
+
entry[key] = config[setting][key]
|
487
446
|
|
488
447
|
if not context.CLIARGS['only_changed'] or changed:
|
489
448
|
entries.append(entry)
|
@@ -495,11 +454,17 @@ class ConfigCLI(CLI):
|
|
495
454
|
# Add base
|
496
455
|
config = self.config.get_configuration_definitions(ignore_private=True)
|
497
456
|
# convert to settings
|
457
|
+
settings = {}
|
498
458
|
for setting in config.keys():
|
499
459
|
v, o = C.config.get_config_value_and_origin(setting, cfile=self.config_file, variables=get_constants())
|
500
|
-
|
460
|
+
settings[setting] = {
|
461
|
+
'name': setting,
|
462
|
+
'value': v,
|
463
|
+
'origin': o,
|
464
|
+
'type': None
|
465
|
+
}
|
501
466
|
|
502
|
-
return self._render_settings(
|
467
|
+
return self._render_settings(settings)
|
503
468
|
|
504
469
|
def _get_plugin_configs(self, ptype, plugins):
|
505
470
|
|
@@ -554,7 +519,12 @@ class ConfigCLI(CLI):
|
|
554
519
|
# not all cases will be error
|
555
520
|
o = 'REQUIRED'
|
556
521
|
|
557
|
-
config_entries[finalname][setting] =
|
522
|
+
config_entries[finalname][setting] = {
|
523
|
+
'name': setting,
|
524
|
+
'value': v,
|
525
|
+
'origin': o,
|
526
|
+
'type': None
|
527
|
+
}
|
558
528
|
|
559
529
|
# pretty please!
|
560
530
|
results = self._render_settings(config_entries[finalname])
|
@@ -587,7 +557,12 @@ class ConfigCLI(CLI):
|
|
587
557
|
if v is None and o is None:
|
588
558
|
# not all cases will be error
|
589
559
|
o = 'REQUIRED'
|
590
|
-
server_config[setting] =
|
560
|
+
server_config[setting] = {
|
561
|
+
'name': setting,
|
562
|
+
'value': v,
|
563
|
+
'origin': o,
|
564
|
+
'type': None
|
565
|
+
}
|
591
566
|
if context.CLIARGS['format'] == 'display':
|
592
567
|
if not context.CLIARGS['only_changed'] or server_config:
|
593
568
|
equals = '=' * len(server)
|
@@ -599,9 +574,9 @@ class ConfigCLI(CLI):
|
|
599
574
|
return output
|
600
575
|
|
601
576
|
def execute_dump(self):
|
602
|
-
|
577
|
+
"""
|
603
578
|
Shows the current settings, merges ansible.cfg if specified
|
604
|
-
|
579
|
+
"""
|
605
580
|
output = []
|
606
581
|
if context.CLIARGS['type'] in ('base', 'all'):
|
607
582
|
# deal with base
|
@@ -617,7 +592,7 @@ class ConfigCLI(CLI):
|
|
617
592
|
for server_config in server_config_list:
|
618
593
|
server = list(server_config.keys())[0]
|
619
594
|
server_reduced_config = server_config.pop(server)
|
620
|
-
configs[server] = server_reduced_config
|
595
|
+
configs[server] = list(server_reduced_config.values())
|
621
596
|
output.append({'GALAXY_SERVERS': configs})
|
622
597
|
|
623
598
|
if context.CLIARGS['type'] == 'all':
|
@@ -644,7 +619,7 @@ class ConfigCLI(CLI):
|
|
644
619
|
if context.CLIARGS['format'] == 'yaml':
|
645
620
|
text = yaml_dump(output)
|
646
621
|
elif context.CLIARGS['format'] == 'json':
|
647
|
-
text =
|
622
|
+
text = _json.json_dumps_formatted(output)
|
648
623
|
|
649
624
|
self.pager(to_text(text, errors='surrogate_or_strict'))
|
650
625
|
|
ansible/cli/console.py
CHANGED
@@ -29,13 +29,14 @@ from ansible.plugins.list import list_plugins
|
|
29
29
|
from ansible.plugins.loader import module_loader, fragment_loader
|
30
30
|
from ansible.utils import plugin_docs
|
31
31
|
from ansible.utils.color import stringc
|
32
|
+
from ansible._internal._datatag._tags import TrustedAsTemplate
|
32
33
|
from ansible.utils.display import Display
|
33
34
|
|
34
35
|
display = Display()
|
35
36
|
|
36
37
|
|
37
38
|
class ConsoleCLI(CLI, cmd.Cmd):
|
38
|
-
|
39
|
+
"""
|
39
40
|
A REPL that allows for running ad-hoc tasks against a chosen inventory
|
40
41
|
from a nice shell with built-in tab completion (based on dominis'
|
41
42
|
``ansible-shell``).
|
@@ -62,7 +63,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
|
|
62
63
|
- ``help [command/module]``: display documentation for
|
63
64
|
the command or module
|
64
65
|
- ``exit``: exit ``ansible-console``
|
65
|
-
|
66
|
+
"""
|
66
67
|
|
67
68
|
name = 'ansible-console'
|
68
69
|
modules = [] # type: list[str] | None
|
@@ -72,6 +73,8 @@ class ConsoleCLI(CLI, cmd.Cmd):
|
|
72
73
|
# use specific to console, but fallback to highlight for backwards compatibility
|
73
74
|
NORMAL_PROMPT = C.COLOR_CONSOLE_PROMPT or C.COLOR_HIGHLIGHT
|
74
75
|
|
76
|
+
USES_CONNECTION = True
|
77
|
+
|
75
78
|
def __init__(self, args):
|
76
79
|
|
77
80
|
super(ConsoleCLI, self).__init__(args)
|
@@ -179,6 +182,8 @@ class ConsoleCLI(CLI, cmd.Cmd):
|
|
179
182
|
else:
|
180
183
|
module_args = ''
|
181
184
|
|
185
|
+
module_args = TrustedAsTemplate().tag(module_args)
|
186
|
+
|
182
187
|
if self.callback:
|
183
188
|
cb = self.callback
|
184
189
|
elif C.DEFAULT_LOAD_CALLBACK_PLUGINS and C.DEFAULT_STDOUT_CALLBACK != 'default':
|
@@ -237,11 +242,8 @@ class ConsoleCLI(CLI, cmd.Cmd):
|
|
237
242
|
except KeyboardInterrupt:
|
238
243
|
display.error('User interrupted execution')
|
239
244
|
return False
|
240
|
-
except Exception as
|
241
|
-
|
242
|
-
import traceback
|
243
|
-
display.v(traceback.format_exc())
|
244
|
-
display.error(to_text(e))
|
245
|
+
except Exception as ex:
|
246
|
+
display.error(ex)
|
245
247
|
return False
|
246
248
|
|
247
249
|
def emptyline(self):
|
@@ -579,7 +581,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
|
|
579
581
|
self.cmdloop()
|
580
582
|
|
581
583
|
def __getattr__(self, name):
|
582
|
-
|
584
|
+
""" handle not found to populate dynamically a module function if module matching name exists """
|
583
585
|
attr = None
|
584
586
|
|
585
587
|
if name.startswith('do_'):
|