ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz/__init__.py +0 -0
- ansible/_internal/_ansiballz/_builder.py +101 -0
- ansible/_internal/_ansiballz/_wrapper.py +262 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_alarm_timeout.py +66 -0
- ansible/_internal/_errors/_captured.py +123 -0
- ansible/_internal/_errors/_error_factory.py +89 -0
- ansible/_internal/_errors/_error_utils.py +240 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_task_timeout.py +28 -0
- ansible/_internal/_event_formatting.py +127 -0
- ansible/_internal/_json/__init__.py +214 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +189 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_ssh/__init__.py +0 -0
- ansible/_internal/_ssh/_agent_launch.py +91 -0
- ansible/_internal/_ssh/_ssh_agent.py +619 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +12 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +592 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1106 -0
- ansible/_internal/_templating/_jinja_common.py +323 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +375 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_template_vars.py +72 -0
- ansible/_internal/_templating/_transform.py +70 -0
- ansible/_internal/_templating/_utils.py +108 -0
- ansible/_internal/_testing.py +26 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +70 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +93 -104
- ansible/cli/_ssh_askpass.py +54 -0
- ansible/cli/adhoc.py +20 -10
- ansible/cli/arguments/option_helpers.py +163 -10
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +13 -11
- ansible/cli/doc.py +134 -77
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -28
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +6 -3
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/compat/importlib_resources.py +9 -12
- ansible/config/base.yml +218 -133
- ansible/config/manager.py +220 -159
- ansible/constants.py +2 -65
- ansible/errors/__init__.py +350 -256
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +480 -514
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +204 -153
- ansible/executor/powershell/become_wrapper.ps1 +107 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
- ansible/executor/powershell/exec_wrapper.ps1 +675 -196
- ansible/executor/powershell/module_manifest.py +469 -265
- ansible/executor/powershell/module_wrapper.ps1 +195 -186
- ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
- ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +139 -149
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +270 -297
- ansible/executor/task_queue_manager.py +135 -137
- ansible/executor/task_result.py +182 -79
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +26 -25
- ansible/galaxy/collection/__init__.py +6 -14
- ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +4 -4
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +6 -10
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +50 -73
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +37 -54
- ansible/inventory/manager.py +79 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
- ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
- ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
- ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +961 -0
- ansible/module_utils/_internal/_datatag/_tags.py +16 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_deprecator.py +157 -0
- ansible/module_utils/_internal/_errors.py +101 -0
- ansible/module_utils/_internal/_event_utils.py +61 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
- ansible/module_utils/_internal/_messages.py +130 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_info.py +38 -0
- ansible/module_utils/_internal/_stack.py +22 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_text_utils.py +6 -0
- ansible/module_utils/_internal/_traceback.py +92 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +303 -202
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/collections.py +7 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -3
- ansible/module_utils/common/respawn.py +11 -33
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +143 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +10 -13
- ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +49 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +2 -2
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +5 -5
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +2 -3
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/sysctl.py +4 -6
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +3 -3
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +27 -13
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +2 -3
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/linux.py +3 -3
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +7 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/service.py +21 -31
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +64 -35
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +69 -49
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +32 -51
- ansible/modules/assemble.py +16 -14
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +24 -24
- ansible/modules/async_wrapper.py +20 -25
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +13 -20
- ansible/modules/copy.py +60 -147
- ansible/modules/cron.py +24 -21
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +13 -15
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +184 -144
- ansible/modules/find.py +22 -20
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +77 -54
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +38 -38
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +15 -32
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +22 -24
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +10 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +21 -26
- ansible/modules/raw.py +6 -6
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +10 -14
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +10 -17
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +16 -19
- ansible/modules/stat.py +15 -31
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +7 -7
- ansible/modules/systemd_service.py +7 -7
- ansible/modules/sysvinit.py +9 -9
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +38 -17
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +45 -32
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +70 -60
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +10 -9
- ansible/parsing/ajson.py +17 -37
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +62 -60
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +327 -99
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +187 -134
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +32 -26
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +14 -17
- ansible/playbook/playbook_include.py +27 -62
- ansible/playbook/role/__init__.py +64 -49
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +28 -12
- ansible/playbook/task.py +192 -121
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +58 -26
- ansible/plugins/action/__init__.py +188 -186
- ansible/plugins/action/add_host.py +2 -2
- ansible/plugins/action/assemble.py +11 -18
- ansible/plugins/action/assert.py +55 -67
- ansible/plugins/action/async_status.py +7 -2
- ansible/plugins/action/copy.py +14 -17
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +7 -8
- ansible/plugins/action/gather_facts.py +13 -14
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +8 -14
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +27 -38
- ansible/plugins/action/service.py +9 -18
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +47 -67
- ansible/plugins/action/unarchive.py +6 -16
- ansible/plugins/action/uri.py +9 -20
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +52 -63
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +294 -201
- ansible/plugins/callback/default.py +99 -95
- ansible/plugins/callback/junit.py +44 -43
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +34 -21
- ansible/plugins/callback/tree.py +27 -16
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +156 -60
- ansible/plugins/connection/paramiko_ssh.py +34 -24
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +326 -86
- ansible/plugins/connection/winrm.py +62 -141
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +8 -4
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +245 -120
- ansible/plugins/filter/encryption.py +42 -34
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/pow.yml +1 -1
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/strftime.yml +3 -3
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +107 -86
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +190 -120
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +72 -19
- ansible/plugins/loader.py +383 -198
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +19 -73
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +87 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +47 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +4 -10
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +58 -4
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +106 -31
- ansible/plugins/shell/sh.py +13 -7
- ansible/plugins/strategy/__init__.py +168 -193
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +75 -35
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/finished.yml +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +5 -8
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +353 -943
- ansible/utils/__init__.py +0 -18
- ansible/utils/collection_loader/__init__.py +54 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +82 -96
- ansible/utils/collection_loader/_collection_meta.py +15 -8
- ansible/utils/display.py +485 -73
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/galaxy.py +2 -2
- ansible/utils/hashing.py +8 -10
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +10 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +10 -12
- ansible/utils/plugin_docs.py +16 -14
- ansible/utils/py3compat.py +2 -7
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +6 -2
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +55 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +220 -285
- ansible/vars/plugins.py +4 -4
- ansible/vars/reserved.py +13 -12
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
- ansible_core-2.19.0.dist-info/RECORD +1097 -0
- ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +6 -0
- ansible_test/_internal/ansible_util.py +3 -1
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -5
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +52 -5
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +3 -2
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +22 -5
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +8 -2
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +19 -2
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +25 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +44 -4
- ansible_test/_internal/commands/units/__init__.py +5 -1
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +23 -13
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/debugging.py +166 -0
- ansible_test/_internal/delegation.py +22 -13
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +260 -16
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +39 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +95 -4
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/processes.py +80 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +11 -4
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +28 -0
- ansible_test/_internal/ssh.py +2 -5
- ansible_test/_internal/target.py +9 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +3 -1
- ansible_test/_internal/timeout.py +2 -1
- ansible_test/_internal/util.py +41 -12
- ansible_test/_internal/util_common.py +18 -5
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/injector/python.py +8 -0
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +38 -36
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
|
@@ -17,24 +17,30 @@
|
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
|
+
import functools
|
|
20
21
|
import hashlib
|
|
21
22
|
import os
|
|
22
23
|
import string
|
|
24
|
+
import typing as t
|
|
23
25
|
|
|
24
26
|
from collections.abc import Mapping
|
|
25
27
|
|
|
26
|
-
from ansible
|
|
28
|
+
from ansible import template as _template
|
|
29
|
+
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleValueOmittedError
|
|
27
30
|
from ansible.inventory.group import to_safe_group_name as original_safe
|
|
31
|
+
from ansible.module_utils._internal import _plugin_info
|
|
28
32
|
from ansible.parsing.utils.addresses import parse_address
|
|
29
|
-
from ansible.
|
|
30
|
-
from ansible.plugins
|
|
33
|
+
from ansible.parsing.dataloader import DataLoader
|
|
34
|
+
from ansible.plugins import AnsiblePlugin, _ConfigurablePlugin
|
|
35
|
+
from ansible.plugins.cache import CachePluginAdjudicator
|
|
31
36
|
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
|
32
|
-
from ansible.module_utils.parsing.convert_bool import boolean
|
|
33
37
|
from ansible.module_utils.six import string_types
|
|
34
|
-
from ansible.template import Templar
|
|
35
38
|
from ansible.utils.display import Display
|
|
36
39
|
from ansible.utils.vars import combine_vars, load_extra_vars
|
|
37
40
|
|
|
41
|
+
if t.TYPE_CHECKING:
|
|
42
|
+
from ansible.inventory.data import InventoryData
|
|
43
|
+
|
|
38
44
|
display = Display()
|
|
39
45
|
|
|
40
46
|
|
|
@@ -45,17 +51,17 @@ def to_safe_group_name(name):
|
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
def detect_range(line=None):
|
|
48
|
-
|
|
54
|
+
"""
|
|
49
55
|
A helper function that checks a given host line to see if it contains
|
|
50
56
|
a range pattern described in the docstring above.
|
|
51
57
|
|
|
52
58
|
Returns True if the given line contains a pattern, else False.
|
|
53
|
-
|
|
59
|
+
"""
|
|
54
60
|
return '[' in line
|
|
55
61
|
|
|
56
62
|
|
|
57
63
|
def expand_hostname_range(line=None):
|
|
58
|
-
|
|
64
|
+
"""
|
|
59
65
|
A helper function that expands a given line that contains a pattern
|
|
60
66
|
specified in top docstring, and returns a list that consists of the
|
|
61
67
|
expanded version.
|
|
@@ -65,7 +71,7 @@ def expand_hostname_range(line=None):
|
|
|
65
71
|
string splitting.
|
|
66
72
|
|
|
67
73
|
References: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#hosts-and-groups
|
|
68
|
-
|
|
74
|
+
"""
|
|
69
75
|
all_hosts = []
|
|
70
76
|
if line:
|
|
71
77
|
# A hostname such as db[1:6]-node is considered to consists
|
|
@@ -127,8 +133,11 @@ def expand_hostname_range(line=None):
|
|
|
127
133
|
|
|
128
134
|
|
|
129
135
|
def get_cache_plugin(plugin_name, **kwargs):
|
|
136
|
+
if not plugin_name:
|
|
137
|
+
raise AnsibleError("A cache plugin must be configured to use inventory caching.")
|
|
138
|
+
|
|
130
139
|
try:
|
|
131
|
-
cache =
|
|
140
|
+
cache = CachePluginAdjudicator(plugin_name, **kwargs)
|
|
132
141
|
except AnsibleError as e:
|
|
133
142
|
if 'fact_caching_connection' in to_native(e):
|
|
134
143
|
raise AnsibleError("error, '%s' inventory cache plugin requires the one of the following to be set "
|
|
@@ -136,17 +145,22 @@ def get_cache_plugin(plugin_name, **kwargs):
|
|
|
136
145
|
"[inventory]: cache_connection;\nEnvironment:\nANSIBLE_INVENTORY_CACHE_CONNECTION,\n"
|
|
137
146
|
"ANSIBLE_CACHE_PLUGIN_CONNECTION." % plugin_name)
|
|
138
147
|
else:
|
|
139
|
-
raise
|
|
148
|
+
raise
|
|
140
149
|
|
|
141
|
-
if
|
|
150
|
+
if cache._plugin.ansible_name != 'ansible.builtin.memory' and kwargs and not getattr(cache._plugin, '_options', None):
|
|
142
151
|
raise AnsibleError('Unable to use cache plugin {0} for inventory. Cache options were provided but may not reconcile '
|
|
143
152
|
'correctly unless set via set_options. Refer to the porting guide if the plugin derives user settings '
|
|
144
153
|
'from ansible.constants.'.format(plugin_name))
|
|
145
154
|
return cache
|
|
146
155
|
|
|
147
156
|
|
|
148
|
-
class
|
|
149
|
-
"""
|
|
157
|
+
class _BaseInventoryPlugin(AnsiblePlugin):
|
|
158
|
+
"""
|
|
159
|
+
Internal base implementation for inventory plugins.
|
|
160
|
+
|
|
161
|
+
Do not inherit from this directly, use one of its public subclasses instead.
|
|
162
|
+
Used to introduce an extra layer in the class hierarchy to allow Constructed to subclass this while remaining a mixin for existing inventory plugins.
|
|
163
|
+
"""
|
|
150
164
|
|
|
151
165
|
TYPE = 'generator'
|
|
152
166
|
|
|
@@ -156,17 +170,27 @@ class BaseInventoryPlugin(AnsiblePlugin):
|
|
|
156
170
|
# it by default.
|
|
157
171
|
_sanitize_group_name = staticmethod(to_safe_group_name)
|
|
158
172
|
|
|
159
|
-
def __init__(self):
|
|
173
|
+
def __init__(self) -> None:
|
|
160
174
|
|
|
161
|
-
super(
|
|
175
|
+
super().__init__()
|
|
162
176
|
|
|
163
177
|
self._options = {}
|
|
164
|
-
self.inventory = None
|
|
165
178
|
self.display = display
|
|
166
|
-
self._vars = {}
|
|
167
179
|
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
# These attributes are set by the parse() method on this (base) class.
|
|
181
|
+
self.loader: DataLoader | None = None
|
|
182
|
+
self.inventory: InventoryData | None = None
|
|
183
|
+
self._vars: dict[str, t.Any] | None = None
|
|
184
|
+
|
|
185
|
+
trusted_by_default: bool = False
|
|
186
|
+
"""Inventory plugins that only source templates from trusted sources can set this True to have trust automatically applied to all templates."""
|
|
187
|
+
|
|
188
|
+
@functools.cached_property
|
|
189
|
+
def templar(self) -> _template.Templar:
|
|
190
|
+
return _template.Templar(loader=self.loader)
|
|
191
|
+
|
|
192
|
+
def parse(self, inventory: InventoryData, loader: DataLoader, path: str, cache: bool = True) -> None:
|
|
193
|
+
""" Populates inventory from the given data. Raises an error on any parse failure
|
|
170
194
|
:arg inventory: a copy of the previously accumulated inventory data,
|
|
171
195
|
to be updated with any new data this plugin provides.
|
|
172
196
|
The inventory can be empty if no other source/plugin ran successfully.
|
|
@@ -177,20 +201,18 @@ class BaseInventoryPlugin(AnsiblePlugin):
|
|
|
177
201
|
but it can also be a raw string for this plugin to consume
|
|
178
202
|
:arg cache: a boolean that indicates if the plugin should use the cache or not
|
|
179
203
|
you can ignore if this plugin does not implement caching.
|
|
180
|
-
|
|
181
|
-
|
|
204
|
+
"""
|
|
182
205
|
self.loader = loader
|
|
183
206
|
self.inventory = inventory
|
|
184
|
-
self.templar = Templar(loader=loader)
|
|
185
207
|
self._vars = load_extra_vars(loader)
|
|
186
208
|
|
|
187
209
|
def verify_file(self, path):
|
|
188
|
-
|
|
210
|
+
""" Verify if file is usable by this plugin, base does minimal accessibility check
|
|
189
211
|
:arg path: a string that was passed as an inventory source,
|
|
190
212
|
it normally is a path to a config file, but this is not a requirement,
|
|
191
213
|
it can also be parsed itself as the inventory data to process.
|
|
192
214
|
So only call this base class if you expect it to be a file.
|
|
193
|
-
|
|
215
|
+
"""
|
|
194
216
|
|
|
195
217
|
valid = False
|
|
196
218
|
b_path = to_bytes(path, errors='surrogate_or_strict')
|
|
@@ -210,15 +232,14 @@ class BaseInventoryPlugin(AnsiblePlugin):
|
|
|
210
232
|
self.inventory.set_variable(host, k, variables[k])
|
|
211
233
|
|
|
212
234
|
def _read_config_data(self, path):
|
|
213
|
-
|
|
235
|
+
""" validate config and set options as appropriate
|
|
214
236
|
:arg path: path to common yaml format config file for this plugin
|
|
215
|
-
|
|
237
|
+
"""
|
|
216
238
|
|
|
217
|
-
config = {}
|
|
218
239
|
try:
|
|
219
240
|
# avoid loader cache so meta: refresh_inventory can pick up config changes
|
|
220
241
|
# if we read more than once, fs cache should be good enough
|
|
221
|
-
config = self.loader.load_from_file(path, cache='none')
|
|
242
|
+
config = self.loader.load_from_file(path, cache='none', trusted_as_template=True)
|
|
222
243
|
except Exception as e:
|
|
223
244
|
raise AnsibleParserError(to_native(e))
|
|
224
245
|
|
|
@@ -244,20 +265,20 @@ class BaseInventoryPlugin(AnsiblePlugin):
|
|
|
244
265
|
return config
|
|
245
266
|
|
|
246
267
|
def _consume_options(self, data):
|
|
247
|
-
|
|
268
|
+
""" update existing options from alternate configuration sources not normally used by Ansible.
|
|
248
269
|
Many API libraries already have existing configuration sources, this allows plugin author to leverage them.
|
|
249
270
|
:arg data: key/value pairs that correspond to configuration options for this plugin
|
|
250
|
-
|
|
271
|
+
"""
|
|
251
272
|
|
|
252
273
|
for k in self._options:
|
|
253
274
|
if k in data:
|
|
254
275
|
self._options[k] = data.pop(k)
|
|
255
276
|
|
|
256
277
|
def _expand_hostpattern(self, hostpattern):
|
|
257
|
-
|
|
278
|
+
"""
|
|
258
279
|
Takes a single host pattern and returns a list of hostnames and an
|
|
259
280
|
optional port number that applies to all of them.
|
|
260
|
-
|
|
281
|
+
"""
|
|
261
282
|
# Can the given hostpattern be parsed as a host with an optional port
|
|
262
283
|
# specification?
|
|
263
284
|
|
|
@@ -279,7 +300,11 @@ class BaseInventoryPlugin(AnsiblePlugin):
|
|
|
279
300
|
return (hostnames, port)
|
|
280
301
|
|
|
281
302
|
|
|
282
|
-
class
|
|
303
|
+
class BaseInventoryPlugin(_BaseInventoryPlugin):
|
|
304
|
+
""" Parses an Inventory Source """
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class BaseFileInventoryPlugin(_BaseInventoryPlugin):
|
|
283
308
|
""" Parses a File based Inventory Source"""
|
|
284
309
|
|
|
285
310
|
TYPE = 'storage'
|
|
@@ -289,51 +314,43 @@ class BaseFileInventoryPlugin(BaseInventoryPlugin):
|
|
|
289
314
|
super(BaseFileInventoryPlugin, self).__init__()
|
|
290
315
|
|
|
291
316
|
|
|
292
|
-
class Cacheable(
|
|
317
|
+
class Cacheable(_plugin_info.HasPluginInfo, _ConfigurablePlugin):
|
|
318
|
+
"""Mixin for inventory plugins which support caching."""
|
|
293
319
|
|
|
294
|
-
_cache
|
|
320
|
+
_cache: CachePluginAdjudicator
|
|
295
321
|
|
|
296
322
|
@property
|
|
297
|
-
def cache(self):
|
|
323
|
+
def cache(self) -> CachePluginAdjudicator:
|
|
298
324
|
return self._cache
|
|
299
325
|
|
|
300
|
-
def load_cache_plugin(self):
|
|
326
|
+
def load_cache_plugin(self) -> None:
|
|
301
327
|
plugin_name = self.get_option('cache_plugin')
|
|
302
328
|
cache_option_keys = [('_uri', 'cache_connection'), ('_timeout', 'cache_timeout'), ('_prefix', 'cache_prefix')]
|
|
303
329
|
cache_options = dict((opt[0], self.get_option(opt[1])) for opt in cache_option_keys if self.get_option(opt[1]) is not None)
|
|
304
330
|
self._cache = get_cache_plugin(plugin_name, **cache_options)
|
|
305
331
|
|
|
306
|
-
def get_cache_key(self, path):
|
|
307
|
-
return
|
|
332
|
+
def get_cache_key(self, path: str) -> str:
|
|
333
|
+
return f'{self.ansible_name}_{self._get_cache_prefix(path)}'
|
|
308
334
|
|
|
309
|
-
def _get_cache_prefix(self, path):
|
|
310
|
-
|
|
335
|
+
def _get_cache_prefix(self, path: str) -> str:
|
|
336
|
+
"""Return a predictable unique key based on the given path."""
|
|
337
|
+
return 'k' + hashlib.sha256(f'{self.ansible_name}{path}'.encode(), usedforsecurity=False).hexdigest()[:6]
|
|
311
338
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
d1 = m.hexdigest()
|
|
339
|
+
def clear_cache(self) -> None:
|
|
340
|
+
self._cache.clear()
|
|
315
341
|
|
|
316
|
-
|
|
317
|
-
n.update(to_bytes(path, errors='surrogate_or_strict'))
|
|
318
|
-
d2 = n.hexdigest()
|
|
319
|
-
|
|
320
|
-
return 's_'.join([d1[:5], d2[:5]])
|
|
321
|
-
|
|
322
|
-
def clear_cache(self):
|
|
323
|
-
self._cache.flush()
|
|
324
|
-
|
|
325
|
-
def update_cache_if_changed(self):
|
|
342
|
+
def update_cache_if_changed(self) -> None:
|
|
326
343
|
self._cache.update_cache_if_changed()
|
|
327
344
|
|
|
328
|
-
def set_cache_plugin(self):
|
|
345
|
+
def set_cache_plugin(self) -> None:
|
|
329
346
|
self._cache.set_cache()
|
|
330
347
|
|
|
331
348
|
|
|
332
|
-
class Constructable(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
349
|
+
class Constructable(_BaseInventoryPlugin):
|
|
350
|
+
def _compose(self, template, variables, disable_lookups=...):
|
|
351
|
+
""" helper method for plugins to compose variables for Ansible based on jinja2 expression and inventory vars"""
|
|
352
|
+
if disable_lookups is not ...:
|
|
353
|
+
self.display.deprecated("The disable_lookups arg has no effect.", version="2.23")
|
|
337
354
|
|
|
338
355
|
try:
|
|
339
356
|
use_extra = self.get_option('use_extra_vars')
|
|
@@ -341,15 +358,14 @@ class Constructable(object):
|
|
|
341
358
|
use_extra = False
|
|
342
359
|
|
|
343
360
|
if use_extra:
|
|
344
|
-
|
|
361
|
+
self.templar.available_variables = combine_vars(variables, self._vars)
|
|
345
362
|
else:
|
|
346
|
-
|
|
363
|
+
self.templar.available_variables = variables
|
|
347
364
|
|
|
348
|
-
return
|
|
349
|
-
disable_lookups=disable_lookups)
|
|
365
|
+
return self.templar.evaluate_expression(template)
|
|
350
366
|
|
|
351
367
|
def _set_composite_vars(self, compose, variables, host, strict=False):
|
|
352
|
-
|
|
368
|
+
""" loops over compose entries to create vars for hosts """
|
|
353
369
|
if compose and isinstance(compose, dict):
|
|
354
370
|
for varname in compose:
|
|
355
371
|
try:
|
|
@@ -361,17 +377,17 @@ class Constructable(object):
|
|
|
361
377
|
self.inventory.set_variable(host, varname, composite)
|
|
362
378
|
|
|
363
379
|
def _add_host_to_composed_groups(self, groups, variables, host, strict=False, fetch_hostvars=True):
|
|
364
|
-
|
|
380
|
+
""" helper to create complex groups for plugins based on jinja2 conditionals, hosts that meet the conditional are added to group"""
|
|
365
381
|
# process each 'group entry'
|
|
366
382
|
if groups and isinstance(groups, dict):
|
|
367
383
|
if fetch_hostvars:
|
|
368
384
|
variables = combine_vars(variables, self.inventory.get_host(host).get_vars())
|
|
369
385
|
self.templar.available_variables = variables
|
|
370
386
|
for group_name in groups:
|
|
371
|
-
conditional =
|
|
387
|
+
conditional = groups[group_name]
|
|
372
388
|
group_name = self._sanitize_group_name(group_name)
|
|
373
389
|
try:
|
|
374
|
-
result =
|
|
390
|
+
result = self.templar.evaluate_conditional(conditional)
|
|
375
391
|
except Exception as e:
|
|
376
392
|
if strict:
|
|
377
393
|
raise AnsibleParserError("Could not add host %s to group %s: %s" % (host, group_name, to_native(e)))
|
|
@@ -384,7 +400,9 @@ class Constructable(object):
|
|
|
384
400
|
self.inventory.add_child(group_name, host)
|
|
385
401
|
|
|
386
402
|
def _add_host_to_keyed_groups(self, keys, variables, host, strict=False, fetch_hostvars=True):
|
|
387
|
-
|
|
403
|
+
""" helper to create groups for plugins based on variable values and add the corresponding hosts to it"""
|
|
404
|
+
should_default_value = (None, '')
|
|
405
|
+
|
|
388
406
|
if keys and isinstance(keys, list):
|
|
389
407
|
for keyed in keys:
|
|
390
408
|
if keyed and isinstance(keyed, dict):
|
|
@@ -401,36 +419,39 @@ class Constructable(object):
|
|
|
401
419
|
trailing_separator = keyed.get('trailing_separator')
|
|
402
420
|
if trailing_separator is not None and default_value_name is not None:
|
|
403
421
|
raise AnsibleParserError("parameters are mutually exclusive for keyed groups: default_value|trailing_separator")
|
|
404
|
-
|
|
422
|
+
|
|
423
|
+
use_default = key in should_default_value and default_value_name is not None
|
|
424
|
+
if key or use_default:
|
|
405
425
|
prefix = keyed.get('prefix', '')
|
|
406
426
|
sep = keyed.get('separator', '_')
|
|
407
427
|
raw_parent_name = keyed.get('parent_group', None)
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
428
|
+
|
|
429
|
+
try:
|
|
430
|
+
raw_parent_name = self.templar.template(raw_parent_name)
|
|
431
|
+
except AnsibleValueOmittedError:
|
|
432
|
+
raw_parent_name = None
|
|
433
|
+
except Exception as ex:
|
|
434
|
+
if strict:
|
|
435
|
+
raise AnsibleParserError(f'Could not generate parent group {raw_parent_name!r} for group {key!r}: {ex}') from ex
|
|
436
|
+
|
|
437
|
+
continue
|
|
415
438
|
|
|
416
439
|
new_raw_group_names = []
|
|
417
|
-
if
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
else:
|
|
422
|
-
new_raw_group_names.append(key)
|
|
440
|
+
if use_default:
|
|
441
|
+
new_raw_group_names.append(default_value_name)
|
|
442
|
+
elif isinstance(key, string_types):
|
|
443
|
+
new_raw_group_names.append(key)
|
|
423
444
|
elif isinstance(key, list):
|
|
424
445
|
for name in key:
|
|
425
446
|
# if list item is empty, 'default_value' will be used as group name
|
|
426
|
-
if name
|
|
447
|
+
if name in should_default_value and default_value_name is not None:
|
|
427
448
|
new_raw_group_names.append(default_value_name)
|
|
428
449
|
else:
|
|
429
450
|
new_raw_group_names.append(name)
|
|
430
451
|
elif isinstance(key, Mapping):
|
|
431
452
|
for (gname, gval) in key.items():
|
|
432
453
|
bare_name = '%s%s%s' % (gname, sep, gval)
|
|
433
|
-
if gval
|
|
454
|
+
if gval in should_default_value:
|
|
434
455
|
# key's value is empty
|
|
435
456
|
if default_value_name is not None:
|
|
436
457
|
bare_name = '%s%s%s' % (gname, sep, default_value_name)
|
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
DOCUMENTATION =
|
|
6
|
+
DOCUMENTATION = """
|
|
7
7
|
name: advanced_host_list
|
|
8
8
|
version_added: "2.4"
|
|
9
9
|
short_description: Parses a 'host list' with ranges
|
|
10
10
|
description:
|
|
11
11
|
- Parses a host list string as a comma separated values of hosts and supports host ranges.
|
|
12
12
|
- This plugin only applies to inventory sources that are not paths and contain at least one comma.
|
|
13
|
-
|
|
13
|
+
"""
|
|
14
14
|
|
|
15
|
-
EXAMPLES =
|
|
15
|
+
EXAMPLES = """
|
|
16
16
|
# simple range
|
|
17
17
|
# ansible -i 'host[1:10],' -m ping
|
|
18
18
|
|
|
19
19
|
# still supports w/o ranges also
|
|
20
20
|
# ansible-playbook -i 'localhost,' play.yml
|
|
21
|
-
|
|
21
|
+
"""
|
|
22
22
|
|
|
23
23
|
import os
|
|
24
24
|
|
|
@@ -31,6 +31,8 @@ class InventoryModule(BaseInventoryPlugin):
|
|
|
31
31
|
|
|
32
32
|
NAME = 'advanced_host_list'
|
|
33
33
|
|
|
34
|
+
# advanced_host_list does not set vars, so needs no special trust assistance from the inventory API
|
|
35
|
+
|
|
34
36
|
def verify_file(self, host_list):
|
|
35
37
|
|
|
36
38
|
valid = False
|
|
@@ -40,7 +42,7 @@ class InventoryModule(BaseInventoryPlugin):
|
|
|
40
42
|
return valid
|
|
41
43
|
|
|
42
44
|
def parse(self, inventory, loader, host_list, cache=True):
|
|
43
|
-
|
|
45
|
+
""" parses the inventory file """
|
|
44
46
|
|
|
45
47
|
super(InventoryModule, self).parse(inventory, loader, host_list)
|
|
46
48
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
DOCUMENTATION =
|
|
6
|
+
DOCUMENTATION = """
|
|
7
7
|
name: auto
|
|
8
8
|
author:
|
|
9
9
|
- Matt Davis (@nitzmahone)
|
|
@@ -14,12 +14,12 @@ DOCUMENTATION = '''
|
|
|
14
14
|
C(plugin) key at its root will automatically cause the named plugin to be loaded and executed with that
|
|
15
15
|
config. This effectively provides automatic enabling of all installed/accessible inventory plugins.
|
|
16
16
|
- To disable this behavior, remove C(auto) from the C(INVENTORY_ENABLED) config element.
|
|
17
|
-
|
|
17
|
+
"""
|
|
18
18
|
|
|
19
|
-
EXAMPLES =
|
|
19
|
+
EXAMPLES = """
|
|
20
20
|
# This plugin is not intended for direct use; it is a fallback mechanism for automatic enabling of
|
|
21
21
|
# all installed inventory plugins.
|
|
22
|
-
|
|
22
|
+
"""
|
|
23
23
|
|
|
24
24
|
from ansible.errors import AnsibleParserError
|
|
25
25
|
from ansible.plugins.inventory import BaseInventoryPlugin
|
|
@@ -30,6 +30,8 @@ class InventoryModule(BaseInventoryPlugin):
|
|
|
30
30
|
|
|
31
31
|
NAME = 'auto'
|
|
32
32
|
|
|
33
|
+
# no need to set trusted_by_default, since the consumers of this value will always consult the real plugin substituted during our parse()
|
|
34
|
+
|
|
33
35
|
def verify_file(self, path):
|
|
34
36
|
if not path.endswith('.yml') and not path.endswith('.yaml'):
|
|
35
37
|
return False
|
|
@@ -55,6 +57,11 @@ class InventoryModule(BaseInventoryPlugin):
|
|
|
55
57
|
raise AnsibleParserError("inventory source '{0}' could not be verified by inventory plugin '{1}'".format(path, plugin_name))
|
|
56
58
|
|
|
57
59
|
self.display.v("Using inventory plugin '{0}' to process inventory source '{1}'".format(plugin._load_name, path))
|
|
60
|
+
|
|
61
|
+
# unfortunate magic to swap the real plugin type we're proxying here into the inventory data API wrapper, so the wrapper can make the right compat
|
|
62
|
+
# decisions based on the metadata the real plugin provides instead of our metadata
|
|
63
|
+
inventory._target_plugin = plugin
|
|
64
|
+
|
|
58
65
|
plugin.parse(inventory, loader, path, cache=cache)
|
|
59
66
|
try:
|
|
60
67
|
plugin.update_cache_if_changed()
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
DOCUMENTATION =
|
|
6
|
+
DOCUMENTATION = """
|
|
7
7
|
name: constructed
|
|
8
8
|
version_added: "2.4"
|
|
9
9
|
short_description: Uses Jinja2 to construct vars and groups based on existing inventory.
|
|
@@ -33,9 +33,9 @@ DOCUMENTATION = '''
|
|
|
33
33
|
version_added: '2.11'
|
|
34
34
|
extends_documentation_fragment:
|
|
35
35
|
- constructed
|
|
36
|
-
|
|
36
|
+
"""
|
|
37
37
|
|
|
38
|
-
EXAMPLES = r
|
|
38
|
+
EXAMPLES = r"""
|
|
39
39
|
# inventory.config file in YAML format
|
|
40
40
|
plugin: ansible.builtin.constructed
|
|
41
41
|
strict: False
|
|
@@ -77,17 +77,16 @@ EXAMPLES = r'''
|
|
|
77
77
|
# this creates a common parent group for all ec2 availability zones
|
|
78
78
|
- key: placement.availability_zone
|
|
79
79
|
parent_group: all_ec2_zones
|
|
80
|
-
|
|
80
|
+
"""
|
|
81
81
|
|
|
82
82
|
import os
|
|
83
83
|
|
|
84
84
|
from ansible import constants as C
|
|
85
|
-
from ansible.errors import AnsibleParserError
|
|
85
|
+
from ansible.errors import AnsibleParserError
|
|
86
86
|
from ansible.inventory.helpers import get_group_vars
|
|
87
87
|
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
|
88
|
-
from ansible.
|
|
88
|
+
from ansible.plugins.loader import cache_loader
|
|
89
89
|
from ansible.utils.vars import combine_vars
|
|
90
|
-
from ansible.vars.fact_cache import FactCache
|
|
91
90
|
from ansible.vars.plugins import get_vars_from_inventory_sources
|
|
92
91
|
|
|
93
92
|
|
|
@@ -96,11 +95,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
|
|
96
95
|
|
|
97
96
|
NAME = 'constructed'
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
super(InventoryModule, self).__init__()
|
|
102
|
-
|
|
103
|
-
self._cache = FactCache()
|
|
98
|
+
# implicit trust behavior is already added by the YAML parser invoked by the loader
|
|
104
99
|
|
|
105
100
|
def verify_file(self, path):
|
|
106
101
|
|
|
@@ -114,11 +109,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
|
|
114
109
|
return valid
|
|
115
110
|
|
|
116
111
|
def get_all_host_vars(self, host, loader, sources):
|
|
117
|
-
|
|
112
|
+
""" requires host object """
|
|
118
113
|
return combine_vars(self.host_groupvars(host, loader, sources), self.host_vars(host, loader, sources))
|
|
119
114
|
|
|
120
115
|
def host_groupvars(self, host, loader, sources):
|
|
121
|
-
|
|
116
|
+
""" requires host object """
|
|
122
117
|
gvars = get_group_vars(host.get_groups())
|
|
123
118
|
|
|
124
119
|
if self.get_option('use_vars_plugins'):
|
|
@@ -127,7 +122,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
|
|
127
122
|
return gvars
|
|
128
123
|
|
|
129
124
|
def host_vars(self, host, loader, sources):
|
|
130
|
-
|
|
125
|
+
""" requires host object """
|
|
131
126
|
hvars = host.get_vars()
|
|
132
127
|
|
|
133
128
|
if self.get_option('use_vars_plugins'):
|
|
@@ -136,7 +131,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
|
|
136
131
|
return hvars
|
|
137
132
|
|
|
138
133
|
def parse(self, inventory, loader, path, cache=False):
|
|
139
|
-
|
|
134
|
+
""" parses the inventory file """
|
|
140
135
|
|
|
141
136
|
super(InventoryModule, self).parse(inventory, loader, path, cache=cache)
|
|
142
137
|
|
|
@@ -147,26 +142,28 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
|
|
147
142
|
sources = inventory.processed_sources
|
|
148
143
|
except AttributeError:
|
|
149
144
|
if self.get_option('use_vars_plugins'):
|
|
150
|
-
raise
|
|
145
|
+
raise
|
|
151
146
|
|
|
152
147
|
strict = self.get_option('strict')
|
|
153
|
-
|
|
148
|
+
|
|
149
|
+
cache = cache_loader.get(C.CACHE_PLUGIN)
|
|
150
|
+
|
|
154
151
|
try:
|
|
155
152
|
# Go over hosts (less var copies)
|
|
156
153
|
for host in inventory.hosts:
|
|
157
154
|
|
|
158
155
|
# get available variables to templar
|
|
159
156
|
hostvars = self.get_all_host_vars(inventory.hosts[host], loader, sources)
|
|
160
|
-
if host
|
|
161
|
-
hostvars = combine_vars(hostvars,
|
|
157
|
+
if cache.contains(host): # adds facts if cache is active
|
|
158
|
+
hostvars = combine_vars(hostvars, cache.get(host))
|
|
162
159
|
|
|
163
160
|
# create composite vars
|
|
164
161
|
self._set_composite_vars(self.get_option('compose'), hostvars, host, strict=strict)
|
|
165
162
|
|
|
166
163
|
# refetch host vars in case new ones have been created above
|
|
167
164
|
hostvars = self.get_all_host_vars(inventory.hosts[host], loader, sources)
|
|
168
|
-
if host
|
|
169
|
-
hostvars = combine_vars(hostvars,
|
|
165
|
+
if cache.contains(host): # adds facts if cache is active
|
|
166
|
+
hostvars = combine_vars(hostvars, cache.get(host))
|
|
170
167
|
|
|
171
168
|
# constructed groups based on conditionals
|
|
172
169
|
self._add_host_to_composed_groups(self.get_option('groups'), hostvars, host, strict=strict, fetch_hostvars=False)
|
|
@@ -174,5 +171,5 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
|
|
174
171
|
# constructed groups based variable values
|
|
175
172
|
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), hostvars, host, strict=strict, fetch_hostvars=False)
|
|
176
173
|
|
|
177
|
-
except Exception as
|
|
178
|
-
raise AnsibleParserError("
|
|
174
|
+
except Exception as ex:
|
|
175
|
+
raise AnsibleParserError(f"Failed to parse {path!r}.") from ex
|