ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +203 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +197 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +345 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +62 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +159 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +62 -53
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +166 -112
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +161 -96
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +268 -258
- ansible/executor/task_queue_manager.py +124 -90
- ansible/executor/task_result.py +183 -78
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +78 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +152 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +86 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +1 -1
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +4 -4
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +9 -8
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +19 -17
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +32 -27
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +31 -27
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +4 -5
- ansible/plugins/action/gather_facts.py +7 -6
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +35 -44
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +284 -179
- ansible/plugins/callback/default.py +99 -92
- ansible/plugins/callback/junit.py +44 -39
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +28 -21
- ansible/plugins/callback/tree.py +16 -11
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +6 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +225 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +97 -77
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +86 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +159 -184
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +55 -21
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +370 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +433 -63
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +51 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +206 -282
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/WHEEL +1 -1
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -0
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +1 -0
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +2 -1
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +4 -0
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +1 -0
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +16 -1
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +24 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +2 -0
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/delegation.py +1 -0
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +35 -27
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
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
|
ansible/inventory/group.py
CHANGED
@@ -16,6 +16,8 @@
|
|
16
16
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
|
+
import typing as t
|
20
|
+
|
19
21
|
from collections.abc import Mapping, MutableMapping
|
20
22
|
from enum import Enum
|
21
23
|
from itertools import chain
|
@@ -26,8 +28,13 @@ from ansible.module_utils.common.text.converters import to_native, to_text
|
|
26
28
|
from ansible.utils.display import Display
|
27
29
|
from ansible.utils.vars import combine_vars
|
28
30
|
|
31
|
+
from . import helpers # this is left as a module import to facilitate easier unit test patching
|
32
|
+
|
29
33
|
display = Display()
|
30
34
|
|
35
|
+
if t.TYPE_CHECKING:
|
36
|
+
from .host import Host
|
37
|
+
|
31
38
|
|
32
39
|
def to_safe_group_name(name, replacer="_", force=False, silent=False):
|
33
40
|
# Converts 'bad' characters in a string to underscores (or provided replacer) so they can be used as Ansible hosts or groups
|
@@ -59,22 +66,23 @@ class InventoryObjectType(Enum):
|
|
59
66
|
|
60
67
|
|
61
68
|
class Group:
|
62
|
-
|
69
|
+
"""A group of ansible hosts."""
|
63
70
|
base_type = InventoryObjectType.GROUP
|
64
71
|
|
65
72
|
# __slots__ = [ 'name', 'hosts', 'vars', 'child_groups', 'parent_groups', 'depth', '_hosts_cache' ]
|
66
73
|
|
67
|
-
def __init__(self, name
|
74
|
+
def __init__(self, name: str) -> None:
|
75
|
+
name = helpers.remove_trust(name)
|
68
76
|
|
69
|
-
self.depth = 0
|
70
|
-
self.name = to_safe_group_name(name)
|
71
|
-
self.hosts = []
|
72
|
-
self._hosts = None
|
73
|
-
self.vars = {}
|
74
|
-
self.child_groups = []
|
75
|
-
self.parent_groups = []
|
76
|
-
self._hosts_cache = None
|
77
|
-
self.priority = 1
|
77
|
+
self.depth: int = 0
|
78
|
+
self.name: str = to_safe_group_name(name)
|
79
|
+
self.hosts: list[Host] = []
|
80
|
+
self._hosts: set[str] | None = None
|
81
|
+
self.vars: dict[str, t.Any] = {}
|
82
|
+
self.child_groups: list[Group] = []
|
83
|
+
self.parent_groups: list[Group] = []
|
84
|
+
self._hosts_cache: list[Host] | None = None
|
85
|
+
self.priority: int = 1
|
78
86
|
|
79
87
|
def __repr__(self):
|
80
88
|
return self.get_name()
|
@@ -82,45 +90,8 @@ class Group:
|
|
82
90
|
def __str__(self):
|
83
91
|
return self.get_name()
|
84
92
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
def __setstate__(self, data):
|
89
|
-
return self.deserialize(data)
|
90
|
-
|
91
|
-
def serialize(self):
|
92
|
-
parent_groups = []
|
93
|
-
for parent in self.parent_groups:
|
94
|
-
parent_groups.append(parent.serialize())
|
95
|
-
|
96
|
-
self._hosts = None
|
97
|
-
|
98
|
-
result = dict(
|
99
|
-
name=self.name,
|
100
|
-
vars=self.vars.copy(),
|
101
|
-
parent_groups=parent_groups,
|
102
|
-
depth=self.depth,
|
103
|
-
hosts=self.hosts,
|
104
|
-
)
|
105
|
-
|
106
|
-
return result
|
107
|
-
|
108
|
-
def deserialize(self, data):
|
109
|
-
self.__init__() # used by __setstate__ to deserialize in place # pylint: disable=unnecessary-dunder-call
|
110
|
-
self.name = data.get('name')
|
111
|
-
self.vars = data.get('vars', dict())
|
112
|
-
self.depth = data.get('depth', 0)
|
113
|
-
self.hosts = data.get('hosts', [])
|
114
|
-
self._hosts = None
|
115
|
-
|
116
|
-
parent_groups = data.get('parent_groups', [])
|
117
|
-
for parent_data in parent_groups:
|
118
|
-
g = Group()
|
119
|
-
g.deserialize(parent_data)
|
120
|
-
self.parent_groups.append(g)
|
121
|
-
|
122
|
-
def _walk_relationship(self, rel, include_self=False, preserve_ordering=False):
|
123
|
-
'''
|
93
|
+
def _walk_relationship(self, rel, include_self=False, preserve_ordering=False) -> set[Group] | list[Group]:
|
94
|
+
"""
|
124
95
|
Given `rel` that is an iterable property of Group,
|
125
96
|
consitituting a directed acyclic graph among all groups,
|
126
97
|
Returns a set of all groups in full tree
|
@@ -132,13 +103,13 @@ class Group:
|
|
132
103
|
| / are directed upward
|
133
104
|
F
|
134
105
|
Called on F, returns set of (A, B, C, D, E)
|
135
|
-
|
136
|
-
seen = set([])
|
106
|
+
"""
|
107
|
+
seen: set[Group] = set([])
|
137
108
|
unprocessed = set(getattr(self, rel))
|
138
109
|
if include_self:
|
139
110
|
unprocessed.add(self)
|
140
111
|
if preserve_ordering:
|
141
|
-
ordered = [self] if include_self else []
|
112
|
+
ordered: list[Group] = [self] if include_self else []
|
142
113
|
ordered.extend(getattr(self, rel))
|
143
114
|
|
144
115
|
while unprocessed:
|
@@ -158,22 +129,22 @@ class Group:
|
|
158
129
|
return ordered
|
159
130
|
return seen
|
160
131
|
|
161
|
-
def get_ancestors(self):
|
162
|
-
return self._walk_relationship('parent_groups')
|
132
|
+
def get_ancestors(self) -> set[Group]:
|
133
|
+
return t.cast(set, self._walk_relationship('parent_groups'))
|
163
134
|
|
164
|
-
def get_descendants(self, **kwargs):
|
135
|
+
def get_descendants(self, **kwargs) -> set[Group] | list[Group]:
|
165
136
|
return self._walk_relationship('child_groups', **kwargs)
|
166
137
|
|
167
138
|
@property
|
168
|
-
def host_names(self):
|
139
|
+
def host_names(self) -> set[str]:
|
169
140
|
if self._hosts is None:
|
170
|
-
self._hosts =
|
141
|
+
self._hosts = {h.name for h in self.hosts}
|
171
142
|
return self._hosts
|
172
143
|
|
173
|
-
def get_name(self):
|
144
|
+
def get_name(self) -> str:
|
174
145
|
return self.name
|
175
146
|
|
176
|
-
def add_child_group(self, group):
|
147
|
+
def add_child_group(self, group: Group) -> bool:
|
177
148
|
added = False
|
178
149
|
if self == group:
|
179
150
|
raise Exception("can't add group to itself")
|
@@ -208,7 +179,7 @@ class Group:
|
|
208
179
|
self.clear_hosts_cache()
|
209
180
|
return added
|
210
181
|
|
211
|
-
def _check_children_depth(self):
|
182
|
+
def _check_children_depth(self) -> None:
|
212
183
|
|
213
184
|
depth = self.depth
|
214
185
|
start_depth = self.depth # self.depth could change over loop
|
@@ -227,7 +198,7 @@ class Group:
|
|
227
198
|
if depth - start_depth > len(seen):
|
228
199
|
raise AnsibleError("The group named '%s' has a recursive dependency loop." % to_native(self.name))
|
229
200
|
|
230
|
-
def add_host(self, host):
|
201
|
+
def add_host(self, host: Host) -> bool:
|
231
202
|
added = False
|
232
203
|
if host.name not in self.host_names:
|
233
204
|
self.hosts.append(host)
|
@@ -237,7 +208,7 @@ class Group:
|
|
237
208
|
added = True
|
238
209
|
return added
|
239
210
|
|
240
|
-
def remove_host(self, host):
|
211
|
+
def remove_host(self, host: Host) -> bool:
|
241
212
|
removed = False
|
242
213
|
if host.name in self.host_names:
|
243
214
|
self.hosts.remove(host)
|
@@ -247,7 +218,8 @@ class Group:
|
|
247
218
|
removed = True
|
248
219
|
return removed
|
249
220
|
|
250
|
-
def set_variable(self, key, value):
|
221
|
+
def set_variable(self, key: str, value: t.Any) -> None:
|
222
|
+
key = helpers.remove_trust(key)
|
251
223
|
|
252
224
|
if key == 'ansible_group_priority':
|
253
225
|
self.set_priority(int(value))
|
@@ -257,36 +229,36 @@ class Group:
|
|
257
229
|
else:
|
258
230
|
self.vars[key] = value
|
259
231
|
|
260
|
-
def clear_hosts_cache(self):
|
232
|
+
def clear_hosts_cache(self) -> None:
|
261
233
|
|
262
234
|
self._hosts_cache = None
|
263
235
|
for g in self.get_ancestors():
|
264
236
|
g._hosts_cache = None
|
265
237
|
|
266
|
-
def get_hosts(self):
|
238
|
+
def get_hosts(self) -> list[Host]:
|
267
239
|
|
268
240
|
if self._hosts_cache is None:
|
269
241
|
self._hosts_cache = self._get_hosts()
|
270
242
|
return self._hosts_cache
|
271
243
|
|
272
|
-
def _get_hosts(self):
|
244
|
+
def _get_hosts(self) -> list[Host]:
|
273
245
|
|
274
|
-
hosts = []
|
275
|
-
seen =
|
246
|
+
hosts: list[Host] = []
|
247
|
+
seen: set[Host] = set()
|
276
248
|
for kid in self.get_descendants(include_self=True, preserve_ordering=True):
|
277
249
|
kid_hosts = kid.hosts
|
278
250
|
for kk in kid_hosts:
|
279
251
|
if kk not in seen:
|
280
|
-
seen
|
252
|
+
seen.add(kk)
|
281
253
|
if self.name == 'all' and kk.implicit:
|
282
254
|
continue
|
283
255
|
hosts.append(kk)
|
284
256
|
return hosts
|
285
257
|
|
286
|
-
def get_vars(self):
|
258
|
+
def get_vars(self) -> dict[str, t.Any]:
|
287
259
|
return self.vars.copy()
|
288
260
|
|
289
|
-
def set_priority(self, priority):
|
261
|
+
def set_priority(self, priority: int | str) -> None:
|
290
262
|
try:
|
291
263
|
self.priority = int(priority)
|
292
264
|
except TypeError:
|
ansible/inventory/helpers.py
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
#############################################
|
19
19
|
from __future__ import annotations
|
20
20
|
|
21
|
+
from ansible._internal._datatag._tags import TrustedAsTemplate
|
21
22
|
from ansible.utils.vars import combine_vars
|
22
23
|
|
23
24
|
|
@@ -37,3 +38,11 @@ def get_group_vars(groups):
|
|
37
38
|
results = combine_vars(results, group.get_vars())
|
38
39
|
|
39
40
|
return results
|
41
|
+
|
42
|
+
|
43
|
+
def remove_trust(value: str) -> str:
|
44
|
+
"""
|
45
|
+
Remove trust from strings which should not be trusted.
|
46
|
+
This exists to centralize the untagging call which facilitate patching it out in unit tests.
|
47
|
+
"""
|
48
|
+
return TrustedAsTemplate.untag(value)
|