ansible-core 2.18.4rc1__py3-none-any.whl → 2.19.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +160 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +198 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +351 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +62 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +153 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +48 -46
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +165 -108
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +136 -76
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +237 -236
- ansible/executor/task_queue_manager.py +62 -38
- ansible/executor/task_result.py +21 -12
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +77 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +154 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +86 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +1 -1
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +4 -4
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +9 -8
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +52 -17
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +20 -18
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +7 -7
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +35 -49
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +39 -32
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +36 -339
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +6 -15
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +4 -5
- ansible/plugins/action/gather_facts.py +8 -7
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +35 -44
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +141 -123
- ansible/plugins/callback/default.py +30 -23
- ansible/plugins/callback/junit.py +28 -24
- ansible/plugins/callback/minimal.py +17 -14
- ansible/plugins/callback/oneline.py +13 -7
- ansible/plugins/callback/tree.py +10 -6
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +6 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +218 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +2 -2
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +97 -77
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +86 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +94 -113
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +13 -28
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +31 -33
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +54 -20
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +368 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +428 -58
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +28 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +4 -4
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +205 -264
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/WHEEL +1 -1
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -0
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +1 -0
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +2 -1
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +4 -0
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +1 -0
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +16 -1
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +24 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +2 -0
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/delegation.py +1 -0
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +35 -27
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/utils/jsonify.py +0 -36
- 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.4rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
ansible/parsing/plugin_docs.py
CHANGED
@@ -4,13 +4,15 @@
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
6
|
import ast
|
7
|
-
|
7
|
+
|
8
|
+
import yaml
|
8
9
|
|
9
10
|
from ansible import constants as C
|
10
11
|
from ansible.errors import AnsibleError, AnsibleParserError
|
11
12
|
from ansible.module_utils.common.text.converters import to_text, to_native
|
12
13
|
from ansible.parsing.yaml.loader import AnsibleLoader
|
13
14
|
from ansible.utils.display import Display
|
15
|
+
from ansible._internal._datatag import _tags
|
14
16
|
|
15
17
|
display = Display()
|
16
18
|
|
@@ -23,33 +25,27 @@ string_to_vars = {
|
|
23
25
|
}
|
24
26
|
|
25
27
|
|
26
|
-
def _var2string(value):
|
27
|
-
''' reverse lookup of the dict above '''
|
28
|
-
for k, v in string_to_vars.items():
|
29
|
-
if v == value:
|
30
|
-
return k
|
31
|
-
|
32
|
-
|
33
28
|
def _init_doc_dict():
|
34
|
-
|
29
|
+
""" initialize a return dict for docs with the expected structure """
|
35
30
|
return {k: None for k in string_to_vars.values()}
|
36
31
|
|
37
32
|
|
38
33
|
def read_docstring_from_yaml_file(filename, verbose=True, ignore_errors=True):
|
39
|
-
|
34
|
+
""" Read docs from 'sidecar' yaml file doc for a plugin """
|
40
35
|
|
41
36
|
data = _init_doc_dict()
|
42
37
|
file_data = {}
|
43
38
|
|
44
39
|
try:
|
45
40
|
with open(filename, 'rb') as yamlfile:
|
46
|
-
file_data =
|
47
|
-
except Exception as
|
48
|
-
msg = "Unable to parse yaml file
|
41
|
+
file_data = yaml.load(yamlfile, Loader=AnsibleLoader)
|
42
|
+
except Exception as ex:
|
43
|
+
msg = f"Unable to parse yaml file {filename}"
|
44
|
+
# DTFIX-RELEASE: find a better pattern for this (can we use the new optional error behavior?)
|
49
45
|
if not ignore_errors:
|
50
|
-
raise AnsibleParserError(msg
|
46
|
+
raise AnsibleParserError(f'{msg}.') from ex
|
51
47
|
elif verbose:
|
52
|
-
display.error(msg)
|
48
|
+
display.error(f'{msg}: {ex}')
|
53
49
|
|
54
50
|
if file_data:
|
55
51
|
for key in string_to_vars:
|
@@ -58,74 +54,11 @@ def read_docstring_from_yaml_file(filename, verbose=True, ignore_errors=True):
|
|
58
54
|
return data
|
59
55
|
|
60
56
|
|
61
|
-
def read_docstring_from_python_module(filename, verbose=True, ignore_errors=True):
|
62
|
-
"""
|
63
|
-
Use tokenization to search for assignment of the documentation variables in the given file.
|
64
|
-
Parse from YAML and return the resulting python structure or None together with examples as plain text.
|
65
|
-
"""
|
66
|
-
|
67
|
-
seen = set()
|
68
|
-
data = _init_doc_dict()
|
69
|
-
|
70
|
-
next_string = None
|
71
|
-
with tokenize.open(filename) as f:
|
72
|
-
tokens = tokenize.generate_tokens(f.readline)
|
73
|
-
for token in tokens:
|
74
|
-
|
75
|
-
# found label that looks like variable
|
76
|
-
if token.type == tokenize.NAME:
|
77
|
-
|
78
|
-
# label is expected value, in correct place and has not been seen before
|
79
|
-
if token.start == 1 and token.string in string_to_vars and token.string not in seen:
|
80
|
-
# next token that is string has the docs
|
81
|
-
next_string = string_to_vars[token.string]
|
82
|
-
continue
|
83
|
-
|
84
|
-
# previous token indicated this string is a doc string
|
85
|
-
if next_string is not None and token.type == tokenize.STRING:
|
86
|
-
|
87
|
-
# ensure we only process one case of it
|
88
|
-
seen.add(token.string)
|
89
|
-
|
90
|
-
value = token.string
|
91
|
-
|
92
|
-
# strip string modifiers/delimiters
|
93
|
-
if value.startswith(('r', 'b')):
|
94
|
-
value = value.lstrip('rb')
|
95
|
-
|
96
|
-
if value.startswith(("'", '"')):
|
97
|
-
value = value.strip("'\"")
|
98
|
-
|
99
|
-
# actually use the data
|
100
|
-
if next_string == 'plainexamples':
|
101
|
-
# keep as string, can be yaml, but we let caller deal with it
|
102
|
-
data[next_string] = to_text(value)
|
103
|
-
else:
|
104
|
-
# yaml load the data
|
105
|
-
try:
|
106
|
-
data[next_string] = AnsibleLoader(value, file_name=filename).get_single_data()
|
107
|
-
except Exception as e:
|
108
|
-
msg = "Unable to parse docs '%s' in python file '%s': %s" % (_var2string(next_string), filename, to_native(e))
|
109
|
-
if not ignore_errors:
|
110
|
-
raise AnsibleParserError(msg, orig_exc=e)
|
111
|
-
elif verbose:
|
112
|
-
display.error(msg)
|
113
|
-
|
114
|
-
next_string = None
|
115
|
-
|
116
|
-
# if nothing else worked, fall back to old method
|
117
|
-
if not seen:
|
118
|
-
data = read_docstring_from_python_file(filename, verbose, ignore_errors)
|
119
|
-
|
120
|
-
return data
|
121
|
-
|
122
|
-
|
123
57
|
def read_docstring_from_python_file(filename, verbose=True, ignore_errors=True):
|
124
58
|
"""
|
125
59
|
Use ast to search for assignment of the DOCUMENTATION and EXAMPLES variables in the given file.
|
126
60
|
Parse DOCUMENTATION from YAML and return the YAML doc or None together with EXAMPLES, as plain text.
|
127
61
|
"""
|
128
|
-
|
129
62
|
data = _init_doc_dict()
|
130
63
|
|
131
64
|
try:
|
@@ -153,28 +86,30 @@ def read_docstring_from_python_file(filename, verbose=True, ignore_errors=True):
|
|
153
86
|
data[varkey] = to_text(child.value.value)
|
154
87
|
else:
|
155
88
|
# string should be yaml if already not a dict
|
156
|
-
|
89
|
+
child_value = _tags.Origin(path=filename, line_num=child.value.lineno).tag(child.value.value)
|
90
|
+
data[varkey] = yaml.load(child_value, Loader=AnsibleLoader)
|
157
91
|
|
158
92
|
display.debug('Documentation assigned: %s' % varkey)
|
159
93
|
|
160
|
-
except Exception as
|
161
|
-
msg = "Unable to parse documentation in python file
|
94
|
+
except Exception as ex:
|
95
|
+
msg = f"Unable to parse documentation in python file {filename!r}"
|
96
|
+
# DTFIX-RELEASE: better pattern to conditionally raise/display
|
162
97
|
if not ignore_errors:
|
163
|
-
raise AnsibleParserError(msg
|
98
|
+
raise AnsibleParserError(f'{msg}.') from ex
|
164
99
|
elif verbose:
|
165
|
-
display.error(msg)
|
100
|
+
display.error(f'{msg}: {ex}.')
|
166
101
|
|
167
102
|
return data
|
168
103
|
|
169
104
|
|
170
105
|
def read_docstring(filename, verbose=True, ignore_errors=True):
|
171
|
-
|
106
|
+
""" returns a documentation dictionary from Ansible plugin docstrings """
|
172
107
|
|
173
108
|
# NOTE: adjacency of doc file to code file is responsibility of caller
|
174
109
|
if filename.endswith(C.YAML_DOC_EXTENSIONS):
|
175
110
|
docstring = read_docstring_from_yaml_file(filename, verbose=verbose, ignore_errors=ignore_errors)
|
176
111
|
elif filename.endswith(C.PYTHON_DOC_EXTENSIONS):
|
177
|
-
docstring =
|
112
|
+
docstring = read_docstring_from_python_file(filename, verbose=verbose, ignore_errors=ignore_errors)
|
178
113
|
elif not ignore_errors:
|
179
114
|
raise AnsibleError("Unknown documentation format: %s" % to_native(filename))
|
180
115
|
|
@@ -221,6 +156,6 @@ def read_docstub(filename):
|
|
221
156
|
in_documentation = True
|
222
157
|
|
223
158
|
short_description = r''.join(doc_stub).strip().rstrip('.')
|
224
|
-
data =
|
159
|
+
data = yaml.load(_tags.Origin(path=str(filename)).tag(short_description), Loader=AnsibleLoader)
|
225
160
|
|
226
161
|
return data
|
ansible/parsing/quoting.py
CHANGED
@@ -23,7 +23,7 @@ def is_quoted(data):
|
|
23
23
|
|
24
24
|
|
25
25
|
def unquote(data):
|
26
|
-
|
26
|
+
""" removes first and last quotes from a string, if the string starts and ends with the same quotes """
|
27
27
|
if is_quoted(data):
|
28
28
|
return data[1:-1]
|
29
29
|
return data
|
ansible/parsing/splitter.py
CHANGED
@@ -22,19 +22,21 @@ import re
|
|
22
22
|
|
23
23
|
from ansible.errors import AnsibleParserError
|
24
24
|
from ansible.module_utils.common.text.converters import to_text
|
25
|
+
from ansible.module_utils._internal._datatag import AnsibleTagHelper
|
26
|
+
from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
|
25
27
|
from ansible.parsing.quoting import unquote
|
26
28
|
|
27
29
|
|
28
30
|
# Decode escapes adapted from rspeer's answer here:
|
29
31
|
# http://stackoverflow.com/questions/4020539/process-escape-sequences-in-a-string-in-python
|
30
32
|
_HEXCHAR = '[a-fA-F0-9]'
|
31
|
-
_ESCAPE_SEQUENCE_RE = re.compile(r
|
33
|
+
_ESCAPE_SEQUENCE_RE = re.compile(r"""
|
32
34
|
( \\U{0} # 8-digit hex escapes
|
33
35
|
| \\u{1} # 4-digit hex escapes
|
34
36
|
| \\x{2} # 2-digit hex escapes
|
35
37
|
| \\N\{{[^}}]+\}} # Unicode characters by name
|
36
38
|
| \\[\\'"abfnrtv] # Single-character escapes
|
37
|
-
)
|
39
|
+
)""".format(_HEXCHAR * 8, _HEXCHAR * 4, _HEXCHAR * 2), re.UNICODE | re.VERBOSE)
|
38
40
|
|
39
41
|
|
40
42
|
def _decode_escapes(s):
|
@@ -45,12 +47,19 @@ def _decode_escapes(s):
|
|
45
47
|
|
46
48
|
|
47
49
|
def parse_kv(args, check_raw=False):
|
48
|
-
|
50
|
+
"""
|
49
51
|
Convert a string of key/value items to a dict. If any free-form params
|
50
52
|
are found and the check_raw option is set to True, they will be added
|
51
53
|
to a new parameter called '_raw_params'. If check_raw is not enabled,
|
52
54
|
they will simply be ignored.
|
53
|
-
|
55
|
+
"""
|
56
|
+
|
57
|
+
tags = []
|
58
|
+
if origin_tag := Origin.get_tag(args):
|
59
|
+
# NB: adjusting the column number is left as an exercise for the reader
|
60
|
+
tags.append(origin_tag)
|
61
|
+
if trusted_tag := TrustedAsTemplate.get_tag(args):
|
62
|
+
tags.append(trusted_tag)
|
54
63
|
|
55
64
|
args = to_text(args, nonstring='passthru')
|
56
65
|
|
@@ -90,14 +99,20 @@ def parse_kv(args, check_raw=False):
|
|
90
99
|
if len(raw_params) > 0:
|
91
100
|
options[u'_raw_params'] = join_args(raw_params)
|
92
101
|
|
102
|
+
if tags:
|
103
|
+
options = {AnsibleTagHelper.tag(k, tags): AnsibleTagHelper.tag(v, tags) for k, v in options.items()}
|
104
|
+
|
105
|
+
if origin_tag:
|
106
|
+
options = origin_tag.tag(options)
|
107
|
+
|
93
108
|
return options
|
94
109
|
|
95
110
|
|
96
111
|
def _get_quote_state(token, quote_char):
|
97
|
-
|
112
|
+
"""
|
98
113
|
the goal of this block is to determine if the quoted string
|
99
114
|
is unterminated in which case it needs to be put back together
|
100
|
-
|
115
|
+
"""
|
101
116
|
# the char before the current one, used to see if
|
102
117
|
# the current character is escaped
|
103
118
|
prev_char = None
|
@@ -114,11 +129,11 @@ def _get_quote_state(token, quote_char):
|
|
114
129
|
|
115
130
|
|
116
131
|
def _count_jinja2_blocks(token, cur_depth, open_token, close_token):
|
117
|
-
|
132
|
+
"""
|
118
133
|
this function counts the number of opening/closing blocks for a
|
119
134
|
given opening/closing type and adjusts the current depth for that
|
120
135
|
block based on the difference
|
121
|
-
|
136
|
+
"""
|
122
137
|
num_open = token.count(open_token)
|
123
138
|
num_close = token.count(close_token)
|
124
139
|
if num_open != num_close:
|
@@ -129,10 +144,10 @@ def _count_jinja2_blocks(token, cur_depth, open_token, close_token):
|
|
129
144
|
|
130
145
|
|
131
146
|
def join_args(s):
|
132
|
-
|
147
|
+
"""
|
133
148
|
Join the original cmd based on manipulations by split_args().
|
134
149
|
This retains the original newlines and whitespaces.
|
135
|
-
|
150
|
+
"""
|
136
151
|
result = ''
|
137
152
|
for p in s:
|
138
153
|
if len(result) == 0 or result.endswith('\n'):
|
@@ -143,7 +158,7 @@ def join_args(s):
|
|
143
158
|
|
144
159
|
|
145
160
|
def split_args(args):
|
146
|
-
|
161
|
+
"""
|
147
162
|
Splits args on whitespace, but intelligently reassembles
|
148
163
|
those that may have been split over a jinja2 block or quotes.
|
149
164
|
|
@@ -156,7 +171,7 @@ def split_args(args):
|
|
156
171
|
|
157
172
|
Basically this is a variation shlex that has some more intelligence for
|
158
173
|
how Ansible needs to use it.
|
159
|
-
|
174
|
+
"""
|
160
175
|
|
161
176
|
if not args:
|
162
177
|
return []
|
@@ -23,21 +23,21 @@ from ansible.errors import AnsibleParserError, AnsibleError
|
|
23
23
|
# Components that match a numeric or alphanumeric begin:end or begin:end:step
|
24
24
|
# range expression inside square brackets.
|
25
25
|
|
26
|
-
numeric_range = r
|
26
|
+
numeric_range = r"""
|
27
27
|
\[
|
28
28
|
(?:[0-9]+:[0-9]+) # numeric begin:end
|
29
29
|
(?::[0-9]+)? # numeric :step (optional)
|
30
30
|
\]
|
31
|
-
|
31
|
+
"""
|
32
32
|
|
33
|
-
hexadecimal_range = r
|
33
|
+
hexadecimal_range = r"""
|
34
34
|
\[
|
35
35
|
(?:[0-9a-f]+:[0-9a-f]+) # hexadecimal begin:end
|
36
36
|
(?::[0-9]+)? # numeric :step (optional)
|
37
37
|
\]
|
38
|
-
|
38
|
+
"""
|
39
39
|
|
40
|
-
alphanumeric_range = r
|
40
|
+
alphanumeric_range = r"""
|
41
41
|
\[
|
42
42
|
(?:
|
43
43
|
[a-z]:[a-z]| # one-char alphabetic range
|
@@ -45,56 +45,56 @@ alphanumeric_range = r'''
|
|
45
45
|
)
|
46
46
|
(?::[0-9]+)? # numeric :step (optional)
|
47
47
|
\]
|
48
|
-
|
48
|
+
"""
|
49
49
|
|
50
50
|
# Components that match a 16-bit portion of an IPv6 address in hexadecimal
|
51
51
|
# notation (0..ffff) or an 8-bit portion of an IPv4 address in decimal notation
|
52
52
|
# (0..255) or an [x:y(:z)] numeric range.
|
53
53
|
|
54
|
-
ipv6_component = r
|
54
|
+
ipv6_component = r"""
|
55
55
|
(?:
|
56
56
|
[0-9a-f]{{1,4}}| # 0..ffff
|
57
57
|
{range} # or a numeric range
|
58
58
|
)
|
59
|
-
|
59
|
+
""".format(range=hexadecimal_range)
|
60
60
|
|
61
|
-
ipv4_component = r
|
61
|
+
ipv4_component = r"""
|
62
62
|
(?:
|
63
63
|
[01]?[0-9]{{1,2}}| # 0..199
|
64
64
|
2[0-4][0-9]| # 200..249
|
65
65
|
25[0-5]| # 250..255
|
66
66
|
{range} # or a numeric range
|
67
67
|
)
|
68
|
-
|
68
|
+
""".format(range=numeric_range)
|
69
69
|
|
70
70
|
# A hostname label, e.g. 'foo' in 'foo.example.com'. Consists of alphanumeric
|
71
71
|
# characters plus dashes (and underscores) or valid ranges. The label may not
|
72
72
|
# start or end with a hyphen or an underscore. This is interpolated into the
|
73
73
|
# hostname pattern below. We don't try to enforce the 63-char length limit.
|
74
74
|
|
75
|
-
label = r
|
75
|
+
label = r"""
|
76
76
|
(?:[\w]|{range}) # Starts with an alphanumeric or a range
|
77
77
|
(?:[\w_-]|{range})* # Then zero or more of the same or [_-]
|
78
78
|
(?<![_-]) # ...as long as it didn't end with [_-]
|
79
|
-
|
79
|
+
""".format(range=alphanumeric_range)
|
80
80
|
|
81
81
|
patterns = {
|
82
82
|
# This matches a square-bracketed expression with a port specification. What
|
83
83
|
# is inside the square brackets is validated later.
|
84
84
|
|
85
85
|
'bracketed_hostport': re.compile(
|
86
|
-
r
|
86
|
+
r"""^
|
87
87
|
\[(.+)\] # [host identifier]
|
88
88
|
:([0-9]+) # :port number
|
89
89
|
$
|
90
|
-
|
90
|
+
""", re.X
|
91
91
|
),
|
92
92
|
|
93
93
|
# This matches a bare IPv4 address or hostname (or host pattern including
|
94
94
|
# [x:y(:z)] ranges) with a port specification.
|
95
95
|
|
96
96
|
'hostport': re.compile(
|
97
|
-
r
|
97
|
+
r"""^
|
98
98
|
((?: # We want to match:
|
99
99
|
[^:\[\]] # (a non-range character
|
100
100
|
| # ...or...
|
@@ -102,16 +102,16 @@ patterns = {
|
|
102
102
|
)*) # repeated as many times as possible
|
103
103
|
:([0-9]+) # followed by a port number
|
104
104
|
$
|
105
|
-
|
105
|
+
""", re.X
|
106
106
|
),
|
107
107
|
|
108
108
|
# This matches an IPv4 address, but also permits range expressions.
|
109
109
|
|
110
110
|
'ipv4': re.compile(
|
111
|
-
r
|
111
|
+
r"""^
|
112
112
|
(?:{i4}\.){{3}}{i4} # Three parts followed by dots plus one
|
113
113
|
$
|
114
|
-
|
114
|
+
""".format(i4=ipv4_component), re.X | re.I
|
115
115
|
),
|
116
116
|
|
117
117
|
# This matches an IPv6 address, but also permits range expressions.
|
@@ -125,8 +125,8 @@ patterns = {
|
|
125
125
|
# accept ranges in place of each component.
|
126
126
|
|
127
127
|
'ipv6': re.compile(
|
128
|
-
r
|
129
|
-
(?:{0}:){{7}}{0}|
|
128
|
+
r"""^
|
129
|
+
((?:{0}:){{7}}{0}| # uncompressed: 1:2:3:4:5:6:7:8
|
130
130
|
(?:{0}:){{1,6}}:| # compressed variants, which are all
|
131
131
|
(?:{0}:)(?::{0}){{1,6}}| # a::b for various lengths of a,b
|
132
132
|
(?:{0}:){{2}}(?::{0}){{1,5}}|
|
@@ -139,9 +139,9 @@ patterns = {
|
|
139
139
|
# ipv4-in-ipv6 variants
|
140
140
|
(?:0:){{6}}(?:{0}\.){{3}}{0}|
|
141
141
|
::(?:ffff:)?(?:{0}\.){{3}}{0}|
|
142
|
-
(?:0:){{5}}ffff:(?:{0}\.){{3}}{0}
|
142
|
+
(?:0:){{5}}ffff:(?:{0}\.){{3}}{0})
|
143
143
|
$
|
144
|
-
|
144
|
+
""".format(ipv6_component), re.X | re.I
|
145
145
|
),
|
146
146
|
|
147
147
|
# This matches a hostname or host pattern including [x:y(:z)] ranges.
|
@@ -155,11 +155,11 @@ patterns = {
|
|
155
155
|
# 253 characters total) or make any attempt to process IDNs.
|
156
156
|
|
157
157
|
'hostname': re.compile(
|
158
|
-
r
|
158
|
+
r"""^
|
159
159
|
{label} # We must have at least one label
|
160
160
|
(?:\.{label})* # Followed by zero or more .labels
|
161
161
|
$
|
162
|
-
|
162
|
+
""".format(label=label), re.X | re.I | re.UNICODE
|
163
163
|
),
|
164
164
|
|
165
165
|
}
|
ansible/parsing/utils/yaml.py
CHANGED
@@ -6,77 +6,48 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import json
|
9
|
+
import typing as t
|
9
10
|
|
10
|
-
|
11
|
+
import yaml
|
11
12
|
|
12
|
-
from ansible.errors import
|
13
|
-
from ansible.
|
14
|
-
from ansible.
|
13
|
+
from ansible.errors import AnsibleJSONParserError
|
14
|
+
from ansible._internal._errors import _utils
|
15
|
+
from ansible.parsing.vault import VaultSecret
|
15
16
|
from ansible.parsing.yaml.loader import AnsibleLoader
|
16
|
-
from ansible.
|
17
|
-
from ansible.
|
17
|
+
from ansible._internal._yaml._errors import AnsibleYAMLParserError
|
18
|
+
from ansible._internal._datatag._tags import Origin
|
19
|
+
from ansible._internal._json._profiles import _legacy
|
18
20
|
|
19
21
|
|
20
|
-
|
22
|
+
def from_yaml(
|
23
|
+
data: str,
|
24
|
+
file_name: str | None = None,
|
25
|
+
show_content: bool = True,
|
26
|
+
vault_secrets: list[tuple[str, VaultSecret]] | None = None, # deprecated: description='Deprecate vault_secrets, it has no effect.' core_version='2.23'
|
27
|
+
json_only: bool = False,
|
28
|
+
) -> t.Any:
|
29
|
+
"""Creates a Python data structure from the given data, which can be either a JSON or YAML string."""
|
30
|
+
# FUTURE: provide Ansible-specific top-level APIs to expose JSON and YAML serialization/deserialization to hide the error handling logic
|
31
|
+
# once those are in place, defer deprecate this entire function
|
21
32
|
|
33
|
+
origin = Origin.get_or_create_tag(data, file_name)
|
22
34
|
|
23
|
-
|
24
|
-
'''
|
25
|
-
Optionally constructs an object (AnsibleBaseYAMLObject) to encapsulate the
|
26
|
-
file name/position where a YAML exception occurred, and raises an AnsibleParserError
|
27
|
-
to display the syntax exception information.
|
28
|
-
'''
|
35
|
+
data = origin.tag(data)
|
29
36
|
|
30
|
-
|
31
|
-
# an object the error class can use to display the faulty line
|
32
|
-
err_obj = None
|
33
|
-
if hasattr(yaml_exc, 'problem_mark'):
|
34
|
-
err_obj = AnsibleBaseYAMLObject()
|
35
|
-
err_obj.ansible_pos = (file_name, yaml_exc.problem_mark.line + 1, yaml_exc.problem_mark.column + 1)
|
36
|
-
|
37
|
-
n_yaml_syntax_error = YAML_SYNTAX_ERROR % to_native(getattr(yaml_exc, 'problem', u''))
|
38
|
-
n_err_msg = 'We were unable to read either as JSON nor YAML, these are the errors we got from each:\n' \
|
39
|
-
'JSON: %s\n\n%s' % (to_native(json_exc), n_yaml_syntax_error)
|
40
|
-
|
41
|
-
raise AnsibleParserError(n_err_msg, obj=err_obj, show_content=show_content, orig_exc=yaml_exc)
|
42
|
-
|
43
|
-
|
44
|
-
def _safe_load(stream, file_name=None, vault_secrets=None):
|
45
|
-
''' Implements yaml.safe_load(), except using our custom loader class. '''
|
46
|
-
|
47
|
-
loader = AnsibleLoader(stream, file_name, vault_secrets)
|
48
|
-
try:
|
49
|
-
return loader.get_single_data()
|
50
|
-
finally:
|
37
|
+
with _utils.RedactAnnotatedSourceContext.when(not show_content):
|
51
38
|
try:
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def from_yaml(data, file_name='<string>', show_content=True, vault_secrets=None, json_only=False):
|
58
|
-
'''
|
59
|
-
Creates a python datastructure from the given data, which can be either
|
60
|
-
a JSON or YAML string.
|
61
|
-
'''
|
62
|
-
new_data = None
|
63
|
-
|
64
|
-
try:
|
65
|
-
# in case we have to deal with vaults
|
66
|
-
AnsibleJSONDecoder.set_secrets(vault_secrets)
|
67
|
-
|
68
|
-
# we first try to load this data as JSON.
|
69
|
-
# Fixes issues with extra vars json strings not being parsed correctly by the yaml parser
|
70
|
-
new_data = json.loads(data, cls=AnsibleJSONDecoder)
|
71
|
-
except Exception as json_exc:
|
39
|
+
# we first try to load this data as JSON.
|
40
|
+
# Fixes issues with extra vars json strings not being parsed correctly by the yaml parser
|
41
|
+
return json.loads(data, cls=_legacy.Decoder)
|
42
|
+
except Exception as ex:
|
43
|
+
json_ex = ex
|
72
44
|
|
73
45
|
if json_only:
|
74
|
-
|
46
|
+
AnsibleJSONParserError.handle_exception(json_ex, origin=origin)
|
75
47
|
|
76
|
-
# must not be JSON, let the rest try
|
77
48
|
try:
|
78
|
-
|
79
|
-
except
|
80
|
-
|
81
|
-
|
82
|
-
|
49
|
+
return yaml.load(data, Loader=AnsibleLoader) # type: ignore[arg-type]
|
50
|
+
except Exception as yaml_ex:
|
51
|
+
# DTFIX-RELEASE: how can we indicate in Origin that the data is in-memory only, to support context information -- is that useful?
|
52
|
+
# we'd need to pass data to handle_exception so it could be used as the content instead of reading from disk
|
53
|
+
AnsibleYAMLParserError.handle_exception(yaml_ex, origin=origin)
|