ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +203 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +197 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +345 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +62 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +159 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +62 -53
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +166 -112
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +161 -96
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +268 -258
- ansible/executor/task_queue_manager.py +124 -90
- ansible/executor/task_result.py +183 -78
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +78 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +152 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +86 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +1 -1
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +4 -4
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +9 -8
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +19 -17
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +32 -27
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +31 -27
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +4 -5
- ansible/plugins/action/gather_facts.py +7 -6
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +35 -44
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +284 -179
- ansible/plugins/callback/default.py +99 -92
- ansible/plugins/callback/junit.py +44 -39
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +28 -21
- ansible/plugins/callback/tree.py +16 -11
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +6 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +225 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +97 -77
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +86 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +159 -184
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +55 -21
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +370 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +433 -63
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +51 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +206 -282
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/WHEEL +1 -1
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -0
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +1 -0
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +2 -1
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +4 -0
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +1 -0
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +16 -1
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +24 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +2 -0
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/delegation.py +1 -0
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +35 -27
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
ansible/modules/file.py
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
from __future__ import annotations
|
8
8
|
|
9
9
|
|
10
|
-
DOCUMENTATION = r
|
10
|
+
DOCUMENTATION = r"""
|
11
11
|
---
|
12
12
|
module: file
|
13
13
|
version_added: historical
|
@@ -123,9 +123,9 @@ attributes:
|
|
123
123
|
author:
|
124
124
|
- Ansible Core Team
|
125
125
|
- Michael DeHaan
|
126
|
-
|
126
|
+
"""
|
127
127
|
|
128
|
-
EXAMPLES = r
|
128
|
+
EXAMPLES = r"""
|
129
129
|
- name: Change file ownership, group and permissions
|
130
130
|
ansible.builtin.file:
|
131
131
|
path: /etc/foo.conf
|
@@ -214,8 +214,8 @@ EXAMPLES = r'''
|
|
214
214
|
path: /etc/foo
|
215
215
|
state: absent
|
216
216
|
|
217
|
-
|
218
|
-
RETURN = r
|
217
|
+
"""
|
218
|
+
RETURN = r"""
|
219
219
|
dest:
|
220
220
|
description: Destination file/path, equal to the value passed to O(path).
|
221
221
|
returned: O(state=touch), O(state=hard), O(state=link)
|
@@ -226,12 +226,11 @@ path:
|
|
226
226
|
returned: O(state=absent), O(state=directory), O(state=file)
|
227
227
|
type: str
|
228
228
|
sample: /path/to/file.txt
|
229
|
-
|
229
|
+
"""
|
230
230
|
|
231
231
|
import errno
|
232
232
|
import os
|
233
233
|
import shutil
|
234
|
-
import sys
|
235
234
|
import time
|
236
235
|
|
237
236
|
from pwd import getpwnam, getpwuid
|
@@ -239,7 +238,7 @@ from grp import getgrnam, getgrgid
|
|
239
238
|
|
240
239
|
from ansible.module_utils.basic import AnsibleModule
|
241
240
|
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
242
|
-
|
241
|
+
from ansible.module_utils.common.sentinel import Sentinel
|
243
242
|
|
244
243
|
# There will only be a single AnsibleModule object per module
|
245
244
|
module = None
|
@@ -257,19 +256,6 @@ class ParameterError(AnsibleModuleError):
|
|
257
256
|
pass
|
258
257
|
|
259
258
|
|
260
|
-
class Sentinel(object):
|
261
|
-
def __new__(cls, *args, **kwargs):
|
262
|
-
return cls
|
263
|
-
|
264
|
-
|
265
|
-
def _ansible_excepthook(exc_type, exc_value, tb):
|
266
|
-
# Using an exception allows us to catch it if the calling code knows it can recover
|
267
|
-
if issubclass(exc_type, AnsibleModuleError):
|
268
|
-
module.fail_json(**exc_value.results)
|
269
|
-
else:
|
270
|
-
sys.__excepthook__(exc_type, exc_value, tb)
|
271
|
-
|
272
|
-
|
273
259
|
def additional_parameter_handling(params):
|
274
260
|
"""Additional parameter validation and reformatting"""
|
275
261
|
# When path is a directory, rewrite the pathname to be the file inside of the directory
|
@@ -307,17 +293,21 @@ def additional_parameter_handling(params):
|
|
307
293
|
|
308
294
|
# make sure the target path is a directory when we're doing a recursive operation
|
309
295
|
if params['recurse'] and params['state'] != 'directory':
|
310
|
-
|
311
|
-
|
296
|
+
module.fail_json(
|
297
|
+
msg="recurse option requires state to be 'directory'",
|
298
|
+
path=params["path"]
|
299
|
+
)
|
312
300
|
|
313
301
|
# Fail if 'src' but no 'state' is specified
|
314
302
|
if params['src'] and params['state'] not in ('link', 'hard'):
|
315
|
-
|
316
|
-
|
303
|
+
module.fail_json(
|
304
|
+
msg="src option requires state to be 'link' or 'hard'",
|
305
|
+
path=params['path']
|
306
|
+
)
|
317
307
|
|
318
308
|
|
319
309
|
def get_state(path):
|
320
|
-
|
310
|
+
""" Find out current state """
|
321
311
|
|
322
312
|
b_path = to_bytes(path, errors='surrogate_or_strict')
|
323
313
|
try:
|
@@ -377,8 +367,8 @@ def recursive_set_attributes(b_path, follow, file_args, mtime, atime):
|
|
377
367
|
except RuntimeError as e:
|
378
368
|
# on Python3 "RecursionError" is raised which is derived from "RuntimeError"
|
379
369
|
# TODO once this function is moved into the common file utilities, this should probably raise more general exception
|
380
|
-
|
381
|
-
|
370
|
+
module.fail_json(
|
371
|
+
msg=f"Could not recursively set attributes on {to_native(b_path)}. Original error was: '{to_native(e)}'"
|
382
372
|
)
|
383
373
|
|
384
374
|
return changed
|
@@ -419,17 +409,17 @@ def initial_diff(path, state, prev_state):
|
|
419
409
|
def get_timestamp_for_time(formatted_time, time_format):
|
420
410
|
if formatted_time == 'preserve':
|
421
411
|
return None
|
422
|
-
|
412
|
+
if formatted_time == 'now':
|
423
413
|
return Sentinel
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
414
|
+
try:
|
415
|
+
struct = time.strptime(formatted_time, time_format)
|
416
|
+
struct_time = time.mktime(struct)
|
417
|
+
except (ValueError, OverflowError) as e:
|
418
|
+
module.fail_json(
|
419
|
+
msg=f"Error while obtaining timestamp for time {formatted_time} using format {time_format}: {to_native(e, nonstring='simplerepr')}",
|
420
|
+
)
|
431
421
|
|
432
|
-
|
422
|
+
return struct_time
|
433
423
|
|
434
424
|
|
435
425
|
def update_timestamp_for_file(path, mtime, atime, diff=None):
|
@@ -486,18 +476,19 @@ def update_timestamp_for_file(path, mtime, atime, diff=None):
|
|
486
476
|
diff['before']['atime'] = previous_atime
|
487
477
|
diff['after']['atime'] = atime
|
488
478
|
except OSError as e:
|
489
|
-
|
490
|
-
|
479
|
+
module.fail_json(
|
480
|
+
msg=f"Error while updating modification or access time: {to_native(e, nonstring='simplerepr')}",
|
481
|
+
path=path
|
482
|
+
)
|
491
483
|
return True
|
492
484
|
|
493
485
|
|
494
486
|
def keep_backward_compatibility_on_timestamps(parameter, state):
|
495
487
|
if state in ['file', 'hard', 'directory', 'link'] and parameter is None:
|
496
488
|
return 'preserve'
|
497
|
-
|
489
|
+
if state == 'touch' and parameter is None:
|
498
490
|
return 'now'
|
499
|
-
|
500
|
-
return parameter
|
491
|
+
return parameter
|
501
492
|
|
502
493
|
|
503
494
|
def execute_diff_peek(path):
|
@@ -530,14 +521,18 @@ def ensure_absent(path):
|
|
530
521
|
try:
|
531
522
|
shutil.rmtree(b_path, ignore_errors=False)
|
532
523
|
except Exception as e:
|
533
|
-
|
524
|
+
module.fail_json(
|
525
|
+
msg=f"rmtree failed: {to_native(e)}"
|
526
|
+
)
|
534
527
|
else:
|
535
528
|
try:
|
536
529
|
os.unlink(b_path)
|
537
530
|
except OSError as e:
|
538
531
|
if e.errno != errno.ENOENT: # It may already have been removed
|
539
|
-
|
540
|
-
|
532
|
+
module.fail_json(
|
533
|
+
msg=f"unlinking failed: {to_native(e)}",
|
534
|
+
path=path
|
535
|
+
)
|
541
536
|
|
542
537
|
result.update({'path': path, 'changed': True, 'diff': diff, 'state': 'absent'})
|
543
538
|
else:
|
@@ -566,9 +561,10 @@ def execute_touch(path, follow, timestamps):
|
|
566
561
|
open(b_path, 'wb').close()
|
567
562
|
changed = True
|
568
563
|
except (OSError, IOError) as e:
|
569
|
-
|
570
|
-
|
571
|
-
|
564
|
+
module.fail_json(
|
565
|
+
msg=f"Error, could not touch target: {to_native(e, nonstring='simplerepr')}",
|
566
|
+
path=path
|
567
|
+
)
|
572
568
|
# Update the attributes on the file
|
573
569
|
diff = initial_diff(path, 'touch', prev_state)
|
574
570
|
file_args = module.load_file_common_arguments(module.params)
|
@@ -606,8 +602,11 @@ def ensure_file_attributes(path, follow, timestamps):
|
|
606
602
|
|
607
603
|
if prev_state not in ('file', 'hard'):
|
608
604
|
# file is not absent and any other state is a conflict
|
609
|
-
|
610
|
-
|
605
|
+
module.fail_json(
|
606
|
+
msg=f"file ({path}) is {prev_state}, cannot continue",
|
607
|
+
path=path,
|
608
|
+
state=prev_state
|
609
|
+
)
|
611
610
|
|
612
611
|
diff = initial_diff(path, 'file', prev_state)
|
613
612
|
changed = module.set_fs_attributes_if_different(file_args, False, diff, expand=False)
|
@@ -664,15 +663,18 @@ def ensure_directory(path, follow, recurse, timestamps):
|
|
664
663
|
changed = module.set_fs_attributes_if_different(tmp_file_args, changed, diff, expand=False)
|
665
664
|
changed |= update_timestamp_for_file(file_args['path'], mtime, atime, diff)
|
666
665
|
except Exception as e:
|
667
|
-
|
668
|
-
|
669
|
-
|
666
|
+
module.fail_json(
|
667
|
+
msg=f"There was an issue creating {curpath} as requested: {to_native(e)}",
|
668
|
+
path=path
|
669
|
+
)
|
670
670
|
return {'path': path, 'changed': changed, 'diff': diff}
|
671
671
|
|
672
672
|
elif prev_state != 'directory':
|
673
673
|
# We already know prev_state is not 'absent', therefore it exists in some form.
|
674
|
-
|
675
|
-
|
674
|
+
module.fail_json(
|
675
|
+
msg=f"{path} already exists as a {prev_state}",
|
676
|
+
path=path
|
677
|
+
)
|
676
678
|
|
677
679
|
#
|
678
680
|
# previous state == directory
|
@@ -714,31 +716,39 @@ def ensure_symlink(path, src, follow, force, timestamps):
|
|
714
716
|
|
715
717
|
b_absrc = to_bytes(absrc, errors='surrogate_or_strict')
|
716
718
|
if not force and src is not None and not os.path.exists(b_absrc):
|
717
|
-
|
718
|
-
|
719
|
-
|
719
|
+
module.fail_json(
|
720
|
+
msg="src file does not exist, use 'force=yes' if you"
|
721
|
+
f" really want to create the link: {absrc}",
|
722
|
+
path=path,
|
723
|
+
src=src
|
724
|
+
)
|
720
725
|
|
721
726
|
if prev_state == 'directory':
|
722
727
|
if not force:
|
723
|
-
|
724
|
-
|
725
|
-
|
728
|
+
module.fail_json(
|
729
|
+
msg=f'refusing to convert from {prev_state} to symlink for {path}',
|
730
|
+
path=path
|
731
|
+
)
|
726
732
|
elif os.listdir(b_path):
|
727
733
|
# refuse to replace a directory that has files in it
|
728
|
-
|
729
|
-
|
730
|
-
|
734
|
+
module.fail_json(
|
735
|
+
msg=f'the directory {path} is not empty, refusing to convert it',
|
736
|
+
path=path
|
737
|
+
)
|
731
738
|
elif prev_state in ('file', 'hard') and not force:
|
732
|
-
|
733
|
-
|
734
|
-
|
739
|
+
module.fail_json(
|
740
|
+
msg=f'refusing to convert from {prev_state} to symlink for {path}',
|
741
|
+
path=path
|
742
|
+
)
|
735
743
|
|
736
744
|
diff = initial_diff(path, 'link', prev_state)
|
737
745
|
changed = False
|
738
746
|
|
739
747
|
if prev_state in ('hard', 'file', 'directory', 'absent'):
|
740
748
|
if src is None:
|
741
|
-
|
749
|
+
module.fail_json(
|
750
|
+
msg='src is required for creating new symlinks',
|
751
|
+
)
|
742
752
|
changed = True
|
743
753
|
elif prev_state == 'link':
|
744
754
|
if src is not None:
|
@@ -748,7 +758,11 @@ def ensure_symlink(path, src, follow, force, timestamps):
|
|
748
758
|
diff['after']['src'] = src
|
749
759
|
changed = True
|
750
760
|
else:
|
751
|
-
|
761
|
+
module.fail_json(
|
762
|
+
msg='unexpected position reached',
|
763
|
+
dest=path,
|
764
|
+
src=src
|
765
|
+
)
|
752
766
|
|
753
767
|
if changed and not module.check_mode:
|
754
768
|
if prev_state != 'absent':
|
@@ -764,16 +778,18 @@ def ensure_symlink(path, src, follow, force, timestamps):
|
|
764
778
|
except OSError as e:
|
765
779
|
if os.path.exists(b_tmppath):
|
766
780
|
os.unlink(b_tmppath)
|
767
|
-
|
768
|
-
|
769
|
-
|
781
|
+
module.fail_json(
|
782
|
+
msg=f"Error while replacing: {to_native(e, nonstring='simplerepr')}",
|
783
|
+
path=path
|
784
|
+
)
|
770
785
|
else:
|
771
786
|
try:
|
772
787
|
os.symlink(b_src, b_path)
|
773
788
|
except OSError as e:
|
774
|
-
|
775
|
-
|
776
|
-
|
789
|
+
module.fail_json(
|
790
|
+
msg=f"Error while linking: {to_native(e, nonstring='simplerepr')}",
|
791
|
+
path=path
|
792
|
+
)
|
777
793
|
|
778
794
|
if module.check_mode and not os.path.exists(b_path):
|
779
795
|
return {'dest': path, 'src': src, 'changed': changed, 'diff': diff}
|
@@ -808,12 +824,18 @@ def ensure_hardlink(path, src, follow, force, timestamps):
|
|
808
824
|
# src is the source of a hardlink. We require it if we are creating a new hardlink.
|
809
825
|
# We require path in the argument_spec so we know it is present at this point.
|
810
826
|
if prev_state != 'hard' and src is None:
|
811
|
-
|
827
|
+
module.fail_json(
|
828
|
+
msg='src is required for creating new hardlinks'
|
829
|
+
)
|
812
830
|
|
813
831
|
# Even if the link already exists, if src was specified it needs to exist.
|
814
832
|
# The inode number will be compared to ensure the link has the correct target.
|
815
833
|
if src is not None and not os.path.exists(b_src):
|
816
|
-
|
834
|
+
module.fail_json(
|
835
|
+
msg='src does not exist',
|
836
|
+
dest=path,
|
837
|
+
src=src
|
838
|
+
)
|
817
839
|
|
818
840
|
diff = initial_diff(path, 'hard', prev_state)
|
819
841
|
changed = False
|
@@ -827,26 +849,39 @@ def ensure_hardlink(path, src, follow, force, timestamps):
|
|
827
849
|
diff['after']['src'] = src
|
828
850
|
changed = True
|
829
851
|
elif prev_state == 'hard':
|
830
|
-
if src is not None and
|
852
|
+
if src is not None and os.stat(b_path).st_ino != os.stat(b_src).st_ino:
|
831
853
|
changed = True
|
832
854
|
if not force:
|
833
|
-
|
834
|
-
|
855
|
+
module.fail_json(
|
856
|
+
msg='Cannot link, different hard link exists at destination',
|
857
|
+
dest=path,
|
858
|
+
src=src
|
859
|
+
)
|
835
860
|
elif prev_state == 'file':
|
836
861
|
changed = True
|
837
862
|
if not force:
|
838
|
-
|
839
|
-
|
863
|
+
module.fail_json(
|
864
|
+
msg=f'Cannot link, {prev_state} exists at destination',
|
865
|
+
dest=path,
|
866
|
+
src=src
|
867
|
+
)
|
840
868
|
elif prev_state == 'directory':
|
841
869
|
changed = True
|
842
870
|
if os.path.exists(b_path):
|
843
871
|
if os.stat(b_path).st_ino == os.stat(b_src).st_ino:
|
844
872
|
return {'path': path, 'changed': False}
|
845
873
|
elif not force:
|
846
|
-
|
847
|
-
|
874
|
+
module.fail_json(
|
875
|
+
msg='Cannot link: different hard link exists at destination',
|
876
|
+
dest=path,
|
877
|
+
src=src
|
878
|
+
)
|
848
879
|
else:
|
849
|
-
|
880
|
+
module.fail_json(
|
881
|
+
msg='unexpected position reached',
|
882
|
+
dest=path,
|
883
|
+
src=src
|
884
|
+
)
|
850
885
|
|
851
886
|
if changed and not module.check_mode:
|
852
887
|
if prev_state != 'absent':
|
@@ -867,18 +902,20 @@ def ensure_hardlink(path, src, follow, force, timestamps):
|
|
867
902
|
except OSError as e:
|
868
903
|
if os.path.exists(b_tmppath):
|
869
904
|
os.unlink(b_tmppath)
|
870
|
-
|
871
|
-
|
872
|
-
|
905
|
+
module.fail_json(
|
906
|
+
msg=f"Error while replacing: {to_native(e, nonstring='simplerepr')}",
|
907
|
+
path=path
|
908
|
+
)
|
873
909
|
else:
|
874
910
|
try:
|
875
911
|
if follow and os.path.islink(b_src):
|
876
912
|
b_src = os.readlink(b_src)
|
877
913
|
os.link(b_src, b_path)
|
878
914
|
except OSError as e:
|
879
|
-
|
880
|
-
|
881
|
-
|
915
|
+
module.fail_json(
|
916
|
+
msg=f"Error while linking: {to_native(e, nonstring='simplerepr')}",
|
917
|
+
path=path
|
918
|
+
)
|
882
919
|
|
883
920
|
if module.check_mode and not os.path.exists(b_path):
|
884
921
|
return {'dest': path, 'src': src, 'changed': changed, 'diff': diff}
|
@@ -940,48 +977,52 @@ def main():
|
|
940
977
|
supports_check_mode=True,
|
941
978
|
)
|
942
979
|
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
980
|
+
try:
|
981
|
+
additional_parameter_handling(module.params)
|
982
|
+
params = module.params
|
983
|
+
|
984
|
+
state = params['state']
|
985
|
+
recurse = params['recurse']
|
986
|
+
force = params['force']
|
987
|
+
follow = params['follow']
|
988
|
+
path = params['path']
|
989
|
+
src = params['src']
|
990
|
+
|
991
|
+
if module.check_mode and state != 'absent':
|
992
|
+
file_args = module.load_file_common_arguments(module.params)
|
993
|
+
if file_args['owner']:
|
994
|
+
check_owner_exists(module, file_args['owner'])
|
995
|
+
if file_args['group']:
|
996
|
+
check_group_exists(module, file_args['group'])
|
997
|
+
|
998
|
+
timestamps = {}
|
999
|
+
timestamps['modification_time'] = keep_backward_compatibility_on_timestamps(params['modification_time'], state)
|
1000
|
+
timestamps['modification_time_format'] = params['modification_time_format']
|
1001
|
+
timestamps['access_time'] = keep_backward_compatibility_on_timestamps(params['access_time'], state)
|
1002
|
+
timestamps['access_time_format'] = params['access_time_format']
|
1003
|
+
|
1004
|
+
# short-circuit for diff_peek
|
1005
|
+
if params['_diff_peek'] is not None:
|
1006
|
+
appears_binary = execute_diff_peek(to_bytes(path, errors='surrogate_or_strict'))
|
1007
|
+
module.exit_json(path=path, changed=False, appears_binary=appears_binary)
|
1008
|
+
|
1009
|
+
if state == 'file':
|
1010
|
+
result = ensure_file_attributes(path, follow, timestamps)
|
1011
|
+
elif state == 'directory':
|
1012
|
+
result = ensure_directory(path, follow, recurse, timestamps)
|
1013
|
+
elif state == 'link':
|
1014
|
+
result = ensure_symlink(path, src, follow, force, timestamps)
|
1015
|
+
elif state == 'hard':
|
1016
|
+
result = ensure_hardlink(path, src, follow, force, timestamps)
|
1017
|
+
elif state == 'touch':
|
1018
|
+
result = execute_touch(path, follow, timestamps)
|
1019
|
+
elif state == 'absent':
|
1020
|
+
result = ensure_absent(path)
|
1021
|
+
except AnsibleModuleError as ex:
|
1022
|
+
module.fail_json(**ex.results)
|
1023
|
+
|
1024
|
+
if not module._diff:
|
1025
|
+
result.pop('diff', None)
|
985
1026
|
|
986
1027
|
module.exit_json(**result)
|
987
1028
|
|
ansible/modules/find.py
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
from __future__ import annotations
|
10
10
|
|
11
11
|
|
12
|
-
DOCUMENTATION = r
|
12
|
+
DOCUMENTATION = r"""
|
13
13
|
---
|
14
14
|
module: find
|
15
15
|
author: Brian Coca (@bcoca)
|
@@ -29,6 +29,10 @@ options:
|
|
29
29
|
- You can choose seconds, minutes, hours, days, or weeks by specifying the
|
30
30
|
first letter of any of those words (e.g., "1w").
|
31
31
|
type: str
|
32
|
+
get_checksum:
|
33
|
+
default: false
|
34
|
+
checksum_algorithm:
|
35
|
+
version_added: "2.19"
|
32
36
|
patterns:
|
33
37
|
default: []
|
34
38
|
description:
|
@@ -132,11 +136,6 @@ options:
|
|
132
136
|
- Set this to V(true) to follow symlinks in path for systems with python 2.6+.
|
133
137
|
type: bool
|
134
138
|
default: no
|
135
|
-
get_checksum:
|
136
|
-
description:
|
137
|
-
- Set this to V(true) to retrieve a file's SHA1 checksum.
|
138
|
-
type: bool
|
139
|
-
default: no
|
140
139
|
use_regex:
|
141
140
|
description:
|
142
141
|
- If V(false), the patterns are file globs (shell).
|
@@ -163,7 +162,7 @@ options:
|
|
163
162
|
- Default is unlimited matches.
|
164
163
|
type: int
|
165
164
|
version_added: "2.18"
|
166
|
-
extends_documentation_fragment: action_common_attributes
|
165
|
+
extends_documentation_fragment: [action_common_attributes, checksum_common]
|
167
166
|
attributes:
|
168
167
|
check_mode:
|
169
168
|
details: since this action does not modify the target it just executes normally during check mode
|
@@ -174,10 +173,10 @@ attributes:
|
|
174
173
|
platforms: posix
|
175
174
|
seealso:
|
176
175
|
- module: ansible.windows.win_find
|
177
|
-
|
176
|
+
"""
|
178
177
|
|
179
178
|
|
180
|
-
EXAMPLES = r
|
179
|
+
EXAMPLES = r"""
|
181
180
|
- name: Recursively find /tmp files older than 2 days
|
182
181
|
ansible.builtin.find:
|
183
182
|
paths: /tmp
|
@@ -246,9 +245,9 @@ EXAMPLES = r'''
|
|
246
245
|
use_regex: true
|
247
246
|
recurse: true
|
248
247
|
limit: 1
|
249
|
-
|
248
|
+
"""
|
250
249
|
|
251
|
-
RETURN = r
|
250
|
+
RETURN = r"""
|
252
251
|
files:
|
253
252
|
description: All matches found with the specified criteria (see stat module for full output of each dictionary)
|
254
253
|
returned: success
|
@@ -279,7 +278,7 @@ skipped_paths:
|
|
279
278
|
type: dict
|
280
279
|
sample: {"/laskdfj": "'/laskdfj' is not a directory"}
|
281
280
|
version_added: '2.12'
|
282
|
-
|
281
|
+
"""
|
283
282
|
|
284
283
|
import errno
|
285
284
|
import fnmatch
|
@@ -302,7 +301,7 @@ class _Object:
|
|
302
301
|
|
303
302
|
|
304
303
|
def pfilter(f, patterns=None, excludes=None, use_regex=False):
|
305
|
-
|
304
|
+
"""filter using glob patterns"""
|
306
305
|
if not patterns and not excludes:
|
307
306
|
return True
|
308
307
|
|
@@ -341,7 +340,7 @@ def pfilter(f, patterns=None, excludes=None, use_regex=False):
|
|
341
340
|
|
342
341
|
|
343
342
|
def agefilter(st, now, age, timestamp):
|
344
|
-
|
343
|
+
"""filter files older than age"""
|
345
344
|
if age is None:
|
346
345
|
return True
|
347
346
|
elif age >= 0 and now - getattr(st, "st_%s" % timestamp) >= abs(age):
|
@@ -352,7 +351,7 @@ def agefilter(st, now, age, timestamp):
|
|
352
351
|
|
353
352
|
|
354
353
|
def sizefilter(st, size):
|
355
|
-
|
354
|
+
"""filter files greater than size"""
|
356
355
|
if size is None:
|
357
356
|
return True
|
358
357
|
elif size >= 0 and st.st_size >= abs(size):
|
@@ -482,6 +481,9 @@ def main():
|
|
482
481
|
hidden=dict(type='bool', default=False),
|
483
482
|
follow=dict(type='bool', default=False),
|
484
483
|
get_checksum=dict(type='bool', default=False),
|
484
|
+
checksum_algorithm=dict(type='str', default='sha1',
|
485
|
+
choices=['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512'],
|
486
|
+
aliases=['checksum', 'checksum_algo']),
|
485
487
|
use_regex=dict(type='bool', default=False),
|
486
488
|
depth=dict(type='int'),
|
487
489
|
mode=dict(type='raw'),
|
@@ -583,7 +585,7 @@ def main():
|
|
583
585
|
|
584
586
|
r.update(statinfo(st))
|
585
587
|
if stat.S_ISREG(st.st_mode) and params['get_checksum']:
|
586
|
-
r['checksum'] = module.
|
588
|
+
r['checksum'] = module.digest_from_file(fsname, params['checksum_algorithm'])
|
587
589
|
|
588
590
|
if stat.S_ISREG(st.st_mode):
|
589
591
|
if sizefilter(st, size):
|
@@ -608,7 +610,7 @@ def main():
|
|
608
610
|
|
609
611
|
r.update(statinfo(st))
|
610
612
|
if params['get_checksum']:
|
611
|
-
r['checksum'] = module.
|
613
|
+
r['checksum'] = module.digest_from_file(fsname, params['checksum_algorithm'])
|
612
614
|
filelist.append(r)
|
613
615
|
|
614
616
|
elif stat.S_ISLNK(st.st_mode) and params['file_type'] == 'link':
|