ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz/__init__.py +0 -0
- ansible/_internal/_ansiballz/_builder.py +101 -0
- ansible/_internal/_ansiballz/_wrapper.py +262 -0
- ansible/_internal/_collection_proxy.py +47 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_alarm_timeout.py +66 -0
- ansible/_internal/_errors/_captured.py +123 -0
- ansible/_internal/_errors/_error_factory.py +89 -0
- ansible/_internal/_errors/_error_utils.py +240 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_task_timeout.py +28 -0
- ansible/_internal/_event_formatting.py +127 -0
- ansible/_internal/_json/__init__.py +214 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +189 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_ssh/__init__.py +0 -0
- ansible/_internal/_ssh/_agent_launch.py +91 -0
- ansible/_internal/_ssh/_ssh_agent.py +619 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +12 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +592 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1106 -0
- ansible/_internal/_templating/_jinja_common.py +323 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +375 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_template_vars.py +72 -0
- ansible/_internal/_templating/_transform.py +70 -0
- ansible/_internal/_templating/_utils.py +108 -0
- ansible/_internal/_testing.py +26 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +70 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +93 -104
- ansible/cli/_ssh_askpass.py +54 -0
- ansible/cli/adhoc.py +20 -10
- ansible/cli/arguments/option_helpers.py +163 -10
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +13 -11
- ansible/cli/doc.py +134 -77
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -28
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +6 -3
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/compat/importlib_resources.py +9 -12
- ansible/config/base.yml +218 -133
- ansible/config/manager.py +220 -159
- ansible/constants.py +2 -65
- ansible/errors/__init__.py +350 -256
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +480 -514
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +204 -153
- ansible/executor/powershell/become_wrapper.ps1 +107 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
- ansible/executor/powershell/exec_wrapper.ps1 +675 -196
- ansible/executor/powershell/module_manifest.py +469 -265
- ansible/executor/powershell/module_wrapper.ps1 +195 -186
- ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
- ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +139 -149
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +270 -297
- ansible/executor/task_queue_manager.py +135 -137
- ansible/executor/task_result.py +182 -79
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +26 -25
- ansible/galaxy/collection/__init__.py +6 -14
- ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +4 -4
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +6 -10
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +50 -73
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +37 -54
- ansible/inventory/manager.py +79 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
- ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
- ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
- ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
- ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +961 -0
- ansible/module_utils/_internal/_datatag/_tags.py +16 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_deprecator.py +157 -0
- ansible/module_utils/_internal/_errors.py +101 -0
- ansible/module_utils/_internal/_event_utils.py +61 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
- ansible/module_utils/_internal/_messages.py +130 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_info.py +38 -0
- ansible/module_utils/_internal/_stack.py +22 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_text_utils.py +6 -0
- ansible/module_utils/_internal/_traceback.py +92 -0
- ansible/module_utils/_internal/_validation.py +14 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +303 -202
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/arg_spec.py +8 -3
- ansible/module_utils/common/collections.py +7 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -3
- ansible/module_utils/common/respawn.py +11 -33
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +143 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +10 -13
- ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +49 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +2 -2
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +5 -5
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +2 -3
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/sysctl.py +4 -6
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +3 -3
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +27 -13
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +2 -3
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/linux.py +3 -3
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +7 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
- ansible/module_utils/service.py +21 -31
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +64 -35
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +69 -49
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +32 -51
- ansible/modules/assemble.py +16 -14
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +24 -24
- ansible/modules/async_wrapper.py +20 -25
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +13 -20
- ansible/modules/copy.py +60 -147
- ansible/modules/cron.py +24 -21
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +39 -13
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +13 -15
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +184 -144
- ansible/modules/find.py +22 -20
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +77 -54
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +38 -38
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +15 -32
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +6 -6
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +22 -24
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +10 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +21 -26
- ansible/modules/raw.py +6 -6
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +10 -14
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +10 -17
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +16 -19
- ansible/modules/stat.py +15 -31
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +7 -7
- ansible/modules/systemd_service.py +7 -7
- ansible/modules/sysvinit.py +9 -9
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +38 -17
- ansible/modules/uri.py +33 -26
- ansible/modules/user.py +45 -32
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +70 -60
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +10 -9
- ansible/parsing/ajson.py +17 -37
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +62 -60
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/jsonify.py +5 -1
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +327 -99
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +43 -335
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +187 -134
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +32 -26
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +14 -17
- ansible/playbook/playbook_include.py +27 -62
- ansible/playbook/role/__init__.py +64 -49
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +28 -12
- ansible/playbook/task.py +192 -121
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +58 -26
- ansible/plugins/action/__init__.py +188 -186
- ansible/plugins/action/add_host.py +2 -2
- ansible/plugins/action/assemble.py +11 -18
- ansible/plugins/action/assert.py +55 -67
- ansible/plugins/action/async_status.py +7 -2
- ansible/plugins/action/copy.py +14 -17
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +7 -8
- ansible/plugins/action/gather_facts.py +13 -14
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +8 -14
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +27 -38
- ansible/plugins/action/service.py +9 -18
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +47 -67
- ansible/plugins/action/unarchive.py +6 -16
- ansible/plugins/action/uri.py +9 -20
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +52 -63
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +294 -201
- ansible/plugins/callback/default.py +99 -95
- ansible/plugins/callback/junit.py +44 -43
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +34 -21
- ansible/plugins/callback/tree.py +27 -16
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +156 -60
- ansible/plugins/connection/paramiko_ssh.py +34 -24
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +326 -86
- ansible/plugins/connection/winrm.py +62 -141
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +8 -4
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +245 -120
- ansible/plugins/filter/encryption.py +42 -34
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/pow.yml +1 -1
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/strftime.yml +3 -3
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +107 -86
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +190 -120
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +72 -19
- ansible/plugins/loader.py +383 -198
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +19 -73
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +87 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +47 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +4 -10
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +58 -4
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +106 -31
- ansible/plugins/shell/sh.py +13 -7
- ansible/plugins/strategy/__init__.py +168 -193
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +75 -35
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/finished.yml +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +5 -8
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +353 -943
- ansible/utils/__init__.py +0 -18
- ansible/utils/collection_loader/__init__.py +54 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +82 -96
- ansible/utils/collection_loader/_collection_meta.py +15 -8
- ansible/utils/display.py +485 -73
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/galaxy.py +2 -2
- ansible/utils/hashing.py +8 -10
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +10 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +10 -12
- ansible/utils/plugin_docs.py +16 -14
- ansible/utils/py3compat.py +2 -7
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +6 -2
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +55 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +220 -285
- ansible/vars/plugins.py +4 -4
- ansible/vars/reserved.py +13 -12
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
- ansible_core-2.19.0.dist-info/RECORD +1097 -0
- ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +6 -0
- ansible_test/_internal/ansible_util.py +3 -1
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -5
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +52 -5
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +3 -2
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +22 -5
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +8 -2
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +19 -2
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +25 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +44 -4
- ansible_test/_internal/commands/units/__init__.py +5 -1
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +23 -13
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/debugging.py +166 -0
- ansible_test/_internal/delegation.py +22 -13
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +260 -16
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +39 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +95 -4
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/processes.py +80 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +11 -4
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +28 -0
- ansible_test/_internal/ssh.py +2 -5
- ansible_test/_internal/target.py +9 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +3 -1
- ansible_test/_internal/timeout.py +2 -1
- ansible_test/_internal/util.py +41 -12
- ansible_test/_internal/util_common.py +18 -5
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/injector/python.py +8 -0
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +38 -36
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"""Profiles to represent individual test hosts or a user-provided inventory file."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import abc
|
|
5
6
|
import dataclasses
|
|
7
|
+
import importlib
|
|
8
|
+
import json
|
|
6
9
|
import os
|
|
10
|
+
import pathlib
|
|
7
11
|
import shlex
|
|
8
12
|
import tempfile
|
|
9
13
|
import time
|
|
@@ -57,6 +61,9 @@ from .util import (
|
|
|
57
61
|
HostConnectionError,
|
|
58
62
|
ANSIBLE_TEST_TARGET_ROOT,
|
|
59
63
|
WINDOWS_CONNECTION_VARIABLES,
|
|
64
|
+
ANSIBLE_SOURCE_ROOT,
|
|
65
|
+
ANSIBLE_LIB_ROOT,
|
|
66
|
+
ANSIBLE_TEST_ROOT,
|
|
60
67
|
)
|
|
61
68
|
|
|
62
69
|
from .util_common import (
|
|
@@ -91,6 +98,8 @@ from .venv import (
|
|
|
91
98
|
|
|
92
99
|
from .ssh import (
|
|
93
100
|
SshConnectionDetail,
|
|
101
|
+
create_ssh_port_forwards,
|
|
102
|
+
SshProcess,
|
|
94
103
|
)
|
|
95
104
|
|
|
96
105
|
from .ansible_util import (
|
|
@@ -205,7 +214,7 @@ class Inventory:
|
|
|
205
214
|
inventory_text += f'[{group}]\n'
|
|
206
215
|
|
|
207
216
|
for host, variables in hosts.items():
|
|
208
|
-
kvp = ' '.join(f
|
|
217
|
+
kvp = ' '.join(f"{key}={value!r}" for key, value in variables.items())
|
|
209
218
|
inventory_text += f'{host} {kvp}\n'
|
|
210
219
|
|
|
211
220
|
inventory_text += '\n'
|
|
@@ -234,18 +243,24 @@ class HostProfile(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
|
234
243
|
*,
|
|
235
244
|
args: EnvironmentConfig,
|
|
236
245
|
config: THostConfig,
|
|
237
|
-
|
|
246
|
+
controller: ControllerHostProfile,
|
|
238
247
|
) -> None:
|
|
239
248
|
self.args = args
|
|
240
249
|
self.config = config
|
|
241
|
-
self.controller =
|
|
242
|
-
self.targets = targets
|
|
250
|
+
self.controller = not controller # this profile is a controller whenever the `controller` arg was not provided
|
|
251
|
+
self.targets = args.targets if self.controller else [] # only keep targets if this profile is a controller
|
|
252
|
+
self.controller_profile = controller if isinstance(self, ControllerProfile) else None
|
|
243
253
|
|
|
244
254
|
self.state: dict[str, t.Any] = {}
|
|
245
255
|
"""State that must be persisted across delegation."""
|
|
246
256
|
self.cache: dict[str, t.Any] = {}
|
|
247
257
|
"""Cache that must not be persisted across delegation."""
|
|
248
258
|
|
|
259
|
+
@property
|
|
260
|
+
@abc.abstractmethod
|
|
261
|
+
def name(self) -> str:
|
|
262
|
+
"""The name of the host profile."""
|
|
263
|
+
|
|
249
264
|
def provision(self) -> None:
|
|
250
265
|
"""Provision the host before delegation."""
|
|
251
266
|
|
|
@@ -273,6 +288,179 @@ class HostProfile(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
|
273
288
|
# args will be populated after the instances are restored
|
|
274
289
|
self.cache = {}
|
|
275
290
|
|
|
291
|
+
def __str__(self) -> str:
|
|
292
|
+
return f'{self.__class__.__name__}: {self.name}'
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
class DebuggableProfile(HostProfile[THostConfig], metaclass=abc.ABCMeta):
|
|
296
|
+
"""Base class for profiles remote debugging."""
|
|
297
|
+
|
|
298
|
+
__PYDEVD_PORT_KEY = 'pydevd_port'
|
|
299
|
+
__DEBUGGING_FORWARDER_KEY = 'debugging_forwarder'
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def debugging_enabled(self) -> bool:
|
|
303
|
+
"""Returns `True` if debugging is enabled for this profile, otherwise `False`."""
|
|
304
|
+
if self.controller:
|
|
305
|
+
return self.args.metadata.debugger_flags.enable
|
|
306
|
+
|
|
307
|
+
return self.args.metadata.debugger_flags.ansiballz
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
def pydevd_port(self) -> int:
|
|
311
|
+
"""The pydevd port to use."""
|
|
312
|
+
return self.state.get(self.__PYDEVD_PORT_KEY) or self.origin_pydev_port
|
|
313
|
+
|
|
314
|
+
@property
|
|
315
|
+
def debugging_forwarder(self) -> SshProcess | None:
|
|
316
|
+
"""The SSH forwarding process, if enabled."""
|
|
317
|
+
return self.cache.get(self.__DEBUGGING_FORWARDER_KEY)
|
|
318
|
+
|
|
319
|
+
@debugging_forwarder.setter
|
|
320
|
+
def debugging_forwarder(self, value: SshProcess) -> None:
|
|
321
|
+
"""The SSH forwarding process, if enabled."""
|
|
322
|
+
self.cache[self.__DEBUGGING_FORWARDER_KEY] = value
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def origin_pydev_port(self) -> int:
|
|
326
|
+
"""The pydevd port on the origin."""
|
|
327
|
+
return self.args.metadata.debugger_settings.port
|
|
328
|
+
|
|
329
|
+
def enable_debugger_forwarding(self, ssh: SshConnectionDetail) -> None:
|
|
330
|
+
"""Enable pydevd port forwarding from the origin."""
|
|
331
|
+
if not self.debugging_enabled:
|
|
332
|
+
return
|
|
333
|
+
|
|
334
|
+
endpoint = ('localhost', self.origin_pydev_port)
|
|
335
|
+
forwards = [endpoint]
|
|
336
|
+
|
|
337
|
+
self.debugging_forwarder = create_ssh_port_forwards(self.args, ssh, forwards)
|
|
338
|
+
|
|
339
|
+
port_forwards = self.debugging_forwarder.collect_port_forwards()
|
|
340
|
+
|
|
341
|
+
self.state[self.__PYDEVD_PORT_KEY] = port = port_forwards[endpoint]
|
|
342
|
+
|
|
343
|
+
display.info(f'Remote debugging of {self.name!r} is available on port {port}.', verbosity=1)
|
|
344
|
+
|
|
345
|
+
def deprovision(self) -> None:
|
|
346
|
+
"""Deprovision the host after delegation has completed."""
|
|
347
|
+
super().deprovision()
|
|
348
|
+
|
|
349
|
+
if not self.debugging_forwarder:
|
|
350
|
+
return # forwarding not in use
|
|
351
|
+
|
|
352
|
+
self.debugging_forwarder.terminate()
|
|
353
|
+
|
|
354
|
+
display.info(f'Waiting for the {self.name!r} remote debugging SSH port forwarding process to terminate.', verbosity=1)
|
|
355
|
+
|
|
356
|
+
self.debugging_forwarder.wait()
|
|
357
|
+
|
|
358
|
+
def get_pydevd_settrace_arguments(self) -> dict[str, object]:
|
|
359
|
+
"""Get settrace arguments for pydevd."""
|
|
360
|
+
return self.args.metadata.debugger_settings.settrace | dict(
|
|
361
|
+
host="localhost",
|
|
362
|
+
port=self.pydevd_port,
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
def get_pydevd_environment_variables(self) -> dict[str, str]:
|
|
366
|
+
"""Get environment variables needed to configure pydevd for debugging."""
|
|
367
|
+
return dict(
|
|
368
|
+
PATHS_FROM_ECLIPSE_TO_PYTHON=json.dumps(list(self.get_source_mapping().items())),
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
def get_source_mapping(self) -> dict[str, str]:
|
|
372
|
+
"""Get the source mapping from the given metadata."""
|
|
373
|
+
from . import data_context
|
|
374
|
+
|
|
375
|
+
if collection := data_context().content.collection:
|
|
376
|
+
source_mapping = {
|
|
377
|
+
f"{self.args.metadata.ansible_test_root}/": f'{ANSIBLE_TEST_ROOT}/',
|
|
378
|
+
f"{self.args.metadata.ansible_lib_root}/": f'{ANSIBLE_LIB_ROOT}/',
|
|
379
|
+
f'{self.args.metadata.collection_root}/ansible_collections/': f'{collection.root}/ansible_collections/',
|
|
380
|
+
}
|
|
381
|
+
else:
|
|
382
|
+
ansible_source_root = pathlib.Path(self.args.metadata.ansible_lib_root).parent.parent
|
|
383
|
+
|
|
384
|
+
source_mapping = {
|
|
385
|
+
f"{ansible_source_root}/": f'{ANSIBLE_SOURCE_ROOT}/',
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
source_mapping = {key: value for key, value in source_mapping.items() if key != value}
|
|
389
|
+
|
|
390
|
+
return source_mapping
|
|
391
|
+
|
|
392
|
+
def activate_debugger(self) -> None:
|
|
393
|
+
"""Activate the debugger after delegation."""
|
|
394
|
+
if not self.args.metadata.loaded or not self.args.metadata.debugger_flags.self:
|
|
395
|
+
return
|
|
396
|
+
|
|
397
|
+
display.info('Activating remote debugging of ansible-test.', verbosity=1)
|
|
398
|
+
|
|
399
|
+
os.environ.update(self.get_pydevd_environment_variables())
|
|
400
|
+
|
|
401
|
+
debugging_module = importlib.import_module(self.args.metadata.debugger_settings.module)
|
|
402
|
+
debugging_module.settrace(**self.get_pydevd_settrace_arguments())
|
|
403
|
+
|
|
404
|
+
pass # pylint: disable=unnecessary-pass # when suspend is True, execution pauses here -- it's also a convenient place to put a breakpoint
|
|
405
|
+
|
|
406
|
+
def get_ansiballz_inventory_variables(self) -> dict[str, t.Any]:
|
|
407
|
+
"""
|
|
408
|
+
Return inventory variables for remote debugging of AnsiballZ modules.
|
|
409
|
+
When delegating, this function must be called after delegation.
|
|
410
|
+
"""
|
|
411
|
+
if not self.args.metadata.debugger_flags.ansiballz:
|
|
412
|
+
return {}
|
|
413
|
+
|
|
414
|
+
return dict(
|
|
415
|
+
_ansible_ansiballz_debugger_config=json.dumps(self.get_ansiballz_debugger_config()),
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
def get_ansiballz_environment_variables(self) -> dict[str, t.Any]:
|
|
419
|
+
"""
|
|
420
|
+
Return environment variables for remote debugging of AnsiballZ modules.
|
|
421
|
+
When delegating, this function must be called after delegation.
|
|
422
|
+
"""
|
|
423
|
+
if not self.args.metadata.debugger_flags.ansiballz:
|
|
424
|
+
return {}
|
|
425
|
+
|
|
426
|
+
return dict(
|
|
427
|
+
_ANSIBLE_ANSIBALLZ_DEBUGGER_CONFIG=json.dumps(self.get_ansiballz_debugger_config()),
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
def get_ansiballz_debugger_config(self) -> dict[str, t.Any]:
|
|
431
|
+
"""
|
|
432
|
+
Return config for remote debugging of AnsiballZ modules.
|
|
433
|
+
When delegating, this function must be called after delegation.
|
|
434
|
+
"""
|
|
435
|
+
debugger_config = dict(
|
|
436
|
+
module=self.args.metadata.debugger_settings.module,
|
|
437
|
+
settrace=self.get_pydevd_settrace_arguments(),
|
|
438
|
+
source_mapping=self.get_source_mapping(),
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
display.info(f'>>> Debugger Config ({self.name} AnsiballZ)\n{json.dumps(debugger_config, indent=4)}', verbosity=3)
|
|
442
|
+
|
|
443
|
+
return debugger_config
|
|
444
|
+
|
|
445
|
+
def get_ansible_cli_environment_variables(self) -> dict[str, t.Any]:
|
|
446
|
+
"""
|
|
447
|
+
Return environment variables for remote debugging of the Ansible CLI.
|
|
448
|
+
When delegating, this function must be called after delegation.
|
|
449
|
+
"""
|
|
450
|
+
if not self.args.metadata.debugger_flags.cli:
|
|
451
|
+
return {}
|
|
452
|
+
|
|
453
|
+
debugger_config = dict(
|
|
454
|
+
args=['-m', 'pydevd', '--client', 'localhost', '--port', str(self.pydevd_port)] + self.args.metadata.debugger_settings.args + ['--file'],
|
|
455
|
+
env=self.get_pydevd_environment_variables(),
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
display.info(f'>>> Debugger Config ({self.name} Ansible CLI)\n{json.dumps(debugger_config, indent=4)}', verbosity=3)
|
|
459
|
+
|
|
460
|
+
return dict(
|
|
461
|
+
ANSIBLE_TEST_DEBUGGER_CONFIG=json.dumps(debugger_config),
|
|
462
|
+
)
|
|
463
|
+
|
|
276
464
|
|
|
277
465
|
class PosixProfile(HostProfile[TPosixConfig], metaclass=abc.ABCMeta):
|
|
278
466
|
"""Base class for POSIX host profiles."""
|
|
@@ -296,7 +484,7 @@ class PosixProfile(HostProfile[TPosixConfig], metaclass=abc.ABCMeta):
|
|
|
296
484
|
return python
|
|
297
485
|
|
|
298
486
|
|
|
299
|
-
class ControllerHostProfile(PosixProfile[TControllerHostConfig], metaclass=abc.ABCMeta):
|
|
487
|
+
class ControllerHostProfile(PosixProfile[TControllerHostConfig], DebuggableProfile[TControllerHostConfig], metaclass=abc.ABCMeta):
|
|
300
488
|
"""Base class for profiles usable as a controller."""
|
|
301
489
|
|
|
302
490
|
@abc.abstractmethod
|
|
@@ -319,6 +507,11 @@ class SshTargetHostProfile(HostProfile[THostConfig], metaclass=abc.ABCMeta):
|
|
|
319
507
|
class RemoteProfile(SshTargetHostProfile[TRemoteConfig], metaclass=abc.ABCMeta):
|
|
320
508
|
"""Base class for remote instance profiles."""
|
|
321
509
|
|
|
510
|
+
@property
|
|
511
|
+
def name(self) -> str:
|
|
512
|
+
"""The name of the host profile."""
|
|
513
|
+
return self.config.name
|
|
514
|
+
|
|
322
515
|
@property
|
|
323
516
|
def core_ci_state(self) -> t.Optional[dict[str, str]]:
|
|
324
517
|
"""The saved Ansible Core CI state."""
|
|
@@ -338,6 +531,8 @@ class RemoteProfile(SshTargetHostProfile[TRemoteConfig], metaclass=abc.ABCMeta):
|
|
|
338
531
|
|
|
339
532
|
def deprovision(self) -> None:
|
|
340
533
|
"""Deprovision the host after delegation has completed."""
|
|
534
|
+
super().deprovision()
|
|
535
|
+
|
|
341
536
|
if self.args.remote_terminate == TerminateMode.ALWAYS or (self.args.remote_terminate == TerminateMode.SUCCESS and self.args.success):
|
|
342
537
|
self.delete_instance()
|
|
343
538
|
|
|
@@ -393,9 +588,19 @@ class RemoteProfile(SshTargetHostProfile[TRemoteConfig], metaclass=abc.ABCMeta):
|
|
|
393
588
|
)
|
|
394
589
|
|
|
395
590
|
|
|
396
|
-
class ControllerProfile(SshTargetHostProfile[ControllerConfig], PosixProfile[ControllerConfig]):
|
|
591
|
+
class ControllerProfile(SshTargetHostProfile[ControllerConfig], PosixProfile[ControllerConfig], DebuggableProfile[ControllerConfig]):
|
|
397
592
|
"""Host profile for the controller as a target."""
|
|
398
593
|
|
|
594
|
+
@property
|
|
595
|
+
def name(self) -> str:
|
|
596
|
+
"""The name of the host profile."""
|
|
597
|
+
return self.controller_profile.name
|
|
598
|
+
|
|
599
|
+
@property
|
|
600
|
+
def pydevd_port(self) -> int:
|
|
601
|
+
"""The pydevd port to use."""
|
|
602
|
+
return self.controller_profile.pydevd_port
|
|
603
|
+
|
|
399
604
|
def get_controller_target_connections(self) -> list[SshConnection]:
|
|
400
605
|
"""Return SSH connection(s) for accessing the host as a target from the controller."""
|
|
401
606
|
settings = SshConnectionDetail(
|
|
@@ -410,7 +615,7 @@ class ControllerProfile(SshTargetHostProfile[ControllerConfig], PosixProfile[Con
|
|
|
410
615
|
return [SshConnection(self.args, settings)]
|
|
411
616
|
|
|
412
617
|
|
|
413
|
-
class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[DockerConfig]):
|
|
618
|
+
class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[DockerConfig], DebuggableProfile[DockerConfig]):
|
|
414
619
|
"""Host profile for a docker instance."""
|
|
415
620
|
|
|
416
621
|
MARKER = 'ansible-test-marker'
|
|
@@ -424,6 +629,11 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
424
629
|
command_privileged: bool
|
|
425
630
|
expected_mounts: tuple[CGroupMount, ...]
|
|
426
631
|
|
|
632
|
+
@property
|
|
633
|
+
def name(self) -> str:
|
|
634
|
+
"""The name of the host profile."""
|
|
635
|
+
return self.config.name
|
|
636
|
+
|
|
427
637
|
@property
|
|
428
638
|
def container_name(self) -> t.Optional[str]:
|
|
429
639
|
"""Return the stored container name, if any, otherwise None."""
|
|
@@ -460,7 +670,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
460
670
|
image=self.config.image,
|
|
461
671
|
name=f'ansible-test-{self.label}',
|
|
462
672
|
ports=[22],
|
|
463
|
-
publish_ports=not self.controller, #
|
|
673
|
+
publish_ports=self.debugging_enabled or not self.controller, # SSH to the controller is not required unless remote debugging is enabled
|
|
464
674
|
options=init_config.options,
|
|
465
675
|
cleanup=False,
|
|
466
676
|
cmd=self.build_init_command(init_config, init_probe),
|
|
@@ -600,7 +810,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
600
810
|
# The host namespace must be used to permit the container to access the cgroup v1 systemd hierarchy created by Podman.
|
|
601
811
|
'--cgroupns', 'host',
|
|
602
812
|
# Mask the host cgroup tmpfs mount to avoid exposing the host cgroup v1 hierarchies (or cgroup v2 hybrid) to the container.
|
|
603
|
-
# Podman will provide a cgroup v1 systemd
|
|
813
|
+
# Podman will provide a cgroup v1 systemd hierarchy on top of this.
|
|
604
814
|
'--tmpfs', '/sys/fs/cgroup',
|
|
605
815
|
))
|
|
606
816
|
|
|
@@ -973,8 +1183,13 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
973
1183
|
docker_logs(self.args, self.container_name)
|
|
974
1184
|
raise
|
|
975
1185
|
|
|
1186
|
+
if self.debugging_enabled:
|
|
1187
|
+
self.enable_debugger_forwarding(self.get_ssh_connection_detail(HostType.origin))
|
|
1188
|
+
|
|
976
1189
|
def deprovision(self) -> None:
|
|
977
1190
|
"""Deprovision the host after delegation has completed."""
|
|
1191
|
+
super().deprovision()
|
|
1192
|
+
|
|
978
1193
|
container_exists = False
|
|
979
1194
|
|
|
980
1195
|
if self.container_name:
|
|
@@ -1024,10 +1239,10 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
1024
1239
|
|
|
1025
1240
|
raise HostConnectionError(f'Timeout waiting for {self.config.name} container {self.container_name}.', callback)
|
|
1026
1241
|
|
|
1027
|
-
def
|
|
1028
|
-
"""Return SSH connection
|
|
1242
|
+
def get_ssh_connection_detail(self, host_type: str) -> SshConnectionDetail:
|
|
1243
|
+
"""Return SSH connection detail for the specified host type."""
|
|
1029
1244
|
containers = get_container_database(self.args)
|
|
1030
|
-
access = containers.data[
|
|
1245
|
+
access = containers.data[host_type]['__test_hosts__'][self.container_name]
|
|
1031
1246
|
|
|
1032
1247
|
host = access.host_ip
|
|
1033
1248
|
port = dict(access.port_map())[22]
|
|
@@ -1045,7 +1260,11 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
1045
1260
|
enable_rsa_sha1='centos6' in self.config.image,
|
|
1046
1261
|
)
|
|
1047
1262
|
|
|
1048
|
-
return
|
|
1263
|
+
return settings
|
|
1264
|
+
|
|
1265
|
+
def get_controller_target_connections(self) -> list[SshConnection]:
|
|
1266
|
+
"""Return SSH connection(s) for accessing the host as a target from the controller."""
|
|
1267
|
+
return [SshConnection(self.args, self.get_ssh_connection_detail(HostType.control))]
|
|
1049
1268
|
|
|
1050
1269
|
def get_origin_controller_connection(self) -> DockerConnection:
|
|
1051
1270
|
"""Return a connection for accessing the host as a controller from the origin."""
|
|
@@ -1115,6 +1334,11 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
|
|
|
1115
1334
|
class NetworkInventoryProfile(HostProfile[NetworkInventoryConfig]):
|
|
1116
1335
|
"""Host profile for a network inventory."""
|
|
1117
1336
|
|
|
1337
|
+
@property
|
|
1338
|
+
def name(self) -> str:
|
|
1339
|
+
"""The name of the host profile."""
|
|
1340
|
+
return self.config.path
|
|
1341
|
+
|
|
1118
1342
|
|
|
1119
1343
|
class NetworkRemoteProfile(RemoteProfile[NetworkRemoteConfig]):
|
|
1120
1344
|
"""Host profile for a network remote instance."""
|
|
@@ -1196,6 +1420,11 @@ class NetworkRemoteProfile(RemoteProfile[NetworkRemoteConfig]):
|
|
|
1196
1420
|
class OriginProfile(ControllerHostProfile[OriginConfig]):
|
|
1197
1421
|
"""Host profile for origin."""
|
|
1198
1422
|
|
|
1423
|
+
@property
|
|
1424
|
+
def name(self) -> str:
|
|
1425
|
+
"""The name of the host profile."""
|
|
1426
|
+
return 'origin'
|
|
1427
|
+
|
|
1199
1428
|
def get_origin_controller_connection(self) -> LocalConnection:
|
|
1200
1429
|
"""Return a connection for accessing the host as a controller from the origin."""
|
|
1201
1430
|
return LocalConnection(self.args)
|
|
@@ -1205,13 +1434,18 @@ class OriginProfile(ControllerHostProfile[OriginConfig]):
|
|
|
1205
1434
|
return os.getcwd()
|
|
1206
1435
|
|
|
1207
1436
|
|
|
1208
|
-
class PosixRemoteProfile(ControllerHostProfile[PosixRemoteConfig], RemoteProfile[PosixRemoteConfig]):
|
|
1437
|
+
class PosixRemoteProfile(ControllerHostProfile[PosixRemoteConfig], RemoteProfile[PosixRemoteConfig], DebuggableProfile[PosixRemoteConfig]):
|
|
1209
1438
|
"""Host profile for a POSIX remote instance."""
|
|
1210
1439
|
|
|
1211
1440
|
def wait(self) -> None:
|
|
1212
1441
|
"""Wait for the instance to be ready. Executed before delegation for the controller and after delegation for targets."""
|
|
1213
1442
|
self.wait_until_ready()
|
|
1214
1443
|
|
|
1444
|
+
def setup(self) -> None:
|
|
1445
|
+
"""Perform out-of-band setup before delegation."""
|
|
1446
|
+
if self.debugging_enabled:
|
|
1447
|
+
self.enable_debugger_forwarding(self.get_origin_controller_connection().settings)
|
|
1448
|
+
|
|
1215
1449
|
def configure(self) -> None:
|
|
1216
1450
|
"""Perform in-band configuration. Executed before delegation for the controller and after delegation for targets."""
|
|
1217
1451
|
# a target uses a single python version, but a controller may include additional versions for targets running on the controller
|
|
@@ -1316,6 +1550,11 @@ class PosixRemoteProfile(ControllerHostProfile[PosixRemoteConfig], RemoteProfile
|
|
|
1316
1550
|
class PosixSshProfile(SshTargetHostProfile[PosixSshConfig], PosixProfile[PosixSshConfig]):
|
|
1317
1551
|
"""Host profile for a POSIX SSH instance."""
|
|
1318
1552
|
|
|
1553
|
+
@property
|
|
1554
|
+
def name(self) -> str:
|
|
1555
|
+
"""The name of the host profile."""
|
|
1556
|
+
return self.config.host
|
|
1557
|
+
|
|
1319
1558
|
def get_controller_target_connections(self) -> list[SshConnection]:
|
|
1320
1559
|
"""Return SSH connection(s) for accessing the host as a target from the controller."""
|
|
1321
1560
|
settings = SshConnectionDetail(
|
|
@@ -1333,6 +1572,11 @@ class PosixSshProfile(SshTargetHostProfile[PosixSshConfig], PosixProfile[PosixSs
|
|
|
1333
1572
|
class WindowsInventoryProfile(SshTargetHostProfile[WindowsInventoryConfig]):
|
|
1334
1573
|
"""Host profile for a Windows inventory."""
|
|
1335
1574
|
|
|
1575
|
+
@property
|
|
1576
|
+
def name(self) -> str:
|
|
1577
|
+
"""The name of the host profile."""
|
|
1578
|
+
return self.config.path
|
|
1579
|
+
|
|
1336
1580
|
def get_controller_target_connections(self) -> list[SshConnection]:
|
|
1337
1581
|
"""Return SSH connection(s) for accessing the host as a target from the controller."""
|
|
1338
1582
|
inventory = parse_inventory(self.args, self.config.path)
|
|
@@ -1435,9 +1679,9 @@ def get_config_profile_type_map() -> dict[t.Type[HostConfig], t.Type[HostProfile
|
|
|
1435
1679
|
def create_host_profile(
|
|
1436
1680
|
args: EnvironmentConfig,
|
|
1437
1681
|
config: HostConfig,
|
|
1438
|
-
controller:
|
|
1682
|
+
controller: ControllerHostProfile | None,
|
|
1439
1683
|
) -> HostProfile:
|
|
1440
1684
|
"""Create and return a host profile from the given host configuration."""
|
|
1441
1685
|
profile_type = get_config_profile_type_map()[type(config)]
|
|
1442
|
-
profile = profile_type(args=args, config=config,
|
|
1686
|
+
profile = profile_type(args=args, config=config, controller=controller)
|
|
1443
1687
|
return profile
|
ansible_test/_internal/http.py
CHANGED
ansible_test/_internal/init.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Inventory creation from host profiles."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import shutil
|
|
6
|
+
import sys
|
|
5
7
|
import typing as t
|
|
6
8
|
|
|
7
9
|
from .config import (
|
|
@@ -13,6 +15,11 @@ from .util import (
|
|
|
13
15
|
exclude_none_values,
|
|
14
16
|
)
|
|
15
17
|
|
|
18
|
+
from .host_configs import (
|
|
19
|
+
ControllerConfig,
|
|
20
|
+
PosixRemoteConfig,
|
|
21
|
+
)
|
|
22
|
+
|
|
16
23
|
from .host_profiles import (
|
|
17
24
|
ControllerHostProfile,
|
|
18
25
|
ControllerProfile,
|
|
@@ -23,6 +30,7 @@ from .host_profiles import (
|
|
|
23
30
|
SshTargetHostProfile,
|
|
24
31
|
WindowsInventoryProfile,
|
|
25
32
|
WindowsRemoteProfile,
|
|
33
|
+
DebuggableProfile,
|
|
26
34
|
)
|
|
27
35
|
|
|
28
36
|
from .ssh import (
|
|
@@ -30,12 +38,40 @@ from .ssh import (
|
|
|
30
38
|
)
|
|
31
39
|
|
|
32
40
|
|
|
41
|
+
def get_common_variables(target_profile: HostProfile, controller: bool = False) -> dict[str, t.Any]:
|
|
42
|
+
"""Get variables common to all scenarios, but dependent on the target profile."""
|
|
43
|
+
target_config = target_profile.config
|
|
44
|
+
|
|
45
|
+
if controller or isinstance(target_config, ControllerConfig):
|
|
46
|
+
# The current process is running on the controller, so consult the controller directly when it is the target.
|
|
47
|
+
macos = sys.platform == 'darwin'
|
|
48
|
+
elif isinstance(target_config, PosixRemoteConfig):
|
|
49
|
+
# The target is not the controller, so consult the remote config for that target.
|
|
50
|
+
macos = target_config.name.startswith('macos/')
|
|
51
|
+
else:
|
|
52
|
+
# The target is a type which either cannot be macOS or for which the OS is unknown.
|
|
53
|
+
# There is currently no means for the user to override this for user provided hosts.
|
|
54
|
+
macos = False
|
|
55
|
+
|
|
56
|
+
common_variables: dict[str, t.Any] = {}
|
|
57
|
+
|
|
58
|
+
if macos:
|
|
59
|
+
# When using sudo on macOS we may encounter permission denied errors when dropping privileges due to inability to access the current working directory.
|
|
60
|
+
# To compensate for this we'll perform a `cd /` before running any commands after `sudo` succeeds.
|
|
61
|
+
common_variables.update(ansible_sudo_chdir='/')
|
|
62
|
+
|
|
63
|
+
if isinstance(target_profile, DebuggableProfile):
|
|
64
|
+
common_variables.update(target_profile.get_ansiballz_inventory_variables())
|
|
65
|
+
|
|
66
|
+
return common_variables
|
|
67
|
+
|
|
68
|
+
|
|
33
69
|
def create_controller_inventory(args: EnvironmentConfig, path: str, controller_host: ControllerHostProfile) -> None:
|
|
34
70
|
"""Create and return inventory for use in controller-only integration tests."""
|
|
35
71
|
inventory = Inventory(
|
|
36
72
|
host_groups=dict(
|
|
37
73
|
testgroup=dict(
|
|
38
|
-
testhost=dict(
|
|
74
|
+
testhost=get_common_variables(controller_host, controller=True) | dict(
|
|
39
75
|
ansible_connection='local',
|
|
40
76
|
ansible_pipelining='yes',
|
|
41
77
|
ansible_python_interpreter=controller_host.python.path,
|
|
@@ -129,7 +165,7 @@ def create_posix_inventory(args: EnvironmentConfig, path: str, target_hosts: lis
|
|
|
129
165
|
inventory = Inventory(
|
|
130
166
|
host_groups=dict(
|
|
131
167
|
testgroup=dict(
|
|
132
|
-
testhost=dict(
|
|
168
|
+
testhost=get_common_variables(target_host) | dict(
|
|
133
169
|
ansible_connection='local',
|
|
134
170
|
ansible_pipelining='yes',
|
|
135
171
|
ansible_python_interpreter=target_host.python.path,
|
|
@@ -145,7 +181,7 @@ def create_posix_inventory(args: EnvironmentConfig, path: str, target_hosts: lis
|
|
|
145
181
|
|
|
146
182
|
ssh = connections[0]
|
|
147
183
|
|
|
148
|
-
testhost: dict[str, t.Optional[t.Union[str, int]]] = dict(
|
|
184
|
+
testhost: dict[str, t.Optional[t.Union[str, int]]] = get_common_variables(target_host) | dict(
|
|
149
185
|
ansible_connection='ssh',
|
|
150
186
|
ansible_pipelining='yes',
|
|
151
187
|
ansible_python_interpreter=ssh.settings.python_interpreter,
|