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
|
@@ -39,7 +39,7 @@ except ImportError:
|
|
|
39
39
|
|
|
40
40
|
# TODO: add python requirements to ansible-test's ansible-core distribution info and remove the hardcoded lowerbound/upperbound fallback
|
|
41
41
|
RESOLVELIB_LOWERBOUND = SemanticVersion("0.5.3")
|
|
42
|
-
RESOLVELIB_UPPERBOUND = SemanticVersion("
|
|
42
|
+
RESOLVELIB_UPPERBOUND = SemanticVersion("2.0.0")
|
|
43
43
|
RESOLVELIB_VERSION = SemanticVersion.from_loose_version(LooseVersion(resolvelib_version))
|
|
44
44
|
|
|
45
45
|
|
|
@@ -148,7 +148,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
148
148
|
|
|
149
149
|
:param resolutions: Mapping of identifier, candidate pairs.
|
|
150
150
|
|
|
151
|
-
:param candidates: Possible candidates for the
|
|
151
|
+
:param candidates: Possible candidates for the identifier.
|
|
152
152
|
Mapping of identifier, list of candidate pairs.
|
|
153
153
|
|
|
154
154
|
:param information: Requirement information of each package.
|
|
@@ -158,7 +158,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
158
158
|
:param backtrack_causes: Sequence of requirement information that were
|
|
159
159
|
the requirements that caused the resolver to most recently backtrack.
|
|
160
160
|
|
|
161
|
-
The preference could depend on
|
|
161
|
+
The preference could depend on various of issues, including
|
|
162
162
|
(not necessarily in this order):
|
|
163
163
|
|
|
164
164
|
* Is this package pinned in the current resolution result?
|
|
@@ -404,7 +404,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
404
404
|
|
|
405
405
|
:param requirement: A requirement that produced the `candidate`.
|
|
406
406
|
|
|
407
|
-
:param candidate: A pinned candidate supposedly
|
|
407
|
+
:param candidate: A pinned candidate supposedly matching the \
|
|
408
408
|
`requirement` specifier. It is guaranteed to \
|
|
409
409
|
have been generated from the `requirement`.
|
|
410
410
|
|
|
@@ -5,12 +5,46 @@
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
+
from collections import defaultdict
|
|
9
|
+
|
|
8
10
|
try:
|
|
9
11
|
from resolvelib import BaseReporter
|
|
10
12
|
except ImportError:
|
|
11
13
|
class BaseReporter: # type: ignore[no-redef]
|
|
12
14
|
pass
|
|
13
15
|
|
|
16
|
+
try:
|
|
17
|
+
from resolvelib.resolvers import Criterion
|
|
18
|
+
except ImportError:
|
|
19
|
+
class Criterion: # type: ignore[no-redef]
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
from ansible.utils.display import Display
|
|
23
|
+
from .dataclasses import Candidate, Requirement
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
display = Display()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
_CLI_APP_NAME = 'ansible-galaxy'
|
|
30
|
+
_MESSAGES_AT_REJECT_COUNT = {
|
|
31
|
+
1: (
|
|
32
|
+
f'{_CLI_APP_NAME} is looking at multiple versions of {{fqcn}} to '
|
|
33
|
+
'determine which version is compatible with other '
|
|
34
|
+
'requirements. This could take a while.'
|
|
35
|
+
),
|
|
36
|
+
8: (
|
|
37
|
+
f'{_CLI_APP_NAME} is looking at multiple versions of {{fqcn}} to '
|
|
38
|
+
'determine which version is compatible with other '
|
|
39
|
+
'requirements. This could take a while.'
|
|
40
|
+
),
|
|
41
|
+
13: (
|
|
42
|
+
'This is taking longer than usual. You might need to provide '
|
|
43
|
+
'the dependency resolver with stricter constraints to reduce '
|
|
44
|
+
'runtime. If you want to abort this run, press Ctrl + C.'
|
|
45
|
+
),
|
|
46
|
+
}
|
|
47
|
+
|
|
14
48
|
|
|
15
49
|
class CollectionDependencyReporter(BaseReporter):
|
|
16
50
|
"""A dependency reporter for Ansible Collections.
|
|
@@ -18,3 +52,50 @@ class CollectionDependencyReporter(BaseReporter):
|
|
|
18
52
|
This is a proxy class allowing us to abstract away importing resolvelib
|
|
19
53
|
outside of the `ansible.galaxy.dependency_resolution` Python package.
|
|
20
54
|
"""
|
|
55
|
+
|
|
56
|
+
def __init__(self) -> None:
|
|
57
|
+
"""Initialize the collection rejection counter."""
|
|
58
|
+
super().__init__()
|
|
59
|
+
|
|
60
|
+
self.reject_count_by_fqcn: defaultdict[str, int] = defaultdict(int)
|
|
61
|
+
|
|
62
|
+
def _maybe_log_rejection_message(self, candidate: Candidate) -> bool:
|
|
63
|
+
"""Print out rejection messages on pre-defined limit hits."""
|
|
64
|
+
# Inspired by https://github.com/pypa/pip/commit/9731131
|
|
65
|
+
self.reject_count_by_fqcn[candidate.fqcn] += 1
|
|
66
|
+
|
|
67
|
+
collection_rejections_count = self.reject_count_by_fqcn[candidate.fqcn]
|
|
68
|
+
|
|
69
|
+
if collection_rejections_count not in _MESSAGES_AT_REJECT_COUNT:
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
collection_rejection_message = _MESSAGES_AT_REJECT_COUNT[
|
|
73
|
+
collection_rejections_count
|
|
74
|
+
]
|
|
75
|
+
display.display(collection_rejection_message.format(fqcn=candidate.fqcn))
|
|
76
|
+
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
def rejecting_candidate( # resolvelib >= 0.9.0
|
|
80
|
+
self,
|
|
81
|
+
criterion: Criterion[Candidate, Requirement],
|
|
82
|
+
candidate: Candidate,
|
|
83
|
+
) -> None:
|
|
84
|
+
"""Augment rejection messages with conflict details."""
|
|
85
|
+
if not self._maybe_log_rejection_message(candidate):
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
msg = 'Will try a different candidate, due to conflict:'
|
|
89
|
+
for req_info in criterion.information:
|
|
90
|
+
req, parent = req_info.requirement, req_info.parent
|
|
91
|
+
msg += '\n '
|
|
92
|
+
if parent:
|
|
93
|
+
msg += f'{parent !s} depends on '
|
|
94
|
+
else:
|
|
95
|
+
msg += 'The user requested '
|
|
96
|
+
msg += str(req)
|
|
97
|
+
display.v(msg)
|
|
98
|
+
|
|
99
|
+
def backtracking(self, candidate: Candidate) -> None: # resolvelib < 0.9.0
|
|
100
|
+
"""Print out rejection messages on pre-defined limit hits."""
|
|
101
|
+
self._maybe_log_rejection_message(candidate)
|
ansible/galaxy/role.py
CHANGED
|
@@ -185,13 +185,11 @@ class GalaxyRole(object):
|
|
|
185
185
|
info_path = os.path.join(self.path, self.META_INSTALL)
|
|
186
186
|
if os.path.isfile(info_path):
|
|
187
187
|
try:
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
with open(info_path, 'r') as f:
|
|
189
|
+
self._install_info = yaml_load(f)
|
|
190
190
|
except Exception:
|
|
191
191
|
display.vvvvv("Unable to load Galaxy install info for %s" % self.name)
|
|
192
192
|
return False
|
|
193
|
-
finally:
|
|
194
|
-
f.close()
|
|
195
193
|
return self._install_info
|
|
196
194
|
|
|
197
195
|
@property
|
|
@@ -440,8 +438,8 @@ class GalaxyRole(object):
|
|
|
440
438
|
if not (self.src and os.path.isfile(self.src)):
|
|
441
439
|
try:
|
|
442
440
|
os.unlink(tmp_file)
|
|
443
|
-
except
|
|
444
|
-
display.
|
|
441
|
+
except OSError as ex:
|
|
442
|
+
display.error_as_warning(f"Unable to remove tmp file {tmp_file!r}.", exception=ex)
|
|
445
443
|
return True
|
|
446
444
|
|
|
447
445
|
return False
|
|
@@ -470,12 +468,10 @@ class GalaxyRole(object):
|
|
|
470
468
|
meta_path = os.path.join(self.path, meta_requirements)
|
|
471
469
|
if os.path.isfile(meta_path):
|
|
472
470
|
try:
|
|
473
|
-
|
|
474
|
-
|
|
471
|
+
with open(meta_path, 'r') as f:
|
|
472
|
+
self._requirements = yaml_load(f)
|
|
475
473
|
except Exception:
|
|
476
474
|
display.vvvvv("Unable to load requirements for %s" % self.name)
|
|
477
|
-
finally:
|
|
478
|
-
f.close()
|
|
479
475
|
|
|
480
476
|
break
|
|
481
477
|
|
ansible/galaxy/token.py
CHANGED
|
@@ -26,10 +26,12 @@ import os
|
|
|
26
26
|
import time
|
|
27
27
|
from stat import S_IRUSR, S_IWUSR
|
|
28
28
|
from urllib.error import HTTPError
|
|
29
|
+
from urllib.parse import urlencode
|
|
29
30
|
|
|
30
31
|
from ansible import constants as C
|
|
31
32
|
from ansible.galaxy.api import GalaxyError
|
|
32
33
|
from ansible.galaxy.user_agent import user_agent
|
|
34
|
+
from ansible.module_utils.common.sentinel import Sentinel as NoTokenSentinel
|
|
33
35
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
34
36
|
from ansible.module_utils.common.yaml import yaml_dump, yaml_load
|
|
35
37
|
from ansible.module_utils.urls import open_url
|
|
@@ -38,21 +40,15 @@ from ansible.utils.display import Display
|
|
|
38
40
|
display = Display()
|
|
39
41
|
|
|
40
42
|
|
|
41
|
-
class NoTokenSentinel(object):
|
|
42
|
-
""" Represents an ansible.cfg server with not token defined (will ignore cmdline and GALAXY_TOKEN_PATH. """
|
|
43
|
-
def __new__(cls, *args, **kwargs):
|
|
44
|
-
return cls
|
|
45
|
-
|
|
46
|
-
|
|
47
43
|
class KeycloakToken(object):
|
|
48
|
-
|
|
44
|
+
"""A token granted by a Keycloak server.
|
|
49
45
|
|
|
50
46
|
Like sso.redhat.com as used by cloud.redhat.com
|
|
51
|
-
ie Automation Hub
|
|
47
|
+
ie Automation Hub"""
|
|
52
48
|
|
|
53
49
|
token_type = 'Bearer'
|
|
54
50
|
|
|
55
|
-
def __init__(self, access_token=None, auth_url=None, validate_certs=True, client_id=None):
|
|
51
|
+
def __init__(self, access_token=None, auth_url=None, validate_certs=True, client_id=None, client_secret=None):
|
|
56
52
|
self.access_token = access_token
|
|
57
53
|
self.auth_url = auth_url
|
|
58
54
|
self._token = None
|
|
@@ -60,11 +56,26 @@ class KeycloakToken(object):
|
|
|
60
56
|
self.client_id = client_id
|
|
61
57
|
if self.client_id is None:
|
|
62
58
|
self.client_id = 'cloud-services'
|
|
59
|
+
self.client_secret = client_secret
|
|
63
60
|
self._expiration = None
|
|
64
61
|
|
|
65
62
|
def _form_payload(self):
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
payload = {
|
|
64
|
+
'client_id': self.client_id,
|
|
65
|
+
}
|
|
66
|
+
if self.client_secret:
|
|
67
|
+
payload['client_secret'] = self.client_secret
|
|
68
|
+
payload['scope'] = 'api.console'
|
|
69
|
+
payload['grant_type'] = 'client_credentials'
|
|
70
|
+
if self.access_token not in (None, NoTokenSentinel):
|
|
71
|
+
display.warning(
|
|
72
|
+
'Found both a client_secret and access_token for galaxy authentication, ignoring access_token'
|
|
73
|
+
)
|
|
74
|
+
else:
|
|
75
|
+
payload['refresh_token'] = self.access_token
|
|
76
|
+
payload['grant_type'] = 'refresh_token'
|
|
77
|
+
|
|
78
|
+
return urlencode(payload)
|
|
68
79
|
|
|
69
80
|
def get(self):
|
|
70
81
|
if self._expiration and time.time() >= self._expiration:
|
|
@@ -73,16 +84,9 @@ class KeycloakToken(object):
|
|
|
73
84
|
if self._token:
|
|
74
85
|
return self._token
|
|
75
86
|
|
|
76
|
-
# - build a request to POST to auth_url
|
|
77
|
-
# - body is form encoded
|
|
78
|
-
# - 'refresh_token' is the offline token stored in ansible.cfg
|
|
79
|
-
# - 'grant_type' is 'refresh_token'
|
|
80
|
-
# - 'client_id' is 'cloud-services'
|
|
81
|
-
# - should probably be based on the contents of the
|
|
82
|
-
# offline_ticket's JWT payload 'aud' (audience)
|
|
83
|
-
# or 'azp' (Authorized party - the party to which the ID Token was issued)
|
|
84
87
|
payload = self._form_payload()
|
|
85
88
|
|
|
89
|
+
display.vvv(f'Authenticating via {self.auth_url}')
|
|
86
90
|
try:
|
|
87
91
|
resp = open_url(to_native(self.auth_url),
|
|
88
92
|
data=payload,
|
|
@@ -91,15 +95,18 @@ class KeycloakToken(object):
|
|
|
91
95
|
http_agent=user_agent())
|
|
92
96
|
except HTTPError as e:
|
|
93
97
|
raise GalaxyError(e, 'Unable to get access token')
|
|
98
|
+
display.vvv('Authentication successful')
|
|
94
99
|
|
|
95
100
|
data = json.load(resp)
|
|
96
101
|
|
|
97
102
|
# So that we have a buffer, expire the token in ~2/3 the given value
|
|
98
103
|
expires_in = data['expires_in'] // 3 * 2
|
|
99
104
|
self._expiration = time.time() + expires_in
|
|
105
|
+
display.vvv(f'Authentication token expires in {expires_in} seconds')
|
|
100
106
|
|
|
101
|
-
# - extract 'access_token'
|
|
102
107
|
self._token = data.get('access_token')
|
|
108
|
+
if token_type := data.get('token_type'):
|
|
109
|
+
self.token_type = token_type
|
|
103
110
|
|
|
104
111
|
return self._token
|
|
105
112
|
|
|
@@ -110,7 +117,7 @@ class KeycloakToken(object):
|
|
|
110
117
|
|
|
111
118
|
|
|
112
119
|
class GalaxyToken(object):
|
|
113
|
-
|
|
120
|
+
""" Class to storing and retrieving local galaxy token """
|
|
114
121
|
|
|
115
122
|
token_type = 'Token'
|
|
116
123
|
|
ansible/inventory/data.py
CHANGED
|
@@ -19,64 +19,49 @@
|
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
21
|
import sys
|
|
22
|
+
import typing as t
|
|
22
23
|
|
|
23
24
|
from ansible import constants as C
|
|
24
25
|
from ansible.errors import AnsibleError
|
|
25
26
|
from ansible.inventory.group import Group
|
|
26
27
|
from ansible.inventory.host import Host
|
|
27
|
-
from ansible.module_utils.six import string_types
|
|
28
28
|
from ansible.utils.display import Display
|
|
29
29
|
from ansible.utils.vars import combine_vars
|
|
30
30
|
from ansible.utils.path import basedir
|
|
31
31
|
|
|
32
|
+
from . import helpers # this is left as a module import to facilitate easier unit test patching
|
|
33
|
+
|
|
34
|
+
|
|
32
35
|
display = Display()
|
|
33
36
|
|
|
34
37
|
|
|
35
|
-
class InventoryData
|
|
38
|
+
class InventoryData:
|
|
36
39
|
"""
|
|
37
40
|
Holds inventory data (host and group objects).
|
|
38
|
-
Using
|
|
41
|
+
Using its methods should guarantee expected relationships and data.
|
|
39
42
|
"""
|
|
40
43
|
|
|
41
|
-
def __init__(self):
|
|
44
|
+
def __init__(self) -> None:
|
|
42
45
|
|
|
43
|
-
self.groups = {}
|
|
44
|
-
self.hosts = {}
|
|
46
|
+
self.groups: dict[str, Group] = {}
|
|
47
|
+
self.hosts: dict[str, Host] = {}
|
|
45
48
|
|
|
46
49
|
# provides 'groups' magic var, host object has group_names
|
|
47
|
-
self._groups_dict_cache = {}
|
|
50
|
+
self._groups_dict_cache: dict[str, list[str]] = {}
|
|
48
51
|
|
|
49
52
|
# current localhost, implicit or explicit
|
|
50
|
-
self.localhost = None
|
|
53
|
+
self.localhost: Host | None = None
|
|
51
54
|
|
|
52
|
-
self.current_source = None
|
|
53
|
-
self.processed_sources = []
|
|
55
|
+
self.current_source: str | None = None
|
|
56
|
+
self.processed_sources: list[str] = []
|
|
54
57
|
|
|
55
58
|
# Always create the 'all' and 'ungrouped' groups,
|
|
56
59
|
for group in ('all', 'ungrouped'):
|
|
57
60
|
self.add_group(group)
|
|
58
|
-
self.add_child('all', 'ungrouped')
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
self._groups_dict_cache = None
|
|
62
|
-
data = {
|
|
63
|
-
'groups': self.groups,
|
|
64
|
-
'hosts': self.hosts,
|
|
65
|
-
'local': self.localhost,
|
|
66
|
-
'source': self.current_source,
|
|
67
|
-
'processed_sources': self.processed_sources
|
|
68
|
-
}
|
|
69
|
-
return data
|
|
70
|
-
|
|
71
|
-
def deserialize(self, data):
|
|
72
|
-
self._groups_dict_cache = {}
|
|
73
|
-
self.hosts = data.get('hosts')
|
|
74
|
-
self.groups = data.get('groups')
|
|
75
|
-
self.localhost = data.get('local')
|
|
76
|
-
self.current_source = data.get('source')
|
|
77
|
-
self.processed_sources = data.get('processed_sources')
|
|
62
|
+
self.add_child('all', 'ungrouped')
|
|
78
63
|
|
|
79
|
-
def _create_implicit_localhost(self, pattern):
|
|
64
|
+
def _create_implicit_localhost(self, pattern: str) -> Host:
|
|
80
65
|
|
|
81
66
|
if self.localhost:
|
|
82
67
|
new_host = self.localhost
|
|
@@ -100,8 +85,8 @@ class InventoryData(object):
|
|
|
100
85
|
|
|
101
86
|
return new_host
|
|
102
87
|
|
|
103
|
-
def reconcile_inventory(self):
|
|
104
|
-
|
|
88
|
+
def reconcile_inventory(self) -> None:
|
|
89
|
+
"""Ensure inventory basic rules, run after updates."""
|
|
105
90
|
|
|
106
91
|
display.debug('Reconcile groups and hosts in inventory.')
|
|
107
92
|
self.current_source = None
|
|
@@ -125,7 +110,7 @@ class InventoryData(object):
|
|
|
125
110
|
|
|
126
111
|
if self.groups['ungrouped'] in mygroups:
|
|
127
112
|
# clear ungrouped of any incorrectly stored by parser
|
|
128
|
-
if set(mygroups).difference(
|
|
113
|
+
if set(mygroups).difference({self.groups['all'], self.groups['ungrouped']}):
|
|
129
114
|
self.groups['ungrouped'].remove_host(host)
|
|
130
115
|
|
|
131
116
|
elif not host.implicit:
|
|
@@ -144,8 +129,10 @@ class InventoryData(object):
|
|
|
144
129
|
|
|
145
130
|
self._groups_dict_cache = {}
|
|
146
131
|
|
|
147
|
-
def get_host(self, hostname):
|
|
148
|
-
|
|
132
|
+
def get_host(self, hostname: str) -> Host | None:
|
|
133
|
+
"""Fetch host object using name deal with implicit localhost."""
|
|
134
|
+
|
|
135
|
+
hostname = helpers.remove_trust(hostname)
|
|
149
136
|
|
|
150
137
|
matching_host = self.hosts.get(hostname, None)
|
|
151
138
|
|
|
@@ -156,19 +143,19 @@ class InventoryData(object):
|
|
|
156
143
|
|
|
157
144
|
return matching_host
|
|
158
145
|
|
|
159
|
-
def add_group(self, group):
|
|
160
|
-
|
|
146
|
+
def add_group(self, group: str) -> str:
|
|
147
|
+
"""Adds a group to inventory if not there already, returns named actually used."""
|
|
161
148
|
|
|
162
149
|
if group:
|
|
163
|
-
if not isinstance(group,
|
|
150
|
+
if not isinstance(group, str):
|
|
164
151
|
raise AnsibleError("Invalid group name supplied, expected a string but got %s for %s" % (type(group), group))
|
|
165
152
|
if group not in self.groups:
|
|
166
153
|
g = Group(group)
|
|
167
|
-
|
|
168
|
-
|
|
154
|
+
group = g.name # the group object may have sanitized the group name; use whatever it has
|
|
155
|
+
if group not in self.groups:
|
|
156
|
+
self.groups[group] = g
|
|
169
157
|
self._groups_dict_cache = {}
|
|
170
158
|
display.debug("Added group %s to inventory" % group)
|
|
171
|
-
group = g.name
|
|
172
159
|
else:
|
|
173
160
|
display.debug("group %s already in inventory" % group)
|
|
174
161
|
else:
|
|
@@ -176,22 +163,24 @@ class InventoryData(object):
|
|
|
176
163
|
|
|
177
164
|
return group
|
|
178
165
|
|
|
179
|
-
def remove_group(self, group):
|
|
166
|
+
def remove_group(self, group: Group) -> None:
|
|
180
167
|
|
|
181
|
-
if group in self.groups:
|
|
182
|
-
del self.groups[group]
|
|
183
|
-
display.debug("Removed group %s from inventory" % group)
|
|
168
|
+
if group.name in self.groups:
|
|
169
|
+
del self.groups[group.name]
|
|
170
|
+
display.debug("Removed group %s from inventory" % group.name)
|
|
184
171
|
self._groups_dict_cache = {}
|
|
185
172
|
|
|
186
173
|
for host in self.hosts:
|
|
187
174
|
h = self.hosts[host]
|
|
188
175
|
h.remove_group(group)
|
|
189
176
|
|
|
190
|
-
def add_host(self, host, group=None, port=None):
|
|
191
|
-
|
|
177
|
+
def add_host(self, host: str, group: str | None = None, port: int | str | None = None) -> str:
|
|
178
|
+
"""Adds a host to inventory and possibly a group if not there already."""
|
|
179
|
+
|
|
180
|
+
host = helpers.remove_trust(host)
|
|
192
181
|
|
|
193
182
|
if host:
|
|
194
|
-
if not isinstance(host,
|
|
183
|
+
if not isinstance(host, str):
|
|
195
184
|
raise AnsibleError("Invalid host name supplied, expected a string but got %s for %s" % (type(host), host))
|
|
196
185
|
|
|
197
186
|
# TODO: add to_safe_host_name
|
|
@@ -211,7 +200,7 @@ class InventoryData(object):
|
|
|
211
200
|
else:
|
|
212
201
|
self.set_variable(host, 'inventory_file', None)
|
|
213
202
|
self.set_variable(host, 'inventory_dir', None)
|
|
214
|
-
display.debug("Added host %s to inventory" %
|
|
203
|
+
display.debug("Added host %s to inventory" % host)
|
|
215
204
|
|
|
216
205
|
# set default localhost from inventory to avoid creating an implicit one. Last localhost defined 'wins'.
|
|
217
206
|
if host in C.LOCALHOST:
|
|
@@ -232,7 +221,7 @@ class InventoryData(object):
|
|
|
232
221
|
|
|
233
222
|
return host
|
|
234
223
|
|
|
235
|
-
def remove_host(self, host):
|
|
224
|
+
def remove_host(self, host: Host) -> None:
|
|
236
225
|
|
|
237
226
|
if host.name in self.hosts:
|
|
238
227
|
del self.hosts[host.name]
|
|
@@ -241,8 +230,10 @@ class InventoryData(object):
|
|
|
241
230
|
g = self.groups[group]
|
|
242
231
|
g.remove_host(host)
|
|
243
232
|
|
|
244
|
-
def set_variable(self, entity, varname, value):
|
|
245
|
-
|
|
233
|
+
def set_variable(self, entity: str, varname: str, value: t.Any) -> None:
|
|
234
|
+
"""Sets a variable for an inventory object."""
|
|
235
|
+
|
|
236
|
+
inv_object: Host | Group
|
|
246
237
|
|
|
247
238
|
if entity in self.groups:
|
|
248
239
|
inv_object = self.groups[entity]
|
|
@@ -254,9 +245,8 @@ class InventoryData(object):
|
|
|
254
245
|
inv_object.set_variable(varname, value)
|
|
255
246
|
display.debug('set %s for %s' % (varname, entity))
|
|
256
247
|
|
|
257
|
-
def add_child(self, group, child):
|
|
258
|
-
|
|
259
|
-
added = False
|
|
248
|
+
def add_child(self, group: str, child: str) -> bool:
|
|
249
|
+
"""Add host or group to group."""
|
|
260
250
|
if group in self.groups:
|
|
261
251
|
g = self.groups[group]
|
|
262
252
|
if child in self.groups:
|
|
@@ -271,12 +261,12 @@ class InventoryData(object):
|
|
|
271
261
|
raise AnsibleError("%s is not a known group" % group)
|
|
272
262
|
return added
|
|
273
263
|
|
|
274
|
-
def get_groups_dict(self):
|
|
264
|
+
def get_groups_dict(self) -> dict[str, list[str]]:
|
|
275
265
|
"""
|
|
276
266
|
We merge a 'magic' var 'groups' with group name keys and hostname list values into every host variable set. Cache for speed.
|
|
277
267
|
"""
|
|
278
268
|
if not self._groups_dict_cache:
|
|
279
|
-
for
|
|
269
|
+
for group_name, group in self.groups.items():
|
|
280
270
|
self._groups_dict_cache[group_name] = [h.name for h in group.get_hosts()]
|
|
281
271
|
|
|
282
272
|
return self._groups_dict_cache
|