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
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import dataclasses
|
|
4
|
+
import typing as t
|
|
5
|
+
|
|
6
|
+
from ansible.module_utils._internal import _datatag, _messages
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclasses.dataclass(**_datatag._tag_dataclass_kwargs)
|
|
10
|
+
class Deprecated(_datatag.AnsibleDatatagBase):
|
|
11
|
+
msg: str
|
|
12
|
+
help_text: t.Optional[str] = None
|
|
13
|
+
date: t.Optional[str] = None
|
|
14
|
+
version: t.Optional[str] = None
|
|
15
|
+
deprecator: t.Optional[_messages.PluginInfo] = None
|
|
16
|
+
formatted_traceback: t.Optional[str] = None
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import pathlib
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def load_params() -> tuple[bytes, str]:
|
|
9
|
+
"""Load module arguments and profile when debugging an Ansible module."""
|
|
10
|
+
parser = argparse.ArgumentParser(description="Directly invoke an Ansible module for debugging.")
|
|
11
|
+
parser.add_argument('args', nargs='?', help='module args JSON (file path or inline string)')
|
|
12
|
+
parser.add_argument('--profile', default='legacy', help='profile for JSON decoding/encoding of args/response')
|
|
13
|
+
|
|
14
|
+
parsed_args = parser.parse_args()
|
|
15
|
+
|
|
16
|
+
args: str | None = parsed_args.args
|
|
17
|
+
profile: str = parsed_args.profile
|
|
18
|
+
|
|
19
|
+
if args:
|
|
20
|
+
if (args_path := pathlib.Path(args)).is_file():
|
|
21
|
+
buffer = args_path.read_bytes()
|
|
22
|
+
else:
|
|
23
|
+
buffer = args.encode(errors='surrogateescape')
|
|
24
|
+
else:
|
|
25
|
+
if sys.stdin.isatty():
|
|
26
|
+
sys.stderr.write('Waiting for Ansible module JSON on STDIN...\n')
|
|
27
|
+
sys.stderr.flush()
|
|
28
|
+
|
|
29
|
+
buffer = sys.stdin.buffer.read()
|
|
30
|
+
|
|
31
|
+
return buffer, profile
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import pathlib
|
|
5
|
+
import sys
|
|
6
|
+
import typing as t
|
|
7
|
+
|
|
8
|
+
from ansible.module_utils._internal import _stack, _messages, _validation, _plugin_info
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def deprecator_from_collection_name(collection_name: str | None) -> _messages.PluginInfo | None:
|
|
12
|
+
"""Returns an instance with the special `collection` type to refer to a non-plugin or ambiguous caller within a collection."""
|
|
13
|
+
# CAUTION: This function is exposed in public API as ansible.module_utils.datatag.deprecator_from_collection_name.
|
|
14
|
+
|
|
15
|
+
if not collection_name:
|
|
16
|
+
return None
|
|
17
|
+
|
|
18
|
+
_validation.validate_collection_name(collection_name)
|
|
19
|
+
|
|
20
|
+
return _messages.PluginInfo(
|
|
21
|
+
resolved_name=collection_name,
|
|
22
|
+
type=None,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_best_deprecator(*, deprecator: _messages.PluginInfo | None = None, collection_name: str | None = None) -> _messages.PluginInfo:
|
|
27
|
+
"""Return the best-available `PluginInfo` for the caller of this method."""
|
|
28
|
+
_skip_stackwalk = True
|
|
29
|
+
|
|
30
|
+
if deprecator and collection_name:
|
|
31
|
+
raise ValueError('Specify only one of `deprecator` or `collection_name`.')
|
|
32
|
+
|
|
33
|
+
return deprecator or deprecator_from_collection_name(collection_name) or get_caller_plugin_info() or INDETERMINATE_DEPRECATOR
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_caller_plugin_info() -> _messages.PluginInfo | None:
|
|
37
|
+
"""Try to get `PluginInfo` for the caller of this method, ignoring marked infrastructure stack frames."""
|
|
38
|
+
_skip_stackwalk = True
|
|
39
|
+
|
|
40
|
+
if frame_info := _stack.caller_frame():
|
|
41
|
+
return _path_as_plugininfo(frame_info.filename)
|
|
42
|
+
|
|
43
|
+
return None # pragma: nocover
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _path_as_plugininfo(path: str) -> _messages.PluginInfo | None:
|
|
47
|
+
"""Return a `PluginInfo` instance if the provided `path` refers to a plugin."""
|
|
48
|
+
return _path_as_core_plugininfo(path) or _path_as_collection_plugininfo(path)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _path_as_core_plugininfo(path: str) -> _messages.PluginInfo | None:
|
|
52
|
+
"""Return a `PluginInfo` instance if the provided `path` refers to a core plugin."""
|
|
53
|
+
try:
|
|
54
|
+
relpath = str(pathlib.Path(path).relative_to(_ANSIBLE_MODULE_BASE_PATH))
|
|
55
|
+
except ValueError:
|
|
56
|
+
return None # not ansible-core
|
|
57
|
+
|
|
58
|
+
namespace = 'ansible.builtin'
|
|
59
|
+
|
|
60
|
+
if match := re.match(r'plugins/(?P<plugin_type>\w+)/(?P<plugin_name>\w+)', relpath):
|
|
61
|
+
plugin_name = match.group("plugin_name")
|
|
62
|
+
plugin_type = _plugin_info.normalize_plugin_type(match.group("plugin_type"))
|
|
63
|
+
|
|
64
|
+
if plugin_type not in _DEPRECATOR_PLUGIN_TYPES:
|
|
65
|
+
# The plugin type isn't a known deprecator type, so we have to assume the caller is intermediate code.
|
|
66
|
+
# We have no way of knowing if the intermediate code is deprecating its own feature, or acting on behalf of another plugin.
|
|
67
|
+
# Callers in this case need to identify the deprecating plugin name, otherwise only ansible-core will be reported.
|
|
68
|
+
# Reporting ansible-core is never wrong, it just may be missing an additional detail (plugin name) in the "on behalf of" case.
|
|
69
|
+
return ANSIBLE_CORE_DEPRECATOR
|
|
70
|
+
|
|
71
|
+
if plugin_name == '__init__':
|
|
72
|
+
# The plugin type is known, but the caller isn't a specific plugin -- instead, it's core plugin infrastructure (the base class).
|
|
73
|
+
return _messages.PluginInfo(resolved_name=namespace, type=plugin_type)
|
|
74
|
+
elif match := re.match(r'modules/(?P<module_name>\w+)', relpath):
|
|
75
|
+
# AnsiballZ Python package for core modules
|
|
76
|
+
plugin_name = match.group("module_name")
|
|
77
|
+
plugin_type = _messages.PluginType.MODULE
|
|
78
|
+
elif match := re.match(r'legacy/(?P<module_name>\w+)', relpath):
|
|
79
|
+
# AnsiballZ Python package for non-core library/role modules
|
|
80
|
+
namespace = 'ansible.legacy'
|
|
81
|
+
|
|
82
|
+
plugin_name = match.group("module_name")
|
|
83
|
+
plugin_type = _messages.PluginType.MODULE
|
|
84
|
+
else:
|
|
85
|
+
return ANSIBLE_CORE_DEPRECATOR # non-plugin core path, safe to use ansible-core for the same reason as the non-deprecator plugin type case above
|
|
86
|
+
|
|
87
|
+
name = f'{namespace}.{plugin_name}'
|
|
88
|
+
|
|
89
|
+
return _messages.PluginInfo(resolved_name=name, type=plugin_type)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _path_as_collection_plugininfo(path: str) -> _messages.PluginInfo | None:
|
|
93
|
+
"""Return a `PluginInfo` instance if the provided `path` refers to a collection plugin."""
|
|
94
|
+
if not (match := re.search(r'/ansible_collections/(?P<ns>\w+)/(?P<coll>\w+)/plugins/(?P<plugin_type>\w+)/(?P<plugin_name>\w+)', path)):
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
plugin_type = _plugin_info.normalize_plugin_type(match.group('plugin_type'))
|
|
98
|
+
|
|
99
|
+
if plugin_type in _AMBIGUOUS_DEPRECATOR_PLUGIN_TYPES:
|
|
100
|
+
# We're able to detect the namespace, collection and plugin type -- but we have no way to identify the plugin name currently.
|
|
101
|
+
# To keep things simple we'll fall back to just identifying the namespace and collection.
|
|
102
|
+
# In the future we could improve the detection and/or make it easier for a caller to identify the plugin name.
|
|
103
|
+
return deprecator_from_collection_name('.'.join((match.group('ns'), match.group('coll'))))
|
|
104
|
+
|
|
105
|
+
if plugin_type not in _DEPRECATOR_PLUGIN_TYPES:
|
|
106
|
+
# The plugin type isn't a known deprecator type, so we have to assume the caller is intermediate code.
|
|
107
|
+
# We have no way of knowing if the intermediate code is deprecating its own feature, or acting on behalf of another plugin.
|
|
108
|
+
# Callers in this case need to identify the deprecator to avoid ambiguity, since it could be the same collection or another collection.
|
|
109
|
+
return INDETERMINATE_DEPRECATOR
|
|
110
|
+
|
|
111
|
+
name = '.'.join((match.group('ns'), match.group('coll'), match.group('plugin_name')))
|
|
112
|
+
|
|
113
|
+
# DTFIX-FUTURE: deprecations from __init__ will be incorrectly attributed to a plugin of that name
|
|
114
|
+
|
|
115
|
+
return _messages.PluginInfo(resolved_name=name, type=plugin_type)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
_ANSIBLE_MODULE_BASE_PATH: t.Final = pathlib.Path(sys.modules['ansible'].__file__).parent
|
|
119
|
+
"""Runtime-detected base path of the `ansible` Python package to distinguish between Ansible-owned and external code."""
|
|
120
|
+
|
|
121
|
+
ANSIBLE_CORE_DEPRECATOR: t.Final = deprecator_from_collection_name('ansible.builtin')
|
|
122
|
+
"""Singleton `PluginInfo` instance for ansible-core callers where the plugin can/should not be identified in messages."""
|
|
123
|
+
|
|
124
|
+
INDETERMINATE_DEPRECATOR: t.Final = _messages.PluginInfo(resolved_name=None, type=None)
|
|
125
|
+
"""Singleton `PluginInfo` instance for indeterminate deprecator."""
|
|
126
|
+
|
|
127
|
+
_DEPRECATOR_PLUGIN_TYPES: t.Final = frozenset(
|
|
128
|
+
{
|
|
129
|
+
_messages.PluginType.ACTION,
|
|
130
|
+
_messages.PluginType.BECOME,
|
|
131
|
+
_messages.PluginType.CACHE,
|
|
132
|
+
_messages.PluginType.CALLBACK,
|
|
133
|
+
_messages.PluginType.CLICONF,
|
|
134
|
+
_messages.PluginType.CONNECTION,
|
|
135
|
+
# DOC_FRAGMENTS - no code execution
|
|
136
|
+
# FILTER - basename inadequate to identify plugin
|
|
137
|
+
_messages.PluginType.HTTPAPI,
|
|
138
|
+
_messages.PluginType.INVENTORY,
|
|
139
|
+
_messages.PluginType.LOOKUP,
|
|
140
|
+
_messages.PluginType.MODULE, # only for collections
|
|
141
|
+
_messages.PluginType.NETCONF,
|
|
142
|
+
_messages.PluginType.SHELL,
|
|
143
|
+
_messages.PluginType.STRATEGY,
|
|
144
|
+
_messages.PluginType.TERMINAL,
|
|
145
|
+
# TEST - basename inadequate to identify plugin
|
|
146
|
+
_messages.PluginType.VARS,
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
"""Plugin types which are valid for identifying a deprecator for deprecation purposes."""
|
|
150
|
+
|
|
151
|
+
_AMBIGUOUS_DEPRECATOR_PLUGIN_TYPES: t.Final = frozenset(
|
|
152
|
+
{
|
|
153
|
+
_messages.PluginType.FILTER,
|
|
154
|
+
_messages.PluginType.TEST,
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
"""Plugin types for which basename cannot be used to identify the plugin name."""
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Copyright (c) 2024 Ansible Project
|
|
2
|
+
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
3
|
+
|
|
4
|
+
"""Internal error handling logic for targets. Not for use on the controller."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations as _annotations
|
|
7
|
+
|
|
8
|
+
import traceback as _sys_traceback
|
|
9
|
+
import typing as _t
|
|
10
|
+
|
|
11
|
+
from . import _messages
|
|
12
|
+
|
|
13
|
+
MSG_REASON_DIRECT_CAUSE: _t.Final[str] = '<<< caused by >>>'
|
|
14
|
+
MSG_REASON_HANDLING_CAUSE: _t.Final[str] = '<<< while handling >>>'
|
|
15
|
+
|
|
16
|
+
TRACEBACK_REASON_EXCEPTION_DIRECT_WARNING: _t.Final[str] = 'The above exception was the direct cause of the following warning:'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class EventFactory:
|
|
20
|
+
"""Factory for creating `Event` instances from `BaseException` instances on targets."""
|
|
21
|
+
|
|
22
|
+
_MAX_DEPTH = 10
|
|
23
|
+
"""Maximum exception chain depth. Exceptions beyond this depth will be omitted."""
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def from_exception(cls, exception: BaseException, include_traceback: bool) -> _messages.Event:
|
|
27
|
+
return cls(include_traceback)._convert_exception(exception)
|
|
28
|
+
|
|
29
|
+
def __init__(self, include_traceback: bool) -> None:
|
|
30
|
+
self._include_traceback = include_traceback
|
|
31
|
+
self._depth = 0
|
|
32
|
+
|
|
33
|
+
def _convert_exception(self, exception: BaseException) -> _messages.Event:
|
|
34
|
+
if self._depth > self._MAX_DEPTH:
|
|
35
|
+
return _messages.Event(
|
|
36
|
+
msg="Maximum depth exceeded, omitting further events.",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
self._depth += 1
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
return _messages.Event(
|
|
43
|
+
msg=self._get_msg(exception),
|
|
44
|
+
formatted_traceback=self._get_formatted_traceback(exception),
|
|
45
|
+
formatted_source_context=self._get_formatted_source_context(exception),
|
|
46
|
+
help_text=self._get_help_text(exception),
|
|
47
|
+
chain=self._get_chain(exception),
|
|
48
|
+
events=self._get_events(exception),
|
|
49
|
+
)
|
|
50
|
+
finally:
|
|
51
|
+
self._depth -= 1
|
|
52
|
+
|
|
53
|
+
def _get_msg(self, exception: BaseException) -> str | None:
|
|
54
|
+
return str(exception).strip()
|
|
55
|
+
|
|
56
|
+
def _get_formatted_traceback(self, exception: BaseException) -> str | None:
|
|
57
|
+
if self._include_traceback:
|
|
58
|
+
return ''.join(_sys_traceback.format_exception(type(exception), exception, exception.__traceback__, chain=False))
|
|
59
|
+
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
def _get_formatted_source_context(self, exception: BaseException) -> str | None:
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
def _get_help_text(self, exception: BaseException) -> str | None:
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
def _get_chain(self, exception: BaseException) -> _messages.EventChain | None:
|
|
69
|
+
if cause := self._get_cause(exception):
|
|
70
|
+
return _messages.EventChain(
|
|
71
|
+
msg_reason=MSG_REASON_DIRECT_CAUSE,
|
|
72
|
+
traceback_reason='The above exception was the direct cause of the following exception:',
|
|
73
|
+
event=self._convert_exception(cause),
|
|
74
|
+
follow=self._follow_cause(exception),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
if context := self._get_context(exception):
|
|
78
|
+
return _messages.EventChain(
|
|
79
|
+
msg_reason=MSG_REASON_HANDLING_CAUSE,
|
|
80
|
+
traceback_reason='During handling of the above exception, another exception occurred:',
|
|
81
|
+
event=self._convert_exception(context),
|
|
82
|
+
follow=False,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
def _follow_cause(self, exception: BaseException) -> bool:
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
def _get_cause(self, exception: BaseException) -> BaseException | None:
|
|
91
|
+
return exception.__cause__
|
|
92
|
+
|
|
93
|
+
def _get_context(self, exception: BaseException) -> BaseException | None:
|
|
94
|
+
if exception.__suppress_context__:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
return exception.__context__
|
|
98
|
+
|
|
99
|
+
def _get_events(self, exception: BaseException) -> tuple[_messages.Event, ...] | None:
|
|
100
|
+
# deprecated: description='move BaseExceptionGroup support here from ControllerEventFactory' python_version='3.10'
|
|
101
|
+
return None
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations as _annotations
|
|
2
|
+
|
|
3
|
+
import typing as _t
|
|
4
|
+
|
|
5
|
+
from ansible.module_utils._internal import _text_utils, _messages
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def deduplicate_message_parts(message_parts: list[str]) -> str:
|
|
9
|
+
"""Format the given list of messages into a brief message, while deduplicating repeated elements."""
|
|
10
|
+
message_parts = list(reversed(message_parts))
|
|
11
|
+
|
|
12
|
+
message = message_parts.pop(0)
|
|
13
|
+
|
|
14
|
+
for message_part in message_parts:
|
|
15
|
+
# avoid duplicate messages where the cause was already concatenated to the exception message
|
|
16
|
+
if message_part.endswith(message):
|
|
17
|
+
message = message_part
|
|
18
|
+
else:
|
|
19
|
+
message = _text_utils.concat_message(message_part, message)
|
|
20
|
+
|
|
21
|
+
return message
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def format_event_brief_message(event: _messages.Event) -> str:
|
|
25
|
+
"""
|
|
26
|
+
Format an event into a brief message.
|
|
27
|
+
Help text, contextual information and sub-events will be omitted.
|
|
28
|
+
"""
|
|
29
|
+
message_parts: list[str] = []
|
|
30
|
+
|
|
31
|
+
while True:
|
|
32
|
+
message_parts.append(event.msg)
|
|
33
|
+
|
|
34
|
+
if not event.chain or not event.chain.follow:
|
|
35
|
+
break
|
|
36
|
+
|
|
37
|
+
event = event.chain.event
|
|
38
|
+
|
|
39
|
+
return deduplicate_message_parts(message_parts)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def deprecation_as_dict(deprecation: _messages.DeprecationSummary) -> _t.Dict[str, _t.Any]:
|
|
43
|
+
"""Returns a dictionary representation of the deprecation object in the format exposed to playbooks."""
|
|
44
|
+
from ansible.module_utils._internal._deprecator import INDETERMINATE_DEPRECATOR # circular import from messages
|
|
45
|
+
|
|
46
|
+
if deprecation.deprecator and deprecation.deprecator != INDETERMINATE_DEPRECATOR:
|
|
47
|
+
collection_name = '.'.join(deprecation.deprecator.resolved_name.split('.')[:2])
|
|
48
|
+
else:
|
|
49
|
+
collection_name = None
|
|
50
|
+
|
|
51
|
+
result = dict(
|
|
52
|
+
msg=format_event_brief_message(deprecation.event),
|
|
53
|
+
collection_name=collection_name,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if deprecation.date:
|
|
57
|
+
result.update(date=deprecation.date)
|
|
58
|
+
else:
|
|
59
|
+
result.update(version=deprecation.version)
|
|
60
|
+
|
|
61
|
+
return result
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import importlib.util
|
|
5
|
+
import types
|
|
6
|
+
|
|
7
|
+
import typing as t
|
|
8
|
+
|
|
9
|
+
from ansible.module_utils._internal._json._profiles import AnsibleProfileJSONEncoder, AnsibleProfileJSONDecoder, _JSONSerializationProfile
|
|
10
|
+
from ansible.module_utils import _internal
|
|
11
|
+
|
|
12
|
+
_T = t.TypeVar('_T', AnsibleProfileJSONEncoder, AnsibleProfileJSONDecoder)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_encoder_decoder(profile: str | types.ModuleType, return_type: type[_T]) -> type[_T]:
|
|
16
|
+
class_name = 'Encoder' if return_type is AnsibleProfileJSONEncoder else 'Decoder'
|
|
17
|
+
|
|
18
|
+
return getattr(get_serialization_module(profile), class_name)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_module_serialization_profile_name(name: str, controller_to_module: bool) -> str:
|
|
22
|
+
if controller_to_module:
|
|
23
|
+
name = f'module_{name}_c2m'
|
|
24
|
+
else:
|
|
25
|
+
name = f'module_{name}_m2c'
|
|
26
|
+
|
|
27
|
+
return name
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_module_serialization_profile_module_name(name: str, controller_to_module: bool) -> str:
|
|
31
|
+
return get_serialization_module_name(get_module_serialization_profile_name(name, controller_to_module))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_serialization_profile(name: str | types.ModuleType) -> _JSONSerializationProfile:
|
|
35
|
+
return getattr(get_serialization_module(name), '_Profile')
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_serialization_module(name: str | types.ModuleType) -> types.ModuleType:
|
|
39
|
+
return importlib.import_module(get_serialization_module_name(name))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_serialization_module_name(name: str | types.ModuleType) -> str:
|
|
43
|
+
if isinstance(name, str):
|
|
44
|
+
if '.' in name:
|
|
45
|
+
return name # name is already fully qualified
|
|
46
|
+
|
|
47
|
+
target_name = f'{__name__}._profiles._{name}'
|
|
48
|
+
elif isinstance(name, types.ModuleType):
|
|
49
|
+
return name.__name__
|
|
50
|
+
else:
|
|
51
|
+
raise TypeError(f'Name is {type(name)} instead of {str} or {types.ModuleType}.')
|
|
52
|
+
|
|
53
|
+
if importlib.util.find_spec(target_name):
|
|
54
|
+
return target_name
|
|
55
|
+
|
|
56
|
+
# the value of is_controller can change after import; always pick it up from the module
|
|
57
|
+
if _internal.is_controller:
|
|
58
|
+
controller_name = f'ansible._internal._json._profiles._{name}'
|
|
59
|
+
|
|
60
|
+
if importlib.util.find_spec(controller_name):
|
|
61
|
+
return controller_name
|
|
62
|
+
|
|
63
|
+
raise ValueError(f'Unknown profile name {name!r}.')
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ansible.module_utils._internal._json import _profiles
|
|
4
|
+
from ansible.module_utils._internal._json._profiles import _tagless
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LegacyTargetJSONEncoder(_tagless.Encoder):
|
|
8
|
+
"""Compatibility wrapper over `legacy` profile JSON encoder to support trust stripping and vault value plaintext conversion."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, preprocess_unsafe: bool = False, vault_to_text: bool = False, _decode_bytes: bool = False, **kwargs) -> None:
|
|
11
|
+
self._decode_bytes = _decode_bytes
|
|
12
|
+
|
|
13
|
+
# NOTE: The preprocess_unsafe and vault_to_text arguments are features of LegacyControllerJSONEncoder.
|
|
14
|
+
# They are implemented here to allow callers to pass them without raising an error, but they have no effect.
|
|
15
|
+
|
|
16
|
+
super().__init__(**kwargs)
|
|
17
|
+
|
|
18
|
+
def default(self, o: object) -> object:
|
|
19
|
+
if self._decode_bytes:
|
|
20
|
+
if type(o) is _profiles._WrappedValue: # pylint: disable=unidiomatic-typecheck
|
|
21
|
+
o = o.wrapped
|
|
22
|
+
|
|
23
|
+
if isinstance(o, bytes):
|
|
24
|
+
return o.decode(errors='surrogateescape') # backward compatibility with `ansible.module_utils.basic.jsonify`
|
|
25
|
+
|
|
26
|
+
return super().default(o)
|