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
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
# Copyright (c) 2018, Ansible Project
|
|
2
2
|
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
3
|
-
|
|
4
|
-
|
|
5
3
|
"""
|
|
6
4
|
Modules in _utils are waiting to find a better home. If you need to use them, be prepared for them
|
|
7
5
|
to move to a different location in the future.
|
|
8
6
|
"""
|
|
7
|
+
|
|
9
8
|
from __future__ import annotations
|
|
10
9
|
|
|
10
|
+
import inspect
|
|
11
|
+
import typing as t
|
|
12
|
+
|
|
13
|
+
_Type = t.TypeVar('_Type')
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_all_subclasses(cls: type[_Type], *, include_abstract: bool = True, consider_self: bool = False) -> set[type[_Type]]:
|
|
17
|
+
"""Recursively find all subclasses of a given type, including abstract classes by default."""
|
|
18
|
+
subclasses: set[type[_Type]] = {cls} if consider_self else set()
|
|
19
|
+
queue: list[type[_Type]] = [cls]
|
|
20
|
+
|
|
21
|
+
while queue:
|
|
22
|
+
parent = queue.pop()
|
|
23
|
+
|
|
24
|
+
for child in parent.__subclasses__():
|
|
25
|
+
if child in subclasses:
|
|
26
|
+
continue
|
|
27
|
+
|
|
28
|
+
queue.append(child)
|
|
29
|
+
subclasses.add(child)
|
|
30
|
+
|
|
31
|
+
if not include_abstract:
|
|
32
|
+
subclasses = {sc for sc in subclasses if not inspect.isabstract(sc)}
|
|
11
33
|
|
|
12
|
-
def get_all_subclasses(cls):
|
|
13
|
-
'''
|
|
14
|
-
Recursively search and find all subclasses of a given class
|
|
15
|
-
|
|
16
|
-
:arg cls: A python class
|
|
17
|
-
:rtype: set
|
|
18
|
-
:returns: The set of python classes which are the subclasses of `cls`.
|
|
19
|
-
|
|
20
|
-
In python, you can use a class's :py:meth:`__subclasses__` method to determine what subclasses
|
|
21
|
-
of a class exist. However, `__subclasses__` only goes one level deep. This function searches
|
|
22
|
-
each child class's `__subclasses__` method to find all of the descendent classes. It then
|
|
23
|
-
returns an iterable of the descendent classes.
|
|
24
|
-
'''
|
|
25
|
-
# Retrieve direct subclasses
|
|
26
|
-
subclasses = set(cls.__subclasses__())
|
|
27
|
-
to_visit = list(subclasses)
|
|
28
|
-
# Then visit all subclasses
|
|
29
|
-
while to_visit:
|
|
30
|
-
for sc in to_visit:
|
|
31
|
-
# The current class is now visited, so remove it from list
|
|
32
|
-
to_visit.remove(sc)
|
|
33
|
-
# Appending all subclasses to visit and keep a reference of available class
|
|
34
|
-
for ssc in sc.__subclasses__():
|
|
35
|
-
if ssc not in subclasses:
|
|
36
|
-
to_visit.append(ssc)
|
|
37
|
-
subclasses.add(ssc)
|
|
38
34
|
return subclasses
|
|
@@ -6,6 +6,7 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
from copy import deepcopy
|
|
8
8
|
|
|
9
|
+
from ansible.module_utils.datatag import deprecator_from_collection_name
|
|
9
10
|
from ansible.module_utils.common.parameters import (
|
|
10
11
|
_ADDITIONAL_CHECKS,
|
|
11
12
|
_get_legal_inputs,
|
|
@@ -300,9 +301,13 @@ class ModuleArgumentSpecValidator(ArgumentSpecValidator):
|
|
|
300
301
|
result = super(ModuleArgumentSpecValidator, self).validate(parameters)
|
|
301
302
|
|
|
302
303
|
for d in result._deprecations:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
304
|
+
# DTFIX-FUTURE: pass an actual deprecator instead of one derived from collection_name
|
|
305
|
+
deprecate( # pylint: disable=ansible-deprecated-date-not-permitted,ansible-deprecated-unnecessary-collection-name
|
|
306
|
+
msg=d['msg'],
|
|
307
|
+
version=d.get('version'),
|
|
308
|
+
date=d.get('date'),
|
|
309
|
+
deprecator=deprecator_from_collection_name(d.get('collection_name')),
|
|
310
|
+
)
|
|
306
311
|
|
|
307
312
|
for w in result._warnings:
|
|
308
313
|
warn('Both option {option} and its alias {alias} are set.'.format(option=w['option'], alias=w['alias']))
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
from ansible.module_utils.common import warnings as _warnings
|
|
9
10
|
from ansible.module_utils.six import binary_type, text_type
|
|
10
11
|
from ansible.module_utils.six.moves.collections_abc import Hashable, Mapping, MutableMapping, Sequence # pylint: disable=unused-import
|
|
11
12
|
|
|
@@ -66,8 +67,7 @@ class ImmutableDict(Hashable, Mapping):
|
|
|
66
67
|
|
|
67
68
|
def is_string(seq):
|
|
68
69
|
"""Identify whether the input has a string-like type (including bytes)."""
|
|
69
|
-
|
|
70
|
-
return isinstance(seq, (text_type, binary_type)) or getattr(seq, '__ENCRYPTED__', False)
|
|
70
|
+
return isinstance(seq, (text_type, binary_type))
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def is_iterable(seq, include_strings=False):
|
|
@@ -103,6 +103,11 @@ def count(seq):
|
|
|
103
103
|
code is run on Python 2.6.* where collections.Counter is not available. It should be
|
|
104
104
|
deprecated and replaced when support for Python < 2.7 is dropped.
|
|
105
105
|
"""
|
|
106
|
+
_warnings.deprecate(
|
|
107
|
+
msg="The `ansible.module_utils.common.collections.count` function is deprecated.",
|
|
108
|
+
version="2.23",
|
|
109
|
+
help_text="Use `collections.Counter` from the Python standard library instead.",
|
|
110
|
+
)
|
|
106
111
|
if not is_iterable(seq):
|
|
107
112
|
raise Exception('Argument provided is not an iterable')
|
|
108
113
|
counters = dict()
|
|
@@ -109,9 +109,9 @@ def _camel_to_snake(name, reversible=False):
|
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
def dict_merge(a, b):
|
|
112
|
-
|
|
112
|
+
"""recursively merges dicts. not just simple a['key'] = b['key'], if
|
|
113
113
|
both a and b have a key whose value is a dict then dict_merge is called
|
|
114
|
-
on both values and the result stored in the returned dictionary.
|
|
114
|
+
on both values and the result stored in the returned dictionary."""
|
|
115
115
|
if not isinstance(b, dict):
|
|
116
116
|
return b
|
|
117
117
|
result = deepcopy(a)
|
|
@@ -55,7 +55,7 @@ def is_executable(path):
|
|
|
55
55
|
# This method is reused by the basic module,
|
|
56
56
|
# the repetition helps the basic module's html documentation come out right.
|
|
57
57
|
# http://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_docstring_signature
|
|
58
|
-
|
|
58
|
+
"""is_executable(path)
|
|
59
59
|
|
|
60
60
|
is the given path executable?
|
|
61
61
|
|
|
@@ -66,7 +66,7 @@ def is_executable(path):
|
|
|
66
66
|
* Does not account for FSACLs.
|
|
67
67
|
* Most times we really want to know "Can the current user execute this
|
|
68
68
|
file". This function does not tell us that, only if any execute bit is set.
|
|
69
|
-
|
|
69
|
+
"""
|
|
70
70
|
# These are all bitfields so first bitwise-or all the permissions we're
|
|
71
71
|
# looking for, then bitwise-and with the file's mode to determine if any
|
|
72
72
|
# execute bits are set.
|
|
@@ -1,84 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
from ansible.module_utils.
|
|
12
|
-
from ansible.module_utils.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
1
|
+
from __future__ import annotations as _annotations
|
|
2
|
+
|
|
3
|
+
import enum as _enum
|
|
4
|
+
import json as _stdlib_json
|
|
5
|
+
import types as _types
|
|
6
|
+
|
|
7
|
+
from ansible.module_utils import _internal
|
|
8
|
+
from ansible.module_utils._internal import _json
|
|
9
|
+
from ansible.module_utils._internal._json import _legacy_encoder
|
|
10
|
+
from ansible.module_utils._internal._json import _profiles
|
|
11
|
+
from ansible.module_utils._internal._json._profiles import _tagless
|
|
12
|
+
from ansible.module_utils.common import warnings as _warnings
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def __getattr__(name: str) -> object:
|
|
16
|
+
"""Handle dynamic module members which are or will be deprecated."""
|
|
17
|
+
if name in ('AnsibleJSONEncoder', '_AnsibleJSONEncoder'):
|
|
18
|
+
# deprecated: description='deprecate legacy encoder' core_version='2.23'
|
|
19
|
+
# if not name.startswith('_'): # avoid duplicate deprecation warning for imports from ajson
|
|
20
|
+
# _warnings.deprecate(
|
|
21
|
+
# msg="The `AnsibleJSONEncoder` type is deprecated.",
|
|
22
|
+
# version="2.27",
|
|
23
|
+
# help_text="Use a profile-based encoder instead.", # DTFIX-FUTURE: improve this help text
|
|
24
|
+
# )
|
|
25
|
+
|
|
26
|
+
return _get_legacy_encoder()
|
|
27
|
+
|
|
28
|
+
if name in ('AnsibleJSONDecoder', '_AnsibleJSONDecoder'):
|
|
29
|
+
# deprecated: description='deprecate legacy decoder' core_version='2.23'
|
|
30
|
+
# if not name.startswith('_'): # avoid duplicate deprecation warning for imports from ajson
|
|
31
|
+
# _warnings.deprecate(
|
|
32
|
+
# msg="The `AnsibleJSONDecoder` type is deprecated.",
|
|
33
|
+
# version="2.27",
|
|
34
|
+
# help_text="Use a profile-based decoder instead.", # DTFIX-FUTURE: improve this help text
|
|
35
|
+
# )
|
|
36
|
+
|
|
37
|
+
return _tagless.Decoder
|
|
38
|
+
|
|
39
|
+
if name == 'json_dump':
|
|
40
|
+
_warnings.deprecate(
|
|
41
|
+
msg="The `json_dump` function is deprecated.",
|
|
42
|
+
version="2.23",
|
|
43
|
+
help_text="Use `json.dumps` with the appropriate `cls` instead.",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return _json_dump
|
|
47
|
+
|
|
48
|
+
raise AttributeError(name)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _get_legacy_encoder() -> type[_stdlib_json.JSONEncoder]:
|
|
52
|
+
"""Compatibility hack: previous module_utils AnsibleJSONEncoder impl did controller-side work, controller plugins require a more fully-featured impl."""
|
|
53
|
+
if _internal.is_controller:
|
|
54
|
+
return _internal.import_controller_module('ansible._internal._json._legacy_encoder').LegacyControllerJSONEncoder
|
|
55
|
+
|
|
56
|
+
return _legacy_encoder.LegacyTargetJSONEncoder
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _json_dump(structure):
|
|
60
|
+
"""JSON dumping function maintained for temporary backward compatibility."""
|
|
61
|
+
return _stdlib_json.dumps(structure, cls=_get_legacy_encoder(), sort_keys=True, indent=4)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Direction(_enum.Enum):
|
|
65
|
+
"""Enumeration used to select a contextually-appropriate JSON profile for module messaging."""
|
|
66
|
+
|
|
67
|
+
CONTROLLER_TO_MODULE = _enum.auto()
|
|
68
|
+
"""Encode/decode messages from the Ansible controller to an Ansible module."""
|
|
69
|
+
MODULE_TO_CONTROLLER = _enum.auto()
|
|
70
|
+
"""Encode/decode messages from an Ansible module to the Ansible controller."""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_encoder(profile: str | _types.ModuleType, /) -> type[_stdlib_json.JSONEncoder]:
|
|
74
|
+
"""Return a `JSONEncoder` for the given `profile`."""
|
|
75
|
+
return _json.get_encoder_decoder(profile, _profiles.AnsibleProfileJSONEncoder)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_decoder(profile: str | _types.ModuleType, /) -> type[_stdlib_json.JSONDecoder]:
|
|
79
|
+
"""Return a `JSONDecoder` for the given `profile`."""
|
|
80
|
+
return _json.get_encoder_decoder(profile, _profiles.AnsibleProfileJSONDecoder)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def get_module_encoder(name: str, direction: Direction, /) -> type[_stdlib_json.JSONEncoder]:
|
|
84
|
+
"""Return a `JSONEncoder` for the module profile specified by `name` and `direction`."""
|
|
85
|
+
return get_encoder(_json.get_module_serialization_profile_name(name, direction == Direction.CONTROLLER_TO_MODULE))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def get_module_decoder(name: str, direction: Direction, /) -> type[_stdlib_json.JSONDecoder]:
|
|
89
|
+
"""Return a `JSONDecoder` for the module profile specified by `name` and `direction`."""
|
|
90
|
+
return get_decoder(_json.get_module_serialization_profile_name(name, direction == Direction.CONTROLLER_TO_MODULE))
|
|
@@ -7,7 +7,7 @@ from ansible.module_utils.common.text.converters import to_native
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def get_best_parsable_locale(module, preferences=None, raise_on_locale=False):
|
|
10
|
-
|
|
10
|
+
"""
|
|
11
11
|
Attempts to return the best possible locale for parsing output in English
|
|
12
12
|
useful for scraping output with i18n tools. When this raises an exception
|
|
13
13
|
and the caller wants to continue, it should use the 'C' locale.
|
|
@@ -17,7 +17,7 @@ def get_best_parsable_locale(module, preferences=None, raise_on_locale=False):
|
|
|
17
17
|
:param raise_on_locale: boolean that determines if we raise exception or not
|
|
18
18
|
due to locale CLI issues
|
|
19
19
|
:returns: The first matched preferred locale or 'C' which is the default
|
|
20
|
-
|
|
20
|
+
"""
|
|
21
21
|
|
|
22
22
|
found = 'C' # default posix, its ascii but always there
|
|
23
23
|
try:
|
|
@@ -6,13 +6,16 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import datetime
|
|
8
8
|
import os
|
|
9
|
+
import typing as t
|
|
9
10
|
|
|
10
11
|
from collections import deque
|
|
11
12
|
from itertools import chain
|
|
12
13
|
|
|
13
14
|
from ansible.module_utils.common.collections import is_iterable
|
|
15
|
+
from ansible.module_utils._internal._datatag import AnsibleSerializable, AnsibleTagHelper
|
|
14
16
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
15
17
|
from ansible.module_utils.common.warnings import warn
|
|
18
|
+
from ansible.module_utils.datatag import native_type_name
|
|
16
19
|
from ansible.module_utils.errors import (
|
|
17
20
|
AliasError,
|
|
18
21
|
AnsibleFallbackNotFound,
|
|
@@ -83,7 +86,7 @@ _ADDITIONAL_CHECKS = (
|
|
|
83
86
|
# if adding boolean attribute, also add to PASS_BOOL
|
|
84
87
|
# some of this dupes defaults from controller config
|
|
85
88
|
# keep in sync with copy in lib/ansible/module_utils/csharp/Ansible.Basic.cs
|
|
86
|
-
PASS_VARS = {
|
|
89
|
+
PASS_VARS: dict[str, t.Any] = {
|
|
87
90
|
'check_mode': ('check_mode', False),
|
|
88
91
|
'debug': ('_debug', False),
|
|
89
92
|
'diff': ('_diff', False),
|
|
@@ -96,9 +99,9 @@ PASS_VARS = {
|
|
|
96
99
|
'selinux_special_fs': ('_selinux_special_fs', ['fuse', 'nfs', 'vboxsf', 'ramfs', '9p', 'vfat']),
|
|
97
100
|
'shell_executable': ('_shell', '/bin/sh'),
|
|
98
101
|
'socket': ('_socket_path', None),
|
|
99
|
-
'string_conversion_action': ('_string_conversion_action', 'warn'),
|
|
100
102
|
'syslog_facility': ('_syslog_facility', 'INFO'),
|
|
101
103
|
'tmpdir': ('_tmpdir', None),
|
|
104
|
+
'tracebacks_for': ('_tracebacks_for', frozenset()),
|
|
102
105
|
'verbosity': ('_verbosity', 0),
|
|
103
106
|
'version': ('ansible_version', '0.0'),
|
|
104
107
|
}
|
|
@@ -408,6 +411,8 @@ def _remove_values_conditions(value, no_log_strings, deferred_removals):
|
|
|
408
411
|
dictionary for ``level1``, then the dict for ``level2``, and finally
|
|
409
412
|
the list for ``level3``.
|
|
410
413
|
"""
|
|
414
|
+
original_value = value
|
|
415
|
+
|
|
411
416
|
if isinstance(value, (text_type, binary_type)):
|
|
412
417
|
# Need native str type
|
|
413
418
|
native_str_value = value
|
|
@@ -432,31 +437,25 @@ def _remove_values_conditions(value, no_log_strings, deferred_removals):
|
|
|
432
437
|
else:
|
|
433
438
|
value = native_str_value
|
|
434
439
|
|
|
440
|
+
elif value is True or value is False or value is None:
|
|
441
|
+
return value
|
|
442
|
+
|
|
435
443
|
elif isinstance(value, Sequence):
|
|
436
|
-
|
|
437
|
-
new_value = type(value)()
|
|
438
|
-
else:
|
|
439
|
-
new_value = [] # Need a mutable value
|
|
444
|
+
new_value = AnsibleTagHelper.tag_copy(original_value, [])
|
|
440
445
|
deferred_removals.append((value, new_value))
|
|
441
|
-
|
|
446
|
+
return new_value
|
|
442
447
|
|
|
443
448
|
elif isinstance(value, Set):
|
|
444
|
-
|
|
445
|
-
new_value = type(value)()
|
|
446
|
-
else:
|
|
447
|
-
new_value = set() # Need a mutable value
|
|
449
|
+
new_value = AnsibleTagHelper.tag_copy(original_value, set())
|
|
448
450
|
deferred_removals.append((value, new_value))
|
|
449
|
-
|
|
451
|
+
return new_value
|
|
450
452
|
|
|
451
453
|
elif isinstance(value, Mapping):
|
|
452
|
-
|
|
453
|
-
new_value = type(value)()
|
|
454
|
-
else:
|
|
455
|
-
new_value = {} # Need a mutable value
|
|
454
|
+
new_value = AnsibleTagHelper.tag_copy(original_value, {})
|
|
456
455
|
deferred_removals.append((value, new_value))
|
|
457
|
-
|
|
456
|
+
return new_value
|
|
458
457
|
|
|
459
|
-
elif isinstance(value,
|
|
458
|
+
elif isinstance(value, (int, float)):
|
|
460
459
|
stringy_value = to_native(value, encoding='utf-8', errors='surrogate_or_strict')
|
|
461
460
|
if stringy_value in no_log_strings:
|
|
462
461
|
return 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER'
|
|
@@ -464,11 +463,15 @@ def _remove_values_conditions(value, no_log_strings, deferred_removals):
|
|
|
464
463
|
if omit_me in stringy_value:
|
|
465
464
|
return 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER'
|
|
466
465
|
|
|
467
|
-
elif isinstance(value, (datetime.datetime, datetime.date)):
|
|
468
|
-
|
|
466
|
+
elif isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
|
|
467
|
+
return value
|
|
468
|
+
elif isinstance(value, AnsibleSerializable):
|
|
469
|
+
return value
|
|
469
470
|
else:
|
|
470
471
|
raise TypeError('Value of unknown type: %s, %s' % (type(value), value))
|
|
471
472
|
|
|
473
|
+
value = AnsibleTagHelper.tag_copy(original_value, value)
|
|
474
|
+
|
|
472
475
|
return value
|
|
473
476
|
|
|
474
477
|
|
|
@@ -541,7 +544,7 @@ def _sanitize_keys_conditions(value, no_log_strings, ignore_keys, deferred_remov
|
|
|
541
544
|
if isinstance(value, tuple(chain(integer_types, (float, bool, NoneType)))):
|
|
542
545
|
return value
|
|
543
546
|
|
|
544
|
-
if isinstance(value, (datetime.datetime, datetime.date)):
|
|
547
|
+
if isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
|
|
545
548
|
return value
|
|
546
549
|
|
|
547
550
|
raise TypeError('Value of unknown type: %s, %s' % (type(value), value))
|
|
@@ -570,7 +573,7 @@ def _validate_elements(wanted_type, parameter, values, options_context=None, err
|
|
|
570
573
|
msg = "Elements value for option '%s'" % parameter
|
|
571
574
|
if options_context:
|
|
572
575
|
msg += " found in '%s'" % " -> ".join(options_context)
|
|
573
|
-
msg += " is of type %s and we were unable to convert to %s: %s" % (
|
|
576
|
+
msg += " is of type %s and we were unable to convert to %s: %s" % (native_type_name(value), wanted_element_type, to_native(e))
|
|
574
577
|
errors.append(ElementError(msg))
|
|
575
578
|
return validated_parameters
|
|
576
579
|
|
|
@@ -629,7 +632,7 @@ def _validate_argument_types(argument_spec, parameters, prefix='', options_conte
|
|
|
629
632
|
elements_wanted_type = spec.get('elements', None)
|
|
630
633
|
if elements_wanted_type:
|
|
631
634
|
elements = parameters[param]
|
|
632
|
-
if
|
|
635
|
+
if not isinstance(parameters[param], list) or not isinstance(elements, list):
|
|
633
636
|
msg = "Invalid type %s for option '%s'" % (wanted_name, elements)
|
|
634
637
|
if options_context:
|
|
635
638
|
msg += " found in '%s'." % " -> ".join(options_context)
|
|
@@ -638,7 +641,7 @@ def _validate_argument_types(argument_spec, parameters, prefix='', options_conte
|
|
|
638
641
|
parameters[param] = _validate_elements(elements_wanted_type, param, elements, options_context, errors)
|
|
639
642
|
|
|
640
643
|
except (TypeError, ValueError) as e:
|
|
641
|
-
msg = "argument '%s' is of type %s" % (param,
|
|
644
|
+
msg = "argument '%s' is of type %s" % (param, native_type_name(value))
|
|
642
645
|
if options_context:
|
|
643
646
|
msg += " found in '%s'." % " -> ".join(options_context)
|
|
644
647
|
msg += " and we were unable to convert to %s: %s" % (wanted_name, to_native(e))
|
|
@@ -10,7 +10,7 @@ from ansible.module_utils.common.warnings import deprecate
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def get_bin_path(arg, opt_dirs=None, required=None):
|
|
13
|
-
|
|
13
|
+
"""
|
|
14
14
|
Find system executable in PATH. Raises ValueError if the executable is not found.
|
|
15
15
|
|
|
16
16
|
:param arg: the executable to find
|
|
@@ -24,12 +24,11 @@ def get_bin_path(arg, opt_dirs=None, required=None):
|
|
|
24
24
|
|
|
25
25
|
In addition to PATH and opt_dirs, this function also looks through /sbin, /usr/sbin and /usr/local/sbin. A lot of
|
|
26
26
|
modules, especially for gathering facts, depend on this behaviour.
|
|
27
|
-
|
|
27
|
+
"""
|
|
28
28
|
if required is not None:
|
|
29
29
|
deprecate(
|
|
30
30
|
msg="The `required` parameter in `get_bin_path` API is deprecated.",
|
|
31
31
|
version="2.21",
|
|
32
|
-
collection_name="ansible.builtin",
|
|
33
32
|
)
|
|
34
33
|
|
|
35
34
|
paths = []
|
|
@@ -7,8 +7,10 @@ import os
|
|
|
7
7
|
import pathlib
|
|
8
8
|
import subprocess
|
|
9
9
|
import sys
|
|
10
|
+
import typing as t
|
|
10
11
|
|
|
11
12
|
from ansible.module_utils.common.text.converters import to_bytes
|
|
13
|
+
from ansible.module_utils._internal._ansiballz import _respawn
|
|
12
14
|
|
|
13
15
|
_ANSIBLE_PARENT_PATH = pathlib.Path(__file__).parents[3]
|
|
14
16
|
|
|
@@ -17,7 +19,7 @@ def has_respawned():
|
|
|
17
19
|
return hasattr(sys.modules['__main__'], '_respawned')
|
|
18
20
|
|
|
19
21
|
|
|
20
|
-
def respawn_module(interpreter_path):
|
|
22
|
+
def respawn_module(interpreter_path) -> t.NoReturn:
|
|
21
23
|
"""
|
|
22
24
|
Respawn the currently-running Ansible Python module under the specified Python interpreter.
|
|
23
25
|
|
|
@@ -38,7 +40,7 @@ def respawn_module(interpreter_path):
|
|
|
38
40
|
raise Exception('module has already been respawned')
|
|
39
41
|
|
|
40
42
|
# FUTURE: we need a safe way to log that a respawn has occurred for forensic/debug purposes
|
|
41
|
-
payload =
|
|
43
|
+
payload = _respawn.create_payload()
|
|
42
44
|
stdin_read, stdin_write = os.pipe()
|
|
43
45
|
os.write(stdin_write, to_bytes(payload))
|
|
44
46
|
os.close(stdin_write)
|
|
@@ -55,10 +57,15 @@ def probe_interpreters_for_module(interpreter_paths, module_name):
|
|
|
55
57
|
:arg interpreter_paths: iterable of paths to Python interpreters. The paths will be probed
|
|
56
58
|
in order, and the first path that exists and can successfully import the named module will
|
|
57
59
|
be returned (or ``None`` if probing fails for all supplied paths).
|
|
58
|
-
:arg module_name: fully-qualified Python module name to probe for (
|
|
60
|
+
:arg module_name: fully-qualified Python module name to probe for (for example, ``selinux``)
|
|
59
61
|
"""
|
|
60
62
|
PYTHONPATH = os.getenv('PYTHONPATH', '')
|
|
61
|
-
|
|
63
|
+
|
|
64
|
+
env = os.environ.copy()
|
|
65
|
+
env.update({
|
|
66
|
+
'PYTHONPATH': f'{_ANSIBLE_PARENT_PATH}:{PYTHONPATH}'.rstrip(': ')
|
|
67
|
+
})
|
|
68
|
+
|
|
62
69
|
for interpreter_path in interpreter_paths:
|
|
63
70
|
if not os.path.exists(interpreter_path):
|
|
64
71
|
continue
|
|
@@ -77,32 +84,3 @@ def probe_interpreters_for_module(interpreter_paths, module_name):
|
|
|
77
84
|
continue
|
|
78
85
|
|
|
79
86
|
return None
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def _create_payload():
|
|
83
|
-
from ansible.module_utils import basic
|
|
84
|
-
smuggled_args = getattr(basic, '_ANSIBLE_ARGS')
|
|
85
|
-
if not smuggled_args:
|
|
86
|
-
raise Exception('unable to access ansible.module_utils.basic._ANSIBLE_ARGS (not launched by AnsiballZ?)')
|
|
87
|
-
module_fqn = sys.modules['__main__']._module_fqn
|
|
88
|
-
modlib_path = sys.modules['__main__']._modlib_path
|
|
89
|
-
respawn_code_template = '''
|
|
90
|
-
import runpy
|
|
91
|
-
import sys
|
|
92
|
-
|
|
93
|
-
module_fqn = {module_fqn!r}
|
|
94
|
-
modlib_path = {modlib_path!r}
|
|
95
|
-
smuggled_args = {smuggled_args!r}
|
|
96
|
-
|
|
97
|
-
if __name__ == '__main__':
|
|
98
|
-
sys.path.insert(0, modlib_path)
|
|
99
|
-
|
|
100
|
-
from ansible.module_utils import basic
|
|
101
|
-
basic._ANSIBLE_ARGS = smuggled_args
|
|
102
|
-
|
|
103
|
-
runpy.run_module(module_fqn, init_globals=dict(_respawned=True), run_name='__main__', alter_sys=True)
|
|
104
|
-
'''
|
|
105
|
-
|
|
106
|
-
respawn_code = respawn_code_template.format(module_fqn=module_fqn, modlib_path=modlib_path, smuggled_args=smuggled_args.strip())
|
|
107
|
-
|
|
108
|
-
return respawn_code
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Copyright (c) 2019 Ansible Project
|
|
2
|
+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Sentinel:
|
|
8
|
+
"""
|
|
9
|
+
Object which can be used to mark whether an entry as being special
|
|
10
|
+
|
|
11
|
+
A sentinel value demarcates a value or marks an entry as having a special meaning. In C, the
|
|
12
|
+
Null byte is used as a sentinel for the end of a string. In Python, None is often used as
|
|
13
|
+
a Sentinel in optional parameters to mean that the parameter was not set by the user.
|
|
14
|
+
|
|
15
|
+
You should use None as a Sentinel value any Python code where None is not a valid entry. If
|
|
16
|
+
None is a valid entry, though, then you need to create a different value, which is the purpose
|
|
17
|
+
of this class.
|
|
18
|
+
|
|
19
|
+
Example of using Sentinel as a default parameter value::
|
|
20
|
+
|
|
21
|
+
def confirm_big_red_button(tristate=Sentinel):
|
|
22
|
+
if tristate is Sentinel:
|
|
23
|
+
print('You must explicitly press the big red button to blow up the base')
|
|
24
|
+
elif tristate is True:
|
|
25
|
+
print('Countdown to destruction activated')
|
|
26
|
+
elif tristate is False:
|
|
27
|
+
print('Countdown stopped')
|
|
28
|
+
elif tristate is None:
|
|
29
|
+
print('Waiting for more input')
|
|
30
|
+
|
|
31
|
+
Example of using Sentinel to tell whether a dict which has a default value has been changed::
|
|
32
|
+
|
|
33
|
+
values = {'one': Sentinel, 'two': Sentinel}
|
|
34
|
+
defaults = {'one': 1, 'two': 2}
|
|
35
|
+
|
|
36
|
+
# [.. Other code which does things including setting a new value for 'one' ..]
|
|
37
|
+
values['one'] = None
|
|
38
|
+
# [..]
|
|
39
|
+
|
|
40
|
+
print('You made changes to:')
|
|
41
|
+
for key, value in values.items():
|
|
42
|
+
if value is Sentinel:
|
|
43
|
+
continue
|
|
44
|
+
print('%s: %s' % (key, value)
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __new__(cls):
|
|
48
|
+
"""
|
|
49
|
+
Return the cls itself. This makes both equality and identity True for comparing the class
|
|
50
|
+
to an instance of the class, preventing common usage errors.
|
|
51
|
+
|
|
52
|
+
Preferred usage::
|
|
53
|
+
|
|
54
|
+
a = Sentinel
|
|
55
|
+
if a is Sentinel:
|
|
56
|
+
print('Sentinel value')
|
|
57
|
+
|
|
58
|
+
However, these are True as well, eliminating common usage errors::
|
|
59
|
+
|
|
60
|
+
if Sentinel is Sentinel():
|
|
61
|
+
print('Sentinel value')
|
|
62
|
+
|
|
63
|
+
if Sentinel == Sentinel():
|
|
64
|
+
print('Sentinel value')
|
|
65
|
+
"""
|
|
66
|
+
return cls
|