ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz/__init__.py +0 -0
- ansible/_internal/_ansiballz/_builder.py +101 -0
- ansible/_internal/_ansiballz/_wrapper.py +262 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_alarm_timeout.py +66 -0
- ansible/_internal/_errors/_captured.py +123 -0
- ansible/_internal/_errors/_error_factory.py +89 -0
- ansible/_internal/_errors/_error_utils.py +240 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_task_timeout.py +28 -0
- ansible/_internal/_event_formatting.py +127 -0
- ansible/_internal/_json/__init__.py +214 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +189 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_ssh/__init__.py +0 -0
- ansible/_internal/_ssh/_agent_launch.py +91 -0
- ansible/_internal/_ssh/_ssh_agent.py +619 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +12 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +592 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1106 -0
- ansible/_internal/_templating/_jinja_common.py +323 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +375 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_template_vars.py +72 -0
- ansible/_internal/_templating/_transform.py +70 -0
- ansible/_internal/_templating/_utils.py +108 -0
- ansible/_internal/_testing.py +26 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +70 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +93 -104
- ansible/cli/_ssh_askpass.py +54 -0
- ansible/cli/adhoc.py +20 -10
- ansible/cli/arguments/option_helpers.py +163 -10
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +13 -11
- ansible/cli/doc.py +134 -77
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -28
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +6 -3
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/compat/importlib_resources.py +9 -12
- ansible/config/base.yml +218 -133
- ansible/config/manager.py +220 -159
- ansible/constants.py +2 -65
- ansible/errors/__init__.py +350 -256
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +480 -514
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +204 -153
- ansible/executor/powershell/become_wrapper.ps1 +107 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
- ansible/executor/powershell/exec_wrapper.ps1 +675 -196
- ansible/executor/powershell/module_manifest.py +469 -265
- ansible/executor/powershell/module_wrapper.ps1 +195 -186
- ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
- ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +139 -149
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +270 -297
- ansible/executor/task_queue_manager.py +135 -137
- ansible/executor/task_result.py +182 -79
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +26 -25
- ansible/galaxy/collection/__init__.py +6 -14
- ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +4 -4
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +6 -10
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +50 -73
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +37 -54
- ansible/inventory/manager.py +79 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
- ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
- ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
- ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +961 -0
- ansible/module_utils/_internal/_datatag/_tags.py +16 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_deprecator.py +157 -0
- ansible/module_utils/_internal/_errors.py +101 -0
- ansible/module_utils/_internal/_event_utils.py +61 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
- ansible/module_utils/_internal/_messages.py +130 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_info.py +38 -0
- ansible/module_utils/_internal/_stack.py +22 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_text_utils.py +6 -0
- ansible/module_utils/_internal/_traceback.py +92 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +303 -202
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/collections.py +7 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -3
- ansible/module_utils/common/respawn.py +11 -33
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +143 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +10 -13
- ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +49 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +2 -2
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +5 -5
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +2 -3
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/sysctl.py +4 -6
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +3 -3
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +27 -13
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +2 -3
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/linux.py +3 -3
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +7 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/service.py +21 -31
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +64 -35
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +69 -49
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +32 -51
- ansible/modules/assemble.py +16 -14
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +24 -24
- ansible/modules/async_wrapper.py +20 -25
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +13 -20
- ansible/modules/copy.py +60 -147
- ansible/modules/cron.py +24 -21
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +13 -15
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +184 -144
- ansible/modules/find.py +22 -20
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +77 -54
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +38 -38
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +15 -32
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +22 -24
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +10 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +21 -26
- ansible/modules/raw.py +6 -6
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +10 -14
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +10 -17
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +16 -19
- ansible/modules/stat.py +15 -31
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +7 -7
- ansible/modules/systemd_service.py +7 -7
- ansible/modules/sysvinit.py +9 -9
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +38 -17
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +45 -32
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +70 -60
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +10 -9
- ansible/parsing/ajson.py +17 -37
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +62 -60
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +327 -99
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +187 -134
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +32 -26
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +14 -17
- ansible/playbook/playbook_include.py +27 -62
- ansible/playbook/role/__init__.py +64 -49
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +28 -12
- ansible/playbook/task.py +192 -121
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +58 -26
- ansible/plugins/action/__init__.py +188 -186
- ansible/plugins/action/add_host.py +2 -2
- ansible/plugins/action/assemble.py +11 -18
- ansible/plugins/action/assert.py +55 -67
- ansible/plugins/action/async_status.py +7 -2
- ansible/plugins/action/copy.py +14 -17
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +7 -8
- ansible/plugins/action/gather_facts.py +13 -14
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +8 -14
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +27 -38
- ansible/plugins/action/service.py +9 -18
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +47 -67
- ansible/plugins/action/unarchive.py +6 -16
- ansible/plugins/action/uri.py +9 -20
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +52 -63
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +294 -201
- ansible/plugins/callback/default.py +99 -95
- ansible/plugins/callback/junit.py +44 -43
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +34 -21
- ansible/plugins/callback/tree.py +27 -16
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +156 -60
- ansible/plugins/connection/paramiko_ssh.py +34 -24
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +326 -86
- ansible/plugins/connection/winrm.py +62 -141
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +8 -4
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +245 -120
- ansible/plugins/filter/encryption.py +42 -34
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/pow.yml +1 -1
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/strftime.yml +3 -3
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +107 -86
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +190 -120
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +72 -19
- ansible/plugins/loader.py +383 -198
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +19 -73
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +87 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +47 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +4 -10
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +58 -4
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +106 -31
- ansible/plugins/shell/sh.py +13 -7
- ansible/plugins/strategy/__init__.py +168 -193
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +75 -35
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/finished.yml +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +5 -8
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +353 -943
- ansible/utils/__init__.py +0 -18
- ansible/utils/collection_loader/__init__.py +54 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +82 -96
- ansible/utils/collection_loader/_collection_meta.py +15 -8
- ansible/utils/display.py +485 -73
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/galaxy.py +2 -2
- ansible/utils/hashing.py +8 -10
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +10 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +10 -12
- ansible/utils/plugin_docs.py +16 -14
- ansible/utils/py3compat.py +2 -7
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +6 -2
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +55 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +220 -285
- ansible/vars/plugins.py +4 -4
- ansible/vars/reserved.py +13 -12
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
- ansible_core-2.19.0.dist-info/RECORD +1097 -0
- ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +6 -0
- ansible_test/_internal/ansible_util.py +3 -1
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -5
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +52 -5
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +3 -2
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +22 -5
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +8 -2
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +19 -2
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +25 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +44 -4
- ansible_test/_internal/commands/units/__init__.py +5 -1
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +23 -13
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/debugging.py +166 -0
- ansible_test/_internal/delegation.py +22 -13
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +260 -16
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +39 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +95 -4
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/processes.py +80 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +11 -4
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +28 -0
- ansible_test/_internal/ssh.py +2 -5
- ansible_test/_internal/target.py +9 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +3 -1
- ansible_test/_internal/timeout.py +2 -1
- ansible_test/_internal/util.py +41 -12
- ansible_test/_internal/util_common.py +18 -5
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/injector/python.py +8 -0
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +38 -36
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
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:
|
|
@@ -333,11 +323,8 @@ def get_state(path):
|
|
|
333
323
|
return 'file'
|
|
334
324
|
|
|
335
325
|
return 'absent'
|
|
336
|
-
except
|
|
337
|
-
|
|
338
|
-
return 'absent'
|
|
339
|
-
else:
|
|
340
|
-
raise
|
|
326
|
+
except FileNotFoundError:
|
|
327
|
+
return 'absent'
|
|
341
328
|
|
|
342
329
|
|
|
343
330
|
# This should be moved into the common file utilities
|
|
@@ -377,8 +364,8 @@ def recursive_set_attributes(b_path, follow, file_args, mtime, atime):
|
|
|
377
364
|
except RuntimeError as e:
|
|
378
365
|
# on Python3 "RecursionError" is raised which is derived from "RuntimeError"
|
|
379
366
|
# TODO once this function is moved into the common file utilities, this should probably raise more general exception
|
|
380
|
-
|
|
381
|
-
|
|
367
|
+
module.fail_json(
|
|
368
|
+
msg=f"Could not recursively set attributes on {to_native(b_path)}. Original error was: '{to_native(e)}'"
|
|
382
369
|
)
|
|
383
370
|
|
|
384
371
|
return changed
|
|
@@ -419,17 +406,17 @@ def initial_diff(path, state, prev_state):
|
|
|
419
406
|
def get_timestamp_for_time(formatted_time, time_format):
|
|
420
407
|
if formatted_time == 'preserve':
|
|
421
408
|
return None
|
|
422
|
-
|
|
409
|
+
if formatted_time == 'now':
|
|
423
410
|
return Sentinel
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
411
|
+
try:
|
|
412
|
+
struct = time.strptime(formatted_time, time_format)
|
|
413
|
+
struct_time = time.mktime(struct)
|
|
414
|
+
except (ValueError, OverflowError) as e:
|
|
415
|
+
module.fail_json(
|
|
416
|
+
msg=f"Error while obtaining timestamp for time {formatted_time} using format {time_format}: {to_native(e, nonstring='simplerepr')}",
|
|
417
|
+
)
|
|
431
418
|
|
|
432
|
-
|
|
419
|
+
return struct_time
|
|
433
420
|
|
|
434
421
|
|
|
435
422
|
def update_timestamp_for_file(path, mtime, atime, diff=None):
|
|
@@ -486,18 +473,19 @@ def update_timestamp_for_file(path, mtime, atime, diff=None):
|
|
|
486
473
|
diff['before']['atime'] = previous_atime
|
|
487
474
|
diff['after']['atime'] = atime
|
|
488
475
|
except OSError as e:
|
|
489
|
-
|
|
490
|
-
|
|
476
|
+
module.fail_json(
|
|
477
|
+
msg=f"Error while updating modification or access time: {to_native(e, nonstring='simplerepr')}",
|
|
478
|
+
path=path
|
|
479
|
+
)
|
|
491
480
|
return True
|
|
492
481
|
|
|
493
482
|
|
|
494
483
|
def keep_backward_compatibility_on_timestamps(parameter, state):
|
|
495
484
|
if state in ['file', 'hard', 'directory', 'link'] and parameter is None:
|
|
496
485
|
return 'preserve'
|
|
497
|
-
|
|
486
|
+
if state == 'touch' and parameter is None:
|
|
498
487
|
return 'now'
|
|
499
|
-
|
|
500
|
-
return parameter
|
|
488
|
+
return parameter
|
|
501
489
|
|
|
502
490
|
|
|
503
491
|
def execute_diff_peek(path):
|
|
@@ -530,14 +518,20 @@ def ensure_absent(path):
|
|
|
530
518
|
try:
|
|
531
519
|
shutil.rmtree(b_path, ignore_errors=False)
|
|
532
520
|
except Exception as e:
|
|
533
|
-
|
|
521
|
+
module.fail_json(
|
|
522
|
+
msg=f"rmtree failed: {to_native(e)}"
|
|
523
|
+
)
|
|
534
524
|
else:
|
|
535
525
|
try:
|
|
536
526
|
os.unlink(b_path)
|
|
537
|
-
except
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
527
|
+
except FileNotFoundError:
|
|
528
|
+
pass
|
|
529
|
+
except OSError as ex:
|
|
530
|
+
module.fail_json(
|
|
531
|
+
msg="Unlinking failed.",
|
|
532
|
+
path=path,
|
|
533
|
+
exception=ex,
|
|
534
|
+
)
|
|
541
535
|
|
|
542
536
|
result.update({'path': path, 'changed': True, 'diff': diff, 'state': 'absent'})
|
|
543
537
|
else:
|
|
@@ -565,10 +559,12 @@ def execute_touch(path, follow, timestamps):
|
|
|
565
559
|
try:
|
|
566
560
|
open(b_path, 'wb').close()
|
|
567
561
|
changed = True
|
|
568
|
-
except
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
562
|
+
except OSError as ex:
|
|
563
|
+
module.fail_json(
|
|
564
|
+
msg="Error, could not touch target.",
|
|
565
|
+
path=path,
|
|
566
|
+
exception=ex,
|
|
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':
|
|
@@ -859,26 +894,27 @@ def ensure_hardlink(path, src, follow, force, timestamps):
|
|
|
859
894
|
if os.path.exists(b_path):
|
|
860
895
|
try:
|
|
861
896
|
os.unlink(b_path)
|
|
862
|
-
except
|
|
863
|
-
|
|
864
|
-
raise
|
|
897
|
+
except FileNotFoundError:
|
|
898
|
+
pass
|
|
865
899
|
os.link(b_src, b_tmppath)
|
|
866
900
|
os.rename(b_tmppath, b_path)
|
|
867
901
|
except OSError as e:
|
|
868
902
|
if os.path.exists(b_tmppath):
|
|
869
903
|
os.unlink(b_tmppath)
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
904
|
+
module.fail_json(
|
|
905
|
+
msg=f"Error while replacing: {to_native(e, nonstring='simplerepr')}",
|
|
906
|
+
path=path
|
|
907
|
+
)
|
|
873
908
|
else:
|
|
874
909
|
try:
|
|
875
910
|
if follow and os.path.islink(b_src):
|
|
876
911
|
b_src = os.readlink(b_src)
|
|
877
912
|
os.link(b_src, b_path)
|
|
878
913
|
except OSError as e:
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
914
|
+
module.fail_json(
|
|
915
|
+
msg=f"Error while linking: {to_native(e, nonstring='simplerepr')}",
|
|
916
|
+
path=path
|
|
917
|
+
)
|
|
882
918
|
|
|
883
919
|
if module.check_mode and not os.path.exists(b_path):
|
|
884
920
|
return {'dest': path, 'src': src, 'changed': changed, 'diff': diff}
|
|
@@ -940,48 +976,52 @@ def main():
|
|
|
940
976
|
supports_check_mode=True,
|
|
941
977
|
)
|
|
942
978
|
|
|
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
|
-
|
|
979
|
+
try:
|
|
980
|
+
additional_parameter_handling(module.params)
|
|
981
|
+
params = module.params
|
|
982
|
+
|
|
983
|
+
state = params['state']
|
|
984
|
+
recurse = params['recurse']
|
|
985
|
+
force = params['force']
|
|
986
|
+
follow = params['follow']
|
|
987
|
+
path = params['path']
|
|
988
|
+
src = params['src']
|
|
989
|
+
|
|
990
|
+
if module.check_mode and state != 'absent':
|
|
991
|
+
file_args = module.load_file_common_arguments(module.params)
|
|
992
|
+
if file_args['owner']:
|
|
993
|
+
check_owner_exists(module, file_args['owner'])
|
|
994
|
+
if file_args['group']:
|
|
995
|
+
check_group_exists(module, file_args['group'])
|
|
996
|
+
|
|
997
|
+
timestamps = {}
|
|
998
|
+
timestamps['modification_time'] = keep_backward_compatibility_on_timestamps(params['modification_time'], state)
|
|
999
|
+
timestamps['modification_time_format'] = params['modification_time_format']
|
|
1000
|
+
timestamps['access_time'] = keep_backward_compatibility_on_timestamps(params['access_time'], state)
|
|
1001
|
+
timestamps['access_time_format'] = params['access_time_format']
|
|
1002
|
+
|
|
1003
|
+
# short-circuit for diff_peek
|
|
1004
|
+
if params['_diff_peek'] is not None:
|
|
1005
|
+
appears_binary = execute_diff_peek(to_bytes(path, errors='surrogate_or_strict'))
|
|
1006
|
+
module.exit_json(path=path, changed=False, appears_binary=appears_binary)
|
|
1007
|
+
|
|
1008
|
+
if state == 'file':
|
|
1009
|
+
result = ensure_file_attributes(path, follow, timestamps)
|
|
1010
|
+
elif state == 'directory':
|
|
1011
|
+
result = ensure_directory(path, follow, recurse, timestamps)
|
|
1012
|
+
elif state == 'link':
|
|
1013
|
+
result = ensure_symlink(path, src, follow, force, timestamps)
|
|
1014
|
+
elif state == 'hard':
|
|
1015
|
+
result = ensure_hardlink(path, src, follow, force, timestamps)
|
|
1016
|
+
elif state == 'touch':
|
|
1017
|
+
result = execute_touch(path, follow, timestamps)
|
|
1018
|
+
elif state == 'absent':
|
|
1019
|
+
result = ensure_absent(path)
|
|
1020
|
+
except AnsibleModuleError as ex:
|
|
1021
|
+
module.fail_json(**ex.results)
|
|
1022
|
+
|
|
1023
|
+
if not module._diff:
|
|
1024
|
+
result.pop('diff', None)
|
|
985
1025
|
|
|
986
1026
|
module.exit_json(**result)
|
|
987
1027
|
|