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
@@ -29,6 +29,8 @@ DOCUMENTATION = '''
|
|
29
29
|
- The plugin does not cache results because external inventory scripts are responsible for their own caching.
|
30
30
|
- To write your own inventory script see (R(Developing dynamic inventory,developing_inventory) from the documentation site.
|
31
31
|
- To find the scripts that used to be part of the code release, go to U(https://github.com/ansible-community/contrib-scripts/).
|
32
|
+
- Since 2.19 using a directory as an inventory source will no longer ignore .ini files by default,
|
33
|
+
but you can still update the configuration to do so.
|
32
34
|
'''
|
33
35
|
|
34
36
|
EXAMPLES = r'''# fmt: code
|
@@ -151,148 +153,136 @@ EXAMPLES = r'''# fmt: code
|
|
151
153
|
'''
|
152
154
|
|
153
155
|
|
156
|
+
import json
|
154
157
|
import os
|
158
|
+
import shlex
|
155
159
|
import subprocess
|
160
|
+
import typing as t
|
156
161
|
|
157
|
-
from
|
158
|
-
|
159
|
-
from ansible.
|
160
|
-
from ansible.module_utils.
|
161
|
-
from ansible.
|
162
|
+
from ansible.errors import AnsibleError, AnsibleJSONParserError
|
163
|
+
from ansible.inventory.data import InventoryData
|
164
|
+
from ansible.module_utils.datatag import native_type_name
|
165
|
+
from ansible.module_utils.common.json import get_decoder
|
166
|
+
from ansible.parsing.dataloader import DataLoader
|
162
167
|
from ansible.plugins.inventory import BaseInventoryPlugin
|
168
|
+
from ansible._internal._datatag._tags import TrustedAsTemplate, Origin
|
163
169
|
from ansible.utils.display import Display
|
170
|
+
from ansible._internal._json._profiles import _legacy, _inventory_legacy
|
164
171
|
|
165
172
|
display = Display()
|
166
173
|
|
167
174
|
|
168
175
|
class InventoryModule(BaseInventoryPlugin):
|
169
|
-
|
176
|
+
"""Host inventory parser for ansible using external inventory scripts."""
|
170
177
|
|
171
178
|
NAME = 'script'
|
172
179
|
|
173
|
-
def __init__(self):
|
174
|
-
|
180
|
+
def __init__(self) -> None:
|
175
181
|
super(InventoryModule, self).__init__()
|
176
182
|
|
177
|
-
self._hosts = set()
|
178
|
-
|
179
|
-
def verify_file(self, path):
|
180
|
-
''' Verify if file is usable by this plugin, base does minimal accessibility check '''
|
181
|
-
|
182
|
-
valid = super(InventoryModule, self).verify_file(path)
|
183
|
-
|
184
|
-
if valid:
|
185
|
-
# not only accessible, file must be executable and/or have shebang
|
186
|
-
shebang_present = False
|
187
|
-
try:
|
188
|
-
with open(path, 'rb') as inv_file:
|
189
|
-
initial_chars = inv_file.read(2)
|
190
|
-
if initial_chars.startswith(b'#!'):
|
191
|
-
shebang_present = True
|
192
|
-
except Exception:
|
193
|
-
pass
|
183
|
+
self._hosts: set[str] = set()
|
194
184
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
return valid
|
199
|
-
|
200
|
-
def parse(self, inventory, loader, path, cache=None):
|
185
|
+
def verify_file(self, path: str) -> bool:
|
186
|
+
return super(InventoryModule, self).verify_file(path) and os.access(path, os.X_OK)
|
201
187
|
|
188
|
+
def parse(self, inventory: InventoryData, loader: DataLoader, path: str, cache: bool = False) -> None:
|
202
189
|
super(InventoryModule, self).parse(inventory, loader, path)
|
203
|
-
self.set_options()
|
204
190
|
|
205
|
-
|
206
|
-
# path information but happen to be in the current working
|
207
|
-
# directory when '.' is not in PATH.
|
208
|
-
cmd = [path, "--list"]
|
209
|
-
|
210
|
-
try:
|
211
|
-
try:
|
212
|
-
sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
213
|
-
except OSError as e:
|
214
|
-
raise AnsibleParserError("problem running %s (%s)" % (' '.join(cmd), to_native(e)))
|
215
|
-
(stdout, stderr) = sp.communicate()
|
191
|
+
self.set_options()
|
216
192
|
|
217
|
-
|
218
|
-
err = to_native(stderr or "")
|
193
|
+
origin = Origin(description=f'<inventory script output from {path!r}>')
|
219
194
|
|
220
|
-
|
221
|
-
err += '\n'
|
195
|
+
data, stderr, stderr_help_text = run_command(path, ['--list'], origin)
|
222
196
|
|
223
|
-
|
224
|
-
|
197
|
+
try:
|
198
|
+
profile_name = detect_profile_name(data)
|
199
|
+
decoder = get_decoder(profile_name)
|
200
|
+
except Exception as ex:
|
201
|
+
raise AnsibleError(
|
202
|
+
message="Unable to get JSON decoder for inventory script result.",
|
203
|
+
help_text=stderr_help_text,
|
204
|
+
# obj will be added by inventory manager
|
205
|
+
) from ex
|
225
206
|
|
226
|
-
|
207
|
+
try:
|
227
208
|
try:
|
228
|
-
|
229
|
-
except Exception as
|
230
|
-
|
209
|
+
processed = json.loads(data, cls=decoder)
|
210
|
+
except Exception as json_ex:
|
211
|
+
AnsibleJSONParserError.handle_exception(json_ex, origin)
|
212
|
+
except Exception as ex:
|
213
|
+
raise AnsibleError(
|
214
|
+
message="Inventory script result could not be parsed as JSON.",
|
215
|
+
help_text=stderr_help_text,
|
216
|
+
# obj will be added by inventory manager
|
217
|
+
) from ex
|
218
|
+
|
219
|
+
# if no other errors happened, and you want to force displaying stderr, do so now
|
220
|
+
if stderr and self.get_option('always_show_stderr'):
|
221
|
+
self.display.error(msg=stderr)
|
222
|
+
|
223
|
+
data_from_meta: dict | None = None
|
224
|
+
|
225
|
+
# A "_meta" subelement may contain a variable "hostvars" which contains a hash for each host
|
226
|
+
# if this "hostvars" exists at all then do not call --host for each # host.
|
227
|
+
# This is for efficiency and scripts should still return data
|
228
|
+
# if called with --host for backwards compat with 1.2 and earlier.
|
229
|
+
for (group, gdata) in processed.items():
|
230
|
+
if group == '_meta':
|
231
|
+
data_from_meta = gdata.get('hostvars')
|
232
|
+
|
233
|
+
if not isinstance(data_from_meta, dict):
|
234
|
+
raise TypeError(f"Value contains '_meta.hostvars' which is {native_type_name(data_from_meta)!r} instead of {native_type_name(dict)!r}.")
|
235
|
+
else:
|
236
|
+
self._parse_group(group, gdata, origin)
|
237
|
+
|
238
|
+
if data_from_meta is None:
|
239
|
+
display.deprecated(
|
240
|
+
msg="Inventory scripts should always provide 'meta.hostvars'. "
|
241
|
+
"Host variables will be collected by running the inventory script with the '--host' option for each host.",
|
242
|
+
version='2.23',
|
243
|
+
obj=origin,
|
244
|
+
)
|
245
|
+
|
246
|
+
for host in self._hosts:
|
247
|
+
if data_from_meta is None:
|
248
|
+
got = self.get_host_variables(path, host, origin)
|
249
|
+
else:
|
250
|
+
got = data_from_meta.get(host, {})
|
231
251
|
|
232
|
-
|
233
|
-
processed = self.loader.load(data, json_only=True)
|
234
|
-
except Exception as e:
|
235
|
-
raise AnsibleError("failed to parse executable inventory script results from {0}: {1}\n{2}".format(path, to_native(e), err))
|
236
|
-
|
237
|
-
# if no other errors happened and you want to force displaying stderr, do so now
|
238
|
-
if stderr and self.get_option('always_show_stderr'):
|
239
|
-
self.display.error(msg=to_text(err))
|
240
|
-
|
241
|
-
if not isinstance(processed, Mapping):
|
242
|
-
raise AnsibleError("failed to parse executable inventory script results from {0}: needs to be a json dict\n{1}".format(path, err))
|
243
|
-
|
244
|
-
group = None
|
245
|
-
data_from_meta = None
|
246
|
-
|
247
|
-
# A "_meta" subelement may contain a variable "hostvars" which contains a hash for each host
|
248
|
-
# if this "hostvars" exists at all then do not call --host for each # host.
|
249
|
-
# This is for efficiency and scripts should still return data
|
250
|
-
# if called with --host for backwards compat with 1.2 and earlier.
|
251
|
-
for (group, gdata) in processed.items():
|
252
|
-
if group == '_meta':
|
253
|
-
if 'hostvars' in gdata:
|
254
|
-
data_from_meta = gdata['hostvars']
|
255
|
-
else:
|
256
|
-
self._parse_group(group, gdata)
|
257
|
-
|
258
|
-
for host in self._hosts:
|
259
|
-
got = {}
|
260
|
-
if data_from_meta is None:
|
261
|
-
got = self.get_host_variables(path, host)
|
262
|
-
else:
|
263
|
-
try:
|
264
|
-
got = data_from_meta.get(host, {})
|
265
|
-
except AttributeError as e:
|
266
|
-
raise AnsibleError("Improperly formatted host information for %s: %s" % (host, to_native(e)), orig_exc=e)
|
267
|
-
|
268
|
-
self._populate_host_vars([host], got)
|
269
|
-
|
270
|
-
except Exception as e:
|
271
|
-
raise AnsibleParserError(to_native(e))
|
272
|
-
|
273
|
-
def _parse_group(self, group, data):
|
252
|
+
self._populate_host_vars([host], got)
|
274
253
|
|
254
|
+
def _parse_group(self, group: str, data: t.Any, origin: Origin) -> None:
|
255
|
+
"""Normalize and ingest host/var information for the named group."""
|
275
256
|
group = self.inventory.add_group(group)
|
276
257
|
|
277
258
|
if not isinstance(data, dict):
|
278
259
|
data = {'hosts': data}
|
279
|
-
|
260
|
+
display.deprecated(
|
261
|
+
msg=f"Group {group!r} was converted to {native_type_name(dict)!r} from {native_type_name(data)!r}.",
|
262
|
+
version='2.23',
|
263
|
+
obj=origin,
|
264
|
+
)
|
280
265
|
elif not any(k in data for k in ('hosts', 'vars', 'children')):
|
281
266
|
data = {'hosts': [group], 'vars': data}
|
267
|
+
display.deprecated(
|
268
|
+
msg=f"Treating malformed group {group!r} as the sole host of that group. Variables provided in this manner cannot be templated.",
|
269
|
+
version='2.23',
|
270
|
+
obj=origin,
|
271
|
+
)
|
282
272
|
|
283
|
-
if 'hosts'
|
284
|
-
if not isinstance(
|
285
|
-
raise
|
273
|
+
if (data_hosts := data.get('hosts', ...)) is not ...:
|
274
|
+
if not isinstance(data_hosts, list):
|
275
|
+
raise TypeError(f"Value contains '{group}.hosts' which is {native_type_name(data_hosts)!r} instead of {native_type_name(list)!r}.")
|
286
276
|
|
287
|
-
for hostname in
|
277
|
+
for hostname in data_hosts:
|
288
278
|
self._hosts.add(hostname)
|
289
279
|
self.inventory.add_host(hostname, group)
|
290
280
|
|
291
|
-
if 'vars'
|
292
|
-
if not isinstance(
|
293
|
-
raise
|
281
|
+
if (data_vars := data.get('vars', ...)) is not ...:
|
282
|
+
if not isinstance(data_vars, dict):
|
283
|
+
raise TypeError(f"Value contains '{group}.vars' which is {native_type_name(data_vars)!r} instead of {native_type_name(dict)!r}.")
|
294
284
|
|
295
|
-
for k, v in
|
285
|
+
for k, v in data_vars.items():
|
296
286
|
self.inventory.set_variable(group, k, v)
|
297
287
|
|
298
288
|
if group != '_meta' and isinstance(data, dict) and 'children' in data:
|
@@ -300,22 +290,102 @@ class InventoryModule(BaseInventoryPlugin):
|
|
300
290
|
child_name = self.inventory.add_group(child_name)
|
301
291
|
self.inventory.add_child(group, child_name)
|
302
292
|
|
303
|
-
|
304
|
-
|
293
|
+
@staticmethod
|
294
|
+
def get_host_variables(path: str, host: str, origin: Origin) -> dict:
|
295
|
+
"""Runs <script> --host <hostname>, to determine additional host variables."""
|
296
|
+
origin = origin.replace(description=f'{origin.description} for host {host!r}')
|
305
297
|
|
306
|
-
|
307
|
-
try:
|
308
|
-
sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
309
|
-
except OSError as e:
|
310
|
-
raise AnsibleError("problem running %s (%s)" % (' '.join(cmd), e))
|
311
|
-
(out, stderr) = sp.communicate()
|
298
|
+
data, stderr, stderr_help_text = run_command(path, ['--host', host], origin)
|
312
299
|
|
313
|
-
if
|
314
|
-
raise AnsibleError("Inventory script (%s) had an execution error: %s" % (path, to_native(stderr)))
|
315
|
-
|
316
|
-
if out.strip() == '':
|
300
|
+
if not data.strip():
|
317
301
|
return {}
|
302
|
+
|
318
303
|
try:
|
319
|
-
|
320
|
-
|
321
|
-
|
304
|
+
try:
|
305
|
+
# Use standard legacy trust inversion here.
|
306
|
+
# Unlike the normal inventory output, everything here is considered a variable and thus supports trust (and trust inversion).
|
307
|
+
processed = json.loads(data, cls=_legacy.Decoder)
|
308
|
+
except Exception as json_ex:
|
309
|
+
AnsibleJSONParserError.handle_exception(json_ex, origin)
|
310
|
+
except Exception as ex:
|
311
|
+
raise AnsibleError(
|
312
|
+
message=f"Inventory script result for host {host!r} could not be parsed as JSON.",
|
313
|
+
help_text=stderr_help_text,
|
314
|
+
# obj will be added by inventory manager
|
315
|
+
) from ex
|
316
|
+
|
317
|
+
return processed
|
318
|
+
|
319
|
+
|
320
|
+
def detect_profile_name(value: str) -> str:
|
321
|
+
"""
|
322
|
+
Detect (optional) JSON profile name from an inventory JSON document.
|
323
|
+
Defaults to `inventory_legacy`.
|
324
|
+
"""
|
325
|
+
try:
|
326
|
+
data = json.loads(value)
|
327
|
+
except Exception as ex:
|
328
|
+
raise ValueError('Value could not be parsed as JSON.') from ex
|
329
|
+
|
330
|
+
if not isinstance(data, dict):
|
331
|
+
raise TypeError(f'Value is {native_type_name(data)!r} instead of {native_type_name(dict)!r}.')
|
332
|
+
|
333
|
+
if (meta := data.get('_meta', ...)) is ...:
|
334
|
+
return _inventory_legacy.Decoder.profile_name
|
335
|
+
|
336
|
+
if not isinstance(meta, dict):
|
337
|
+
raise TypeError(f"Value contains '_meta' which is {native_type_name(meta)!r} instead of {native_type_name(dict)!r}.")
|
338
|
+
|
339
|
+
if (profile := meta.get('profile', ...)) is ...:
|
340
|
+
return _inventory_legacy.Decoder.profile_name
|
341
|
+
|
342
|
+
if not isinstance(profile, str):
|
343
|
+
raise TypeError(f"Value contains '_meta.profile' which is {native_type_name(profile)!r} instead of {native_type_name(str)!r}.")
|
344
|
+
|
345
|
+
if not profile.startswith('inventory_'):
|
346
|
+
raise ValueError(f"Non-inventory profile {profile!r} is not allowed.")
|
347
|
+
|
348
|
+
return profile
|
349
|
+
|
350
|
+
|
351
|
+
def run_command(path: str, options: list[str], origin: Origin) -> tuple[str, str, str]:
|
352
|
+
"""Run an inventory script, normalize and validate output."""
|
353
|
+
cmd = [path] + options
|
354
|
+
|
355
|
+
try:
|
356
|
+
sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
357
|
+
except OSError as ex:
|
358
|
+
raise AnsibleError(
|
359
|
+
message=f"Failed to execute inventory script command {shlex.join(cmd)!r}.",
|
360
|
+
# obj will be added by inventory manager
|
361
|
+
) from ex
|
362
|
+
|
363
|
+
stdout_bytes, stderr_bytes = sp.communicate()
|
364
|
+
|
365
|
+
stderr = stderr_bytes.decode(errors='surrogateescape')
|
366
|
+
|
367
|
+
if stderr and not stderr.endswith('\n'):
|
368
|
+
stderr += '\n'
|
369
|
+
|
370
|
+
# DTFIX-RELEASE: another use case for the "not quite help text, definitely not message" diagnostic output on errors
|
371
|
+
stderr_help_text = f'Standard error from inventory script:\n{stderr}' if stderr.strip() else None
|
372
|
+
|
373
|
+
if sp.returncode != 0:
|
374
|
+
raise AnsibleError(
|
375
|
+
message=f"Inventory script returned non-zero exit code {sp.returncode}.",
|
376
|
+
help_text=stderr_help_text,
|
377
|
+
# obj will be added by inventory manager
|
378
|
+
)
|
379
|
+
|
380
|
+
try:
|
381
|
+
data = stdout_bytes.decode()
|
382
|
+
except Exception as ex:
|
383
|
+
raise AnsibleError(
|
384
|
+
"Inventory script result contained characters that cannot be interpreted as UTF-8.",
|
385
|
+
help_text=stderr_help_text,
|
386
|
+
# obj will be added by inventory manager
|
387
|
+
) from ex
|
388
|
+
else:
|
389
|
+
data = TrustedAsTemplate().tag(origin.tag(data))
|
390
|
+
|
391
|
+
return data, stderr, stderr_help_text
|
@@ -3,19 +3,16 @@
|
|
3
3
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
-
DOCUMENTATION = r
|
6
|
+
DOCUMENTATION = r"""
|
7
7
|
name: toml
|
8
8
|
version_added: "2.8"
|
9
9
|
short_description: Uses a specific TOML file as an inventory source.
|
10
10
|
description:
|
11
11
|
- TOML based inventory format
|
12
12
|
- File MUST have a valid '.toml' file extension
|
13
|
-
|
14
|
-
- >
|
15
|
-
Requires one of the following python libraries: 'toml', 'tomli', or 'tomllib'
|
16
|
-
'''
|
13
|
+
"""
|
17
14
|
|
18
|
-
EXAMPLES = r
|
15
|
+
EXAMPLES = r"""# fmt: toml
|
19
16
|
# Example 1
|
20
17
|
[all.vars]
|
21
18
|
has_java = false
|
@@ -84,115 +81,27 @@ host4 = {}
|
|
84
81
|
|
85
82
|
[g2.hosts]
|
86
83
|
host4 = {}
|
87
|
-
|
84
|
+
"""
|
88
85
|
|
89
86
|
import os
|
90
|
-
import
|
87
|
+
import tomllib
|
91
88
|
|
92
89
|
from collections.abc import MutableMapping, MutableSequence
|
93
|
-
from functools import partial
|
94
90
|
|
95
|
-
from ansible.errors import AnsibleFileNotFound, AnsibleParserError
|
96
|
-
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
97
|
-
from ansible.module_utils.six import string_types
|
98
|
-
from ansible.parsing.yaml.objects import AnsibleSequence, AnsibleUnicode
|
91
|
+
from ansible.errors import AnsibleFileNotFound, AnsibleParserError
|
92
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
93
|
+
from ansible.module_utils.six import string_types
|
99
94
|
from ansible.plugins.inventory import BaseFileInventoryPlugin
|
100
95
|
from ansible.utils.display import Display
|
101
|
-
from ansible.utils.unsafe_proxy import AnsibleUnsafeBytes, AnsibleUnsafeText
|
102
|
-
|
103
|
-
HAS_TOML = False
|
104
|
-
try:
|
105
|
-
import toml
|
106
|
-
HAS_TOML = True
|
107
|
-
except ImportError:
|
108
|
-
pass
|
109
|
-
|
110
|
-
HAS_TOMLIW = False
|
111
|
-
try:
|
112
|
-
import tomli_w # type: ignore[import]
|
113
|
-
HAS_TOMLIW = True
|
114
|
-
except ImportError:
|
115
|
-
pass
|
116
|
-
|
117
|
-
HAS_TOMLLIB = False
|
118
|
-
try:
|
119
|
-
import tomllib # type: ignore[import]
|
120
|
-
HAS_TOMLLIB = True
|
121
|
-
except ImportError:
|
122
|
-
try:
|
123
|
-
import tomli as tomllib # type: ignore[no-redef]
|
124
|
-
HAS_TOMLLIB = True
|
125
|
-
except ImportError:
|
126
|
-
pass
|
127
96
|
|
128
97
|
display = Display()
|
129
98
|
|
130
99
|
|
131
|
-
# dumps
|
132
|
-
if HAS_TOML and hasattr(toml, 'TomlEncoder'):
|
133
|
-
# toml>=0.10.0
|
134
|
-
class AnsibleTomlEncoder(toml.TomlEncoder):
|
135
|
-
def __init__(self, *args, **kwargs):
|
136
|
-
super(AnsibleTomlEncoder, self).__init__(*args, **kwargs)
|
137
|
-
# Map our custom YAML object types to dump_funcs from ``toml``
|
138
|
-
self.dump_funcs.update({
|
139
|
-
AnsibleSequence: self.dump_funcs.get(list),
|
140
|
-
AnsibleUnicode: self.dump_funcs.get(str),
|
141
|
-
AnsibleUnsafeBytes: self.dump_funcs.get(str),
|
142
|
-
AnsibleUnsafeText: self.dump_funcs.get(str),
|
143
|
-
})
|
144
|
-
toml_dumps = partial(toml.dumps, encoder=AnsibleTomlEncoder()) # type: t.Callable[[t.Any], str]
|
145
|
-
else:
|
146
|
-
# toml<0.10.0
|
147
|
-
# tomli-w
|
148
|
-
def toml_dumps(data): # type: (t.Any) -> str
|
149
|
-
if HAS_TOML:
|
150
|
-
return toml.dumps(convert_yaml_objects_to_native(data))
|
151
|
-
elif HAS_TOMLIW:
|
152
|
-
return tomli_w.dumps(convert_yaml_objects_to_native(data))
|
153
|
-
raise AnsibleRuntimeError(
|
154
|
-
'The python "toml" or "tomli-w" library is required when using the TOML output format'
|
155
|
-
)
|
156
|
-
|
157
|
-
# loads
|
158
|
-
if HAS_TOML:
|
159
|
-
# prefer toml if installed, since it supports both encoding and decoding
|
160
|
-
toml_loads = toml.loads # type: ignore[assignment]
|
161
|
-
TOMLDecodeError = toml.TomlDecodeError # type: t.Any
|
162
|
-
elif HAS_TOMLLIB:
|
163
|
-
toml_loads = tomllib.loads # type: ignore[assignment]
|
164
|
-
TOMLDecodeError = tomllib.TOMLDecodeError # type: t.Any # type: ignore[no-redef]
|
165
|
-
|
166
|
-
|
167
|
-
def convert_yaml_objects_to_native(obj):
|
168
|
-
"""Older versions of the ``toml`` python library, and tomllib, don't have
|
169
|
-
a pluggable way to tell the encoder about custom types, so we need to
|
170
|
-
ensure objects that we pass are native types.
|
171
|
-
|
172
|
-
Used with:
|
173
|
-
- ``toml<0.10.0`` where ``toml.TomlEncoder`` is missing
|
174
|
-
- ``tomli`` or ``tomllib``
|
175
|
-
|
176
|
-
This function recurses an object and ensures we cast any of the types from
|
177
|
-
``ansible.parsing.yaml.objects`` into their native types, effectively cleansing
|
178
|
-
the data before we hand it over to the toml library.
|
179
|
-
|
180
|
-
This function doesn't directly check for the types from ``ansible.parsing.yaml.objects``
|
181
|
-
but instead checks for the types those objects inherit from, to offer more flexibility.
|
182
|
-
"""
|
183
|
-
if isinstance(obj, dict):
|
184
|
-
return dict((k, convert_yaml_objects_to_native(v)) for k, v in obj.items())
|
185
|
-
elif isinstance(obj, list):
|
186
|
-
return [convert_yaml_objects_to_native(v) for v in obj]
|
187
|
-
elif isinstance(obj, text_type):
|
188
|
-
return text_type(obj)
|
189
|
-
else:
|
190
|
-
return obj
|
191
|
-
|
192
|
-
|
193
100
|
class InventoryModule(BaseFileInventoryPlugin):
|
194
101
|
NAME = 'toml'
|
195
102
|
|
103
|
+
trusted_by_default = True # we need the inventory system to mark trust for us, since we're not manually traversing var assignments
|
104
|
+
|
196
105
|
def _parse_group(self, group, group_data):
|
197
106
|
if group_data is not None and not isinstance(group_data, MutableMapping):
|
198
107
|
self.display.warning("Skipping '%s' as this is not a valid group definition" % group)
|
@@ -246,33 +155,14 @@ class InventoryModule(BaseFileInventoryPlugin):
|
|
246
155
|
raise AnsibleFileNotFound("Unable to retrieve file contents", file_name=file_name)
|
247
156
|
|
248
157
|
try:
|
249
|
-
(
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
orig_exc=e
|
255
|
-
)
|
256
|
-
except (IOError, OSError) as e:
|
257
|
-
raise AnsibleParserError(
|
258
|
-
"An error occurred while trying to read the file '%s': %s" % (file_name, to_native(e)),
|
259
|
-
orig_exc=e
|
260
|
-
)
|
261
|
-
except Exception as e:
|
262
|
-
raise AnsibleParserError(
|
263
|
-
"An unexpected error occurred while parsing the file '%s': %s" % (file_name, to_native(e)),
|
264
|
-
orig_exc=e
|
265
|
-
)
|
158
|
+
return tomllib.loads(self.loader.get_text_file_contents(file_name))
|
159
|
+
except tomllib.TOMLDecodeError as ex:
|
160
|
+
raise AnsibleParserError(f'TOML file {file_name!r} is invalid.') from ex
|
161
|
+
except Exception as ex:
|
162
|
+
raise AnsibleParserError(f'An error occurred while parsing the file {file_name!r}.') from ex
|
266
163
|
|
267
164
|
def parse(self, inventory, loader, path, cache=True):
|
268
|
-
|
269
|
-
if not HAS_TOMLLIB and not HAS_TOML:
|
270
|
-
# tomllib works here too, but we don't call it out in the error,
|
271
|
-
# since you either have it or not as part of cpython stdlib >= 3.11
|
272
|
-
raise AnsibleParserError(
|
273
|
-
'The TOML inventory plugin requires the python "toml", or "tomli" library'
|
274
|
-
)
|
275
|
-
|
165
|
+
""" parses the inventory file """
|
276
166
|
super(InventoryModule, self).parse(inventory, loader, path)
|
277
167
|
self.set_options()
|
278
168
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
-
DOCUMENTATION =
|
6
|
+
DOCUMENTATION = """
|
7
7
|
name: yaml
|
8
8
|
version_added: "2.4"
|
9
9
|
short_description: Uses a specific YAML file as an inventory source.
|
@@ -31,8 +31,8 @@ DOCUMENTATION = '''
|
|
31
31
|
- section: inventory_plugin_yaml
|
32
32
|
key: yaml_valid_extensions
|
33
33
|
|
34
|
-
|
35
|
-
EXAMPLES =
|
34
|
+
"""
|
35
|
+
EXAMPLES = """
|
36
36
|
all: # keys must be unique, i.e. only one 'hosts' per group
|
37
37
|
hosts:
|
38
38
|
test1:
|
@@ -63,7 +63,7 @@ all: # keys must be unique, i.e. only one 'hosts' per group
|
|
63
63
|
test1 # same host as above, additional group membership
|
64
64
|
vars:
|
65
65
|
group_last_var: value
|
66
|
-
|
66
|
+
"""
|
67
67
|
|
68
68
|
import os
|
69
69
|
|
@@ -81,6 +81,8 @@ class InventoryModule(BaseFileInventoryPlugin):
|
|
81
81
|
|
82
82
|
NAME = 'yaml'
|
83
83
|
|
84
|
+
# implicit trust behavior is already added by the YAML parser invoked by the loader
|
85
|
+
|
84
86
|
def __init__(self):
|
85
87
|
|
86
88
|
super(InventoryModule, self).__init__()
|
@@ -95,13 +97,13 @@ class InventoryModule(BaseFileInventoryPlugin):
|
|
95
97
|
return valid
|
96
98
|
|
97
99
|
def parse(self, inventory, loader, path, cache=True):
|
98
|
-
|
100
|
+
""" parses the inventory file """
|
99
101
|
|
100
102
|
super(InventoryModule, self).parse(inventory, loader, path)
|
101
103
|
self.set_options()
|
102
104
|
|
103
105
|
try:
|
104
|
-
data = self.loader.load_from_file(path, cache='none')
|
106
|
+
data = self.loader.load_from_file(path, cache='none', trusted_as_template=True)
|
105
107
|
except Exception as e:
|
106
108
|
raise AnsibleParserError(e)
|
107
109
|
|
@@ -170,9 +172,9 @@ class InventoryModule(BaseFileInventoryPlugin):
|
|
170
172
|
return group
|
171
173
|
|
172
174
|
def _parse_host(self, host_pattern):
|
173
|
-
|
175
|
+
"""
|
174
176
|
Each host key can be a pattern, try to process it and add variables as needed
|
175
|
-
|
177
|
+
"""
|
176
178
|
try:
|
177
179
|
(hostnames, port) = self._expand_hostpattern(host_pattern)
|
178
180
|
except TypeError:
|
ansible/plugins/list.py
CHANGED
@@ -124,7 +124,7 @@ def list_collection_plugins(ptype, collections, search_paths=None):
|
|
124
124
|
try:
|
125
125
|
ploader = getattr(loader, '{0}_loader'.format(ptype))
|
126
126
|
except AttributeError:
|
127
|
-
raise AnsibleError(
|
127
|
+
raise AnsibleError(f"Cannot list plugins, incorrect plugin type {ptype!r} supplied.") from None
|
128
128
|
|
129
129
|
# get plugins for each collection
|
130
130
|
for collection in collections.keys():
|
@@ -191,8 +191,8 @@ def list_plugins(ptype, collections=None, search_paths=None):
|
|
191
191
|
else:
|
192
192
|
try:
|
193
193
|
plugin_collections[collection] = to_bytes(_get_collection_path(collection))
|
194
|
-
except ValueError as
|
195
|
-
raise AnsibleError("Cannot use supplied collection {
|
194
|
+
except ValueError as ex:
|
195
|
+
raise AnsibleError(f"Cannot use supplied collection {collection!r}.") from ex
|
196
196
|
|
197
197
|
if plugin_collections:
|
198
198
|
plugins.update(list_collection_plugins(ptype, plugin_collections))
|