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.

Files changed (757) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz/__init__.py +0 -0
  3. ansible/_internal/_ansiballz/_builder.py +101 -0
  4. ansible/_internal/_ansiballz/_wrapper.py +262 -0
  5. ansible/_internal/_collection_proxy.py +47 -0
  6. ansible/_internal/_datatag/__init__.py +0 -0
  7. ansible/_internal/_datatag/_tags.py +130 -0
  8. ansible/_internal/_datatag/_utils.py +19 -0
  9. ansible/_internal/_datatag/_wrappers.py +33 -0
  10. ansible/_internal/_errors/__init__.py +0 -0
  11. ansible/_internal/_errors/_alarm_timeout.py +66 -0
  12. ansible/_internal/_errors/_captured.py +123 -0
  13. ansible/_internal/_errors/_error_factory.py +89 -0
  14. ansible/_internal/_errors/_error_utils.py +240 -0
  15. ansible/_internal/_errors/_handler.py +91 -0
  16. ansible/_internal/_errors/_task_timeout.py +28 -0
  17. ansible/_internal/_event_formatting.py +127 -0
  18. ansible/_internal/_json/__init__.py +214 -0
  19. ansible/_internal/_json/_legacy_encoder.py +34 -0
  20. ansible/_internal/_json/_profiles/__init__.py +0 -0
  21. ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
  22. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  23. ansible/_internal/_json/_profiles/_legacy.py +189 -0
  24. ansible/_internal/_locking.py +21 -0
  25. ansible/_internal/_plugins/__init__.py +0 -0
  26. ansible/_internal/_plugins/_cache.py +57 -0
  27. ansible/_internal/_ssh/__init__.py +0 -0
  28. ansible/_internal/_ssh/_agent_launch.py +91 -0
  29. ansible/_internal/_ssh/_ssh_agent.py +619 -0
  30. ansible/_internal/_task.py +78 -0
  31. ansible/_internal/_templating/__init__.py +12 -0
  32. ansible/_internal/_templating/_access.py +86 -0
  33. ansible/_internal/_templating/_chain_templar.py +63 -0
  34. ansible/_internal/_templating/_datatag.py +95 -0
  35. ansible/_internal/_templating/_engine.py +592 -0
  36. ansible/_internal/_templating/_errors.py +28 -0
  37. ansible/_internal/_templating/_jinja_bits.py +1106 -0
  38. ansible/_internal/_templating/_jinja_common.py +323 -0
  39. ansible/_internal/_templating/_jinja_patches.py +44 -0
  40. ansible/_internal/_templating/_jinja_plugins.py +375 -0
  41. ansible/_internal/_templating/_lazy_containers.py +633 -0
  42. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  43. ansible/_internal/_templating/_template_vars.py +72 -0
  44. ansible/_internal/_templating/_transform.py +70 -0
  45. ansible/_internal/_templating/_utils.py +108 -0
  46. ansible/_internal/_testing.py +26 -0
  47. ansible/_internal/_wrapt.py +1052 -0
  48. ansible/_internal/_yaml/__init__.py +0 -0
  49. ansible/_internal/_yaml/_constructor.py +240 -0
  50. ansible/_internal/_yaml/_dumper.py +70 -0
  51. ansible/_internal/_yaml/_errors.py +166 -0
  52. ansible/_internal/_yaml/_loader.py +66 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  59. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  60. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  61. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  62. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  63. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  64. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  65. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  66. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  67. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  68. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  69. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  70. ansible/cli/__init__.py +93 -104
  71. ansible/cli/_ssh_askpass.py +54 -0
  72. ansible/cli/adhoc.py +20 -10
  73. ansible/cli/arguments/option_helpers.py +163 -10
  74. ansible/cli/config.py +43 -68
  75. ansible/cli/console.py +13 -11
  76. ansible/cli/doc.py +134 -77
  77. ansible/cli/galaxy.py +27 -20
  78. ansible/cli/inventory.py +28 -28
  79. ansible/cli/playbook.py +4 -12
  80. ansible/cli/pull.py +6 -3
  81. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  82. ansible/cli/vault.py +12 -11
  83. ansible/compat/__init__.py +2 -2
  84. ansible/compat/importlib_resources.py +9 -12
  85. ansible/config/base.yml +218 -133
  86. ansible/config/manager.py +220 -159
  87. ansible/constants.py +2 -65
  88. ansible/errors/__init__.py +350 -256
  89. ansible/executor/interpreter_discovery.py +28 -149
  90. ansible/executor/module_common.py +480 -514
  91. ansible/executor/play_iterator.py +22 -27
  92. ansible/executor/playbook_executor.py +11 -11
  93. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  94. ansible/executor/powershell/async_wrapper.ps1 +204 -153
  95. ansible/executor/powershell/become_wrapper.ps1 +107 -144
  96. ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
  97. ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
  98. ansible/executor/powershell/exec_wrapper.ps1 +675 -196
  99. ansible/executor/powershell/module_manifest.py +469 -265
  100. ansible/executor/powershell/module_wrapper.ps1 +195 -186
  101. ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
  102. ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
  103. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  104. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  105. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  106. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  107. ansible/executor/process/worker.py +139 -149
  108. ansible/executor/stats.py +5 -5
  109. ansible/executor/task_executor.py +270 -297
  110. ansible/executor/task_queue_manager.py +135 -137
  111. ansible/executor/task_result.py +182 -79
  112. ansible/galaxy/__init__.py +2 -2
  113. ansible/galaxy/api.py +26 -25
  114. ansible/galaxy/collection/__init__.py +6 -14
  115. ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
  116. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  117. ansible/galaxy/dependency_resolution/providers.py +4 -4
  118. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  119. ansible/galaxy/role.py +6 -10
  120. ansible/galaxy/token.py +28 -21
  121. ansible/inventory/data.py +47 -57
  122. ansible/inventory/group.py +50 -73
  123. ansible/inventory/helpers.py +9 -0
  124. ansible/inventory/host.py +37 -54
  125. ansible/inventory/manager.py +79 -34
  126. ansible/keyword_desc.yml +1 -1
  127. ansible/module_utils/_internal/__init__.py +55 -0
  128. ansible/module_utils/_internal/_ambient_context.py +58 -0
  129. ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
  130. ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
  131. ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
  132. ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
  133. ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
  134. ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
  135. ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
  136. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  137. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  138. ansible/module_utils/_internal/_datatag/__init__.py +961 -0
  139. ansible/module_utils/_internal/_datatag/_tags.py +16 -0
  140. ansible/module_utils/_internal/_debugging.py +31 -0
  141. ansible/module_utils/_internal/_deprecator.py +157 -0
  142. ansible/module_utils/_internal/_errors.py +101 -0
  143. ansible/module_utils/_internal/_event_utils.py +61 -0
  144. ansible/module_utils/_internal/_json/__init__.py +63 -0
  145. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  146. ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
  147. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  148. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
  149. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
  150. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  151. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  152. ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
  153. ansible/module_utils/_internal/_messages.py +130 -0
  154. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  155. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
  156. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  157. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  158. ansible/module_utils/_internal/_plugin_info.py +38 -0
  159. ansible/module_utils/_internal/_stack.py +22 -0
  160. ansible/module_utils/_internal/_testing.py +0 -0
  161. ansible/module_utils/_internal/_text_utils.py +6 -0
  162. ansible/module_utils/_internal/_traceback.py +92 -0
  163. ansible/module_utils/_internal/_validation.py +14 -0
  164. ansible/module_utils/ansible_release.py +2 -2
  165. ansible/module_utils/api.py +1 -2
  166. ansible/module_utils/basic.py +303 -202
  167. ansible/module_utils/common/_utils.py +24 -28
  168. ansible/module_utils/common/arg_spec.py +8 -3
  169. ansible/module_utils/common/collections.py +7 -2
  170. ansible/module_utils/common/dict_transformations.py +2 -2
  171. ansible/module_utils/common/file.py +2 -2
  172. ansible/module_utils/common/json.py +90 -84
  173. ansible/module_utils/common/locale.py +2 -2
  174. ansible/module_utils/common/parameters.py +27 -24
  175. ansible/module_utils/common/process.py +2 -3
  176. ansible/module_utils/common/respawn.py +11 -33
  177. ansible/module_utils/common/sentinel.py +66 -0
  178. ansible/module_utils/common/sys_info.py +8 -8
  179. ansible/module_utils/common/text/converters.py +16 -37
  180. ansible/module_utils/common/validation.py +35 -24
  181. ansible/module_utils/common/warnings.py +143 -25
  182. ansible/module_utils/common/yaml.py +29 -3
  183. ansible/module_utils/compat/datetime.py +33 -21
  184. ansible/module_utils/compat/paramiko.py +21 -10
  185. ansible/module_utils/compat/typing.py +6 -5
  186. ansible/module_utils/connection.py +10 -13
  187. ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
  188. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  189. ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
  190. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  191. ansible/module_utils/datatag.py +49 -0
  192. ansible/module_utils/distro/__init__.py +2 -2
  193. ansible/module_utils/facts/ansible_collector.py +4 -5
  194. ansible/module_utils/facts/collector.py +13 -14
  195. ansible/module_utils/facts/compat.py +4 -4
  196. ansible/module_utils/facts/default_collectors.py +1 -1
  197. ansible/module_utils/facts/hardware/aix.py +34 -0
  198. ansible/module_utils/facts/hardware/base.py +2 -2
  199. ansible/module_utils/facts/hardware/darwin.py +1 -3
  200. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  201. ansible/module_utils/facts/hardware/linux.py +5 -5
  202. ansible/module_utils/facts/namespace.py +1 -1
  203. ansible/module_utils/facts/network/base.py +1 -1
  204. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  205. ansible/module_utils/facts/network/iscsi.py +1 -2
  206. ansible/module_utils/facts/network/nvme.py +1 -2
  207. ansible/module_utils/facts/other/facter.py +2 -3
  208. ansible/module_utils/facts/other/ohai.py +2 -3
  209. ansible/module_utils/facts/sysctl.py +4 -6
  210. ansible/module_utils/facts/system/apparmor.py +1 -2
  211. ansible/module_utils/facts/system/caps.py +3 -3
  212. ansible/module_utils/facts/system/chroot.py +1 -2
  213. ansible/module_utils/facts/system/cmdline.py +1 -2
  214. ansible/module_utils/facts/system/date_time.py +5 -3
  215. ansible/module_utils/facts/system/distribution.py +27 -13
  216. ansible/module_utils/facts/system/dns.py +1 -1
  217. ansible/module_utils/facts/system/env.py +1 -2
  218. ansible/module_utils/facts/system/fips.py +7 -20
  219. ansible/module_utils/facts/system/loadavg.py +1 -2
  220. ansible/module_utils/facts/system/local.py +2 -3
  221. ansible/module_utils/facts/system/lsb.py +1 -2
  222. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  223. ansible/module_utils/facts/system/platform.py +1 -2
  224. ansible/module_utils/facts/system/python.py +1 -2
  225. ansible/module_utils/facts/system/selinux.py +1 -1
  226. ansible/module_utils/facts/system/service_mgr.py +1 -2
  227. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  228. ansible/module_utils/facts/system/systemd.py +1 -1
  229. ansible/module_utils/facts/system/user.py +1 -2
  230. ansible/module_utils/facts/utils.py +3 -3
  231. ansible/module_utils/facts/virtual/base.py +1 -1
  232. ansible/module_utils/facts/virtual/linux.py +3 -3
  233. ansible/module_utils/facts/virtual/sunos.py +3 -15
  234. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  235. ansible/module_utils/json_utils.py +2 -2
  236. ansible/module_utils/parsing/convert_bool.py +7 -1
  237. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  238. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  239. ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
  240. ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
  241. ansible/module_utils/service.py +21 -31
  242. ansible/module_utils/splitter.py +7 -7
  243. ansible/module_utils/testing.py +31 -0
  244. ansible/module_utils/urls.py +64 -35
  245. ansible/modules/add_host.py +4 -4
  246. ansible/modules/apt.py +69 -49
  247. ansible/modules/apt_key.py +19 -12
  248. ansible/modules/apt_repository.py +32 -51
  249. ansible/modules/assemble.py +16 -14
  250. ansible/modules/assert.py +4 -4
  251. ansible/modules/async_status.py +24 -24
  252. ansible/modules/async_wrapper.py +20 -25
  253. ansible/modules/blockinfile.py +6 -7
  254. ansible/modules/command.py +13 -20
  255. ansible/modules/copy.py +60 -147
  256. ansible/modules/cron.py +24 -21
  257. ansible/modules/deb822_repository.py +8 -9
  258. ansible/modules/debconf.py +5 -5
  259. ansible/modules/debug.py +4 -4
  260. ansible/modules/dnf.py +8 -8
  261. ansible/modules/dnf5.py +39 -13
  262. ansible/modules/dpkg_selections.py +4 -4
  263. ansible/modules/expect.py +13 -15
  264. ansible/modules/fail.py +4 -4
  265. ansible/modules/fetch.py +4 -4
  266. ansible/modules/file.py +184 -144
  267. ansible/modules/find.py +22 -20
  268. ansible/modules/gather_facts.py +3 -3
  269. ansible/modules/get_url.py +77 -54
  270. ansible/modules/getent.py +7 -9
  271. ansible/modules/git.py +38 -38
  272. ansible/modules/group.py +6 -6
  273. ansible/modules/group_by.py +4 -4
  274. ansible/modules/hostname.py +15 -32
  275. ansible/modules/import_playbook.py +6 -6
  276. ansible/modules/import_role.py +6 -6
  277. ansible/modules/import_tasks.py +6 -6
  278. ansible/modules/include_role.py +6 -6
  279. ansible/modules/include_tasks.py +6 -6
  280. ansible/modules/include_vars.py +6 -6
  281. ansible/modules/iptables.py +86 -73
  282. ansible/modules/known_hosts.py +22 -24
  283. ansible/modules/lineinfile.py +5 -5
  284. ansible/modules/meta.py +4 -4
  285. ansible/modules/mount_facts.py +2 -2
  286. ansible/modules/package.py +10 -4
  287. ansible/modules/package_facts.py +22 -10
  288. ansible/modules/pause.py +6 -6
  289. ansible/modules/ping.py +6 -6
  290. ansible/modules/pip.py +21 -26
  291. ansible/modules/raw.py +6 -6
  292. ansible/modules/reboot.py +6 -6
  293. ansible/modules/replace.py +10 -14
  294. ansible/modules/rpm_key.py +7 -8
  295. ansible/modules/script.py +4 -4
  296. ansible/modules/service.py +10 -17
  297. ansible/modules/service_facts.py +87 -10
  298. ansible/modules/set_fact.py +5 -5
  299. ansible/modules/set_stats.py +4 -4
  300. ansible/modules/setup.py +2 -2
  301. ansible/modules/shell.py +6 -6
  302. ansible/modules/slurp.py +16 -19
  303. ansible/modules/stat.py +15 -31
  304. ansible/modules/subversion.py +15 -15
  305. ansible/modules/systemd.py +7 -7
  306. ansible/modules/systemd_service.py +7 -7
  307. ansible/modules/sysvinit.py +9 -9
  308. ansible/modules/tempfile.py +5 -6
  309. ansible/modules/template.py +6 -6
  310. ansible/modules/unarchive.py +38 -17
  311. ansible/modules/uri.py +33 -26
  312. ansible/modules/user.py +45 -32
  313. ansible/modules/validate_argument_spec.py +10 -7
  314. ansible/modules/wait_for.py +70 -60
  315. ansible/modules/wait_for_connection.py +6 -6
  316. ansible/modules/yum_repository.py +10 -9
  317. ansible/parsing/ajson.py +17 -37
  318. ansible/parsing/dataloader.py +99 -54
  319. ansible/parsing/mod_args.py +62 -60
  320. ansible/parsing/plugin_docs.py +21 -86
  321. ansible/parsing/quoting.py +1 -1
  322. ansible/parsing/splitter.py +27 -12
  323. ansible/parsing/utils/addresses.py +24 -24
  324. ansible/parsing/utils/jsonify.py +5 -1
  325. ansible/parsing/utils/yaml.py +32 -61
  326. ansible/parsing/vault/__init__.py +327 -99
  327. ansible/parsing/yaml/__init__.py +0 -18
  328. ansible/parsing/yaml/dumper.py +6 -120
  329. ansible/parsing/yaml/loader.py +6 -39
  330. ansible/parsing/yaml/objects.py +43 -335
  331. ansible/playbook/__init__.py +1 -1
  332. ansible/playbook/attribute.py +8 -3
  333. ansible/playbook/base.py +187 -134
  334. ansible/playbook/block.py +26 -24
  335. ansible/playbook/collectionsearch.py +1 -15
  336. ansible/playbook/conditional.py +3 -77
  337. ansible/playbook/handler.py +8 -2
  338. ansible/playbook/helpers.py +41 -53
  339. ansible/playbook/included_file.py +32 -26
  340. ansible/playbook/loop_control.py +2 -2
  341. ansible/playbook/play.py +85 -44
  342. ansible/playbook/play_context.py +14 -17
  343. ansible/playbook/playbook_include.py +27 -62
  344. ansible/playbook/role/__init__.py +64 -49
  345. ansible/playbook/role/definition.py +15 -17
  346. ansible/playbook/role/include.py +2 -4
  347. ansible/playbook/role/metadata.py +10 -11
  348. ansible/playbook/role_include.py +3 -3
  349. ansible/playbook/taggable.py +28 -12
  350. ansible/playbook/task.py +192 -121
  351. ansible/playbook/task_include.py +5 -5
  352. ansible/plugins/__init__.py +58 -26
  353. ansible/plugins/action/__init__.py +188 -186
  354. ansible/plugins/action/add_host.py +2 -2
  355. ansible/plugins/action/assemble.py +11 -18
  356. ansible/plugins/action/assert.py +55 -67
  357. ansible/plugins/action/async_status.py +7 -2
  358. ansible/plugins/action/copy.py +14 -17
  359. ansible/plugins/action/debug.py +37 -31
  360. ansible/plugins/action/dnf.py +3 -4
  361. ansible/plugins/action/fail.py +1 -1
  362. ansible/plugins/action/fetch.py +7 -8
  363. ansible/plugins/action/gather_facts.py +13 -14
  364. ansible/plugins/action/group_by.py +1 -1
  365. ansible/plugins/action/include_vars.py +10 -11
  366. ansible/plugins/action/package.py +8 -14
  367. ansible/plugins/action/pause.py +2 -2
  368. ansible/plugins/action/script.py +27 -38
  369. ansible/plugins/action/service.py +9 -18
  370. ansible/plugins/action/set_fact.py +3 -12
  371. ansible/plugins/action/set_stats.py +3 -8
  372. ansible/plugins/action/template.py +47 -67
  373. ansible/plugins/action/unarchive.py +6 -16
  374. ansible/plugins/action/uri.py +9 -20
  375. ansible/plugins/action/validate_argument_spec.py +5 -5
  376. ansible/plugins/action/wait_for_connection.py +1 -1
  377. ansible/plugins/become/__init__.py +31 -8
  378. ansible/plugins/become/runas.py +71 -0
  379. ansible/plugins/become/su.py +13 -8
  380. ansible/plugins/become/sudo.py +19 -0
  381. ansible/plugins/cache/__init__.py +52 -63
  382. ansible/plugins/cache/base.py +8 -0
  383. ansible/plugins/cache/jsonfile.py +10 -16
  384. ansible/plugins/cache/memory.py +6 -12
  385. ansible/plugins/callback/__init__.py +294 -201
  386. ansible/plugins/callback/default.py +99 -95
  387. ansible/plugins/callback/junit.py +44 -43
  388. ansible/plugins/callback/minimal.py +28 -25
  389. ansible/plugins/callback/oneline.py +34 -21
  390. ansible/plugins/callback/tree.py +27 -16
  391. ansible/plugins/connection/__init__.py +47 -34
  392. ansible/plugins/connection/local.py +156 -60
  393. ansible/plugins/connection/paramiko_ssh.py +34 -24
  394. ansible/plugins/connection/psrp.py +76 -165
  395. ansible/plugins/connection/ssh.py +326 -86
  396. ansible/plugins/connection/winrm.py +62 -141
  397. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  398. ansible/plugins/doc_fragments/action_core.py +6 -6
  399. ansible/plugins/doc_fragments/backup.py +2 -2
  400. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  401. ansible/plugins/doc_fragments/constructed.py +8 -4
  402. ansible/plugins/doc_fragments/decrypt.py +2 -2
  403. ansible/plugins/doc_fragments/default_callback.py +2 -2
  404. ansible/plugins/doc_fragments/files.py +2 -2
  405. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  406. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  407. ansible/plugins/doc_fragments/return_common.py +2 -2
  408. ansible/plugins/doc_fragments/template_common.py +4 -4
  409. ansible/plugins/doc_fragments/url.py +17 -1
  410. ansible/plugins/doc_fragments/url_windows.py +2 -2
  411. ansible/plugins/doc_fragments/validate.py +2 -2
  412. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  413. ansible/plugins/filter/__init__.py +6 -2
  414. ansible/plugins/filter/b64decode.yml +22 -0
  415. ansible/plugins/filter/b64encode.yml +22 -0
  416. ansible/plugins/filter/bool.yml +11 -4
  417. ansible/plugins/filter/core.py +245 -120
  418. ansible/plugins/filter/encryption.py +42 -34
  419. ansible/plugins/filter/flatten.yml +3 -2
  420. ansible/plugins/filter/human_to_bytes.yml +1 -1
  421. ansible/plugins/filter/mathstuff.py +30 -37
  422. ansible/plugins/filter/password_hash.yml +8 -0
  423. ansible/plugins/filter/pow.yml +1 -1
  424. ansible/plugins/filter/regex_search.yml +1 -4
  425. ansible/plugins/filter/root.yml +1 -1
  426. ansible/plugins/filter/split.yml +1 -1
  427. ansible/plugins/filter/strftime.yml +3 -3
  428. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  429. ansible/plugins/filter/to_uuid.yml +1 -1
  430. ansible/plugins/filter/to_yaml.yml +0 -4
  431. ansible/plugins/filter/unvault.yml +1 -1
  432. ansible/plugins/filter/urls.py +1 -1
  433. ansible/plugins/filter/urlsplit.py +8 -9
  434. ansible/plugins/filter/vault.yml +14 -9
  435. ansible/plugins/filter/win_basename.yml +6 -1
  436. ansible/plugins/filter/win_dirname.yml +5 -0
  437. ansible/plugins/inventory/__init__.py +107 -86
  438. ansible/plugins/inventory/advanced_host_list.py +7 -5
  439. ansible/plugins/inventory/auto.py +11 -4
  440. ansible/plugins/inventory/constructed.py +21 -24
  441. ansible/plugins/inventory/generator.py +16 -11
  442. ansible/plugins/inventory/host_list.py +7 -5
  443. ansible/plugins/inventory/ini.py +78 -44
  444. ansible/plugins/inventory/script.py +190 -120
  445. ansible/plugins/inventory/toml.py +16 -126
  446. ansible/plugins/inventory/yaml.py +10 -8
  447. ansible/plugins/list.py +72 -19
  448. ansible/plugins/loader.py +383 -198
  449. ansible/plugins/lookup/__init__.py +21 -4
  450. ansible/plugins/lookup/config.py +21 -35
  451. ansible/plugins/lookup/csvfile.py +19 -73
  452. ansible/plugins/lookup/dict.py +1 -6
  453. ansible/plugins/lookup/env.py +12 -9
  454. ansible/plugins/lookup/file.py +5 -8
  455. ansible/plugins/lookup/first_found.py +87 -55
  456. ansible/plugins/lookup/indexed_items.py +1 -10
  457. ansible/plugins/lookup/ini.py +14 -13
  458. ansible/plugins/lookup/items.py +1 -1
  459. ansible/plugins/lookup/lines.py +8 -1
  460. ansible/plugins/lookup/list.py +1 -1
  461. ansible/plugins/lookup/nested.py +2 -18
  462. ansible/plugins/lookup/password.py +5 -5
  463. ansible/plugins/lookup/pipe.py +5 -7
  464. ansible/plugins/lookup/sequence.py +18 -8
  465. ansible/plugins/lookup/subelements.py +1 -4
  466. ansible/plugins/lookup/template.py +47 -36
  467. ansible/plugins/lookup/together.py +0 -12
  468. ansible/plugins/lookup/unvault.py +1 -5
  469. ansible/plugins/lookup/url.py +4 -10
  470. ansible/plugins/lookup/vars.py +16 -24
  471. ansible/plugins/shell/__init__.py +58 -4
  472. ansible/plugins/shell/cmd.py +2 -2
  473. ansible/plugins/shell/powershell.py +106 -31
  474. ansible/plugins/shell/sh.py +13 -7
  475. ansible/plugins/strategy/__init__.py +168 -193
  476. ansible/plugins/strategy/debug.py +2 -2
  477. ansible/plugins/strategy/free.py +16 -31
  478. ansible/plugins/strategy/host_pinned.py +2 -2
  479. ansible/plugins/strategy/linear.py +41 -41
  480. ansible/plugins/terminal/__init__.py +4 -4
  481. ansible/plugins/test/__init__.py +7 -2
  482. ansible/plugins/test/core.py +75 -35
  483. ansible/plugins/test/files.py +1 -1
  484. ansible/plugins/test/finished.yml +1 -1
  485. ansible/plugins/test/mathstuff.py +3 -3
  486. ansible/plugins/test/uri.py +5 -8
  487. ansible/plugins/vars/host_group_vars.py +7 -14
  488. ansible/release.py +2 -2
  489. ansible/template/__init__.py +353 -943
  490. ansible/utils/__init__.py +0 -18
  491. ansible/utils/collection_loader/__init__.py +54 -5
  492. ansible/utils/collection_loader/_collection_config.py +5 -6
  493. ansible/utils/collection_loader/_collection_finder.py +82 -96
  494. ansible/utils/collection_loader/_collection_meta.py +15 -8
  495. ansible/utils/display.py +485 -73
  496. ansible/utils/encrypt.py +27 -19
  497. ansible/utils/fqcn.py +2 -2
  498. ansible/utils/galaxy.py +2 -2
  499. ansible/utils/hashing.py +8 -10
  500. ansible/utils/helpers.py +2 -2
  501. ansible/utils/listify.py +10 -8
  502. ansible/utils/lock.py +2 -2
  503. ansible/utils/path.py +10 -12
  504. ansible/utils/plugin_docs.py +16 -14
  505. ansible/utils/py3compat.py +2 -7
  506. ansible/utils/sentinel.py +4 -62
  507. ansible/utils/singleton.py +2 -0
  508. ansible/utils/ssh_functions.py +6 -2
  509. ansible/utils/unsafe_proxy.py +23 -332
  510. ansible/utils/vars.py +55 -8
  511. ansible/utils/version.py +2 -2
  512. ansible/vars/clean.py +5 -5
  513. ansible/vars/hostvars.py +60 -90
  514. ansible/vars/manager.py +220 -285
  515. ansible/vars/plugins.py +4 -4
  516. ansible/vars/reserved.py +13 -12
  517. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
  518. ansible_core-2.19.0.dist-info/RECORD +1097 -0
  519. ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
  520. ansible_test/_data/completion/docker.txt +7 -7
  521. ansible_test/_data/completion/remote.txt +6 -6
  522. ansible_test/_data/completion/windows.txt +1 -0
  523. ansible_test/_data/requirements/ansible.txt +2 -2
  524. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  525. ansible_test/_data/requirements/sanity.changelog.txt +2 -2
  526. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  527. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  528. ansible_test/_data/requirements/sanity.pylint.txt +5 -5
  529. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  530. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  531. ansible_test/_data/requirements/units.txt +1 -0
  532. ansible_test/_internal/__init__.py +6 -0
  533. ansible_test/_internal/ansible_util.py +3 -1
  534. ansible_test/_internal/become.py +1 -0
  535. ansible_test/_internal/bootstrap.py +1 -0
  536. ansible_test/_internal/cache.py +1 -0
  537. ansible_test/_internal/cgroup.py +1 -0
  538. ansible_test/_internal/ci/__init__.py +1 -0
  539. ansible_test/_internal/ci/azp.py +1 -0
  540. ansible_test/_internal/ci/local.py +1 -0
  541. ansible_test/_internal/classification/__init__.py +1 -0
  542. ansible_test/_internal/classification/common.py +1 -0
  543. ansible_test/_internal/classification/csharp.py +1 -0
  544. ansible_test/_internal/classification/powershell.py +1 -0
  545. ansible_test/_internal/classification/python.py +1 -0
  546. ansible_test/_internal/cli/__init__.py +1 -0
  547. ansible_test/_internal/cli/actions.py +1 -0
  548. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  549. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  550. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  551. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  552. ansible_test/_internal/cli/commands/__init__.py +11 -5
  553. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  554. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  555. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  556. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  557. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  558. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  559. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  560. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  561. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  562. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  563. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  564. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  565. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  566. ansible_test/_internal/cli/commands/env.py +1 -0
  567. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  568. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  569. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  570. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  571. ansible_test/_internal/cli/commands/sanity.py +9 -0
  572. ansible_test/_internal/cli/commands/shell.py +1 -0
  573. ansible_test/_internal/cli/commands/units.py +1 -0
  574. ansible_test/_internal/cli/compat.py +1 -0
  575. ansible_test/_internal/cli/completers.py +1 -0
  576. ansible_test/_internal/cli/converters.py +1 -0
  577. ansible_test/_internal/cli/environments.py +52 -5
  578. ansible_test/_internal/cli/epilog.py +1 -0
  579. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  580. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  581. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  582. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  583. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  584. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  585. ansible_test/_internal/commands/__init__.py +1 -0
  586. ansible_test/_internal/commands/coverage/__init__.py +3 -2
  587. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  588. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  589. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  590. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  591. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  592. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  593. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  594. ansible_test/_internal/commands/coverage/combine.py +2 -1
  595. ansible_test/_internal/commands/coverage/erase.py +1 -0
  596. ansible_test/_internal/commands/coverage/html.py +1 -0
  597. ansible_test/_internal/commands/coverage/report.py +1 -0
  598. ansible_test/_internal/commands/coverage/xml.py +1 -0
  599. ansible_test/_internal/commands/env/__init__.py +2 -0
  600. ansible_test/_internal/commands/integration/__init__.py +22 -5
  601. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  602. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  603. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  604. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  605. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  606. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  607. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  608. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  609. ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
  610. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  611. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  612. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  613. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  614. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  615. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  616. ansible_test/_internal/commands/integration/coverage.py +8 -2
  617. ansible_test/_internal/commands/integration/filters.py +1 -0
  618. ansible_test/_internal/commands/integration/network.py +1 -0
  619. ansible_test/_internal/commands/integration/posix.py +1 -0
  620. ansible_test/_internal/commands/integration/windows.py +1 -0
  621. ansible_test/_internal/commands/sanity/__init__.py +19 -2
  622. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  623. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  624. ansible_test/_internal/commands/sanity/compile.py +1 -0
  625. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  626. ansible_test/_internal/commands/sanity/import.py +1 -0
  627. ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
  628. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  629. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  630. ansible_test/_internal/commands/sanity/pylint.py +25 -26
  631. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  632. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  633. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  634. ansible_test/_internal/commands/shell/__init__.py +44 -4
  635. ansible_test/_internal/commands/units/__init__.py +5 -1
  636. ansible_test/_internal/compat/__init__.py +1 -0
  637. ansible_test/_internal/compat/packaging.py +1 -0
  638. ansible_test/_internal/compat/yaml.py +1 -0
  639. ansible_test/_internal/completion.py +1 -0
  640. ansible_test/_internal/config.py +23 -13
  641. ansible_test/_internal/connections.py +1 -0
  642. ansible_test/_internal/constants.py +1 -0
  643. ansible_test/_internal/containers.py +1 -0
  644. ansible_test/_internal/content_config.py +1 -0
  645. ansible_test/_internal/core_ci.py +1 -0
  646. ansible_test/_internal/coverage_util.py +11 -10
  647. ansible_test/_internal/data.py +1 -0
  648. ansible_test/_internal/debugging.py +166 -0
  649. ansible_test/_internal/delegation.py +22 -13
  650. ansible_test/_internal/dev/__init__.py +1 -0
  651. ansible_test/_internal/dev/container_probe.py +1 -0
  652. ansible_test/_internal/diff.py +3 -2
  653. ansible_test/_internal/docker_util.py +2 -1
  654. ansible_test/_internal/encoding.py +1 -0
  655. ansible_test/_internal/executor.py +1 -0
  656. ansible_test/_internal/git.py +1 -0
  657. ansible_test/_internal/host_configs.py +1 -0
  658. ansible_test/_internal/host_profiles.py +260 -16
  659. ansible_test/_internal/http.py +1 -0
  660. ansible_test/_internal/init.py +1 -0
  661. ansible_test/_internal/inventory.py +39 -3
  662. ansible_test/_internal/io.py +1 -0
  663. ansible_test/_internal/metadata.py +95 -4
  664. ansible_test/_internal/payload.py +1 -0
  665. ansible_test/_internal/processes.py +80 -0
  666. ansible_test/_internal/provider/__init__.py +1 -0
  667. ansible_test/_internal/provider/layout/__init__.py +1 -0
  668. ansible_test/_internal/provider/layout/ansible.py +1 -0
  669. ansible_test/_internal/provider/layout/collection.py +1 -0
  670. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  671. ansible_test/_internal/provider/source/__init__.py +1 -0
  672. ansible_test/_internal/provider/source/git.py +1 -0
  673. ansible_test/_internal/provider/source/installed.py +1 -0
  674. ansible_test/_internal/provider/source/unsupported.py +1 -0
  675. ansible_test/_internal/provider/source/unversioned.py +1 -0
  676. ansible_test/_internal/provisioning.py +11 -4
  677. ansible_test/_internal/pypi_proxy.py +6 -5
  678. ansible_test/_internal/python_requirements.py +28 -0
  679. ansible_test/_internal/ssh.py +2 -5
  680. ansible_test/_internal/target.py +9 -0
  681. ansible_test/_internal/test.py +3 -2
  682. ansible_test/_internal/thread.py +3 -1
  683. ansible_test/_internal/timeout.py +2 -1
  684. ansible_test/_internal/util.py +41 -12
  685. ansible_test/_internal/util_common.py +18 -5
  686. ansible_test/_internal/venv.py +1 -0
  687. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  688. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  689. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  690. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  691. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  692. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  693. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  694. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  695. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  696. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  697. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  698. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  699. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  700. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  701. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  702. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  703. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  704. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
  705. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
  706. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
  707. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
  708. ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
  709. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
  710. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
  711. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  712. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  713. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  714. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  715. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  716. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  717. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  718. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  719. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  720. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  721. ansible_test/_util/target/injector/python.py +8 -0
  722. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  723. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  724. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  725. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  726. ansible_test/_util/target/sanity/import/importer.py +15 -16
  727. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  728. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  729. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  730. ansible_test/_util/target/setup/requirements.py +38 -36
  731. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  732. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  733. ansible/compat/selectors.py +0 -32
  734. ansible/errors/yaml_strings.py +0 -138
  735. ansible/executor/action_write_locks.py +0 -44
  736. ansible/executor/discovery/python_target.py +0 -47
  737. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  738. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  739. ansible/module_utils/compat/importlib.py +0 -26
  740. ansible/module_utils/compat/selectors.py +0 -32
  741. ansible/module_utils/pycompat24.py +0 -73
  742. ansible/parsing/yaml/constructor.py +0 -178
  743. ansible/template/native_helpers.py +0 -251
  744. ansible/template/template.py +0 -43
  745. ansible/template/vars.py +0 -77
  746. ansible/utils/native_jinja.py +0 -11
  747. ansible/vars/fact_cache.py +0 -71
  748. ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
  749. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
  750. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
  751. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
  752. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
  753. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  754. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  755. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  756. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  757. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
@@ -4,78 +4,148 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- from ansible import constants as C
8
- from ansible.parsing.dataloader import DataLoader
7
+ import collections.abc as _c
8
+ import dataclasses
9
+ import functools
10
+ import typing as t
11
+
12
+ from ansible import constants
13
+ from ansible.utils import vars as _vars
9
14
  from ansible.vars.clean import module_response_deepcopy, strip_internal_keys
15
+ from ansible.module_utils._internal import _messages
16
+ from ansible._internal import _collection_proxy
17
+
18
+ if t.TYPE_CHECKING:
19
+ from ansible.inventory.host import Host
20
+ from ansible.playbook.task import Task
10
21
 
11
22
  _IGNORE = ('failed', 'skipped')
12
- _PRESERVE = ('attempts', 'changed', 'retries')
13
- _SUB_PRESERVE = {'_ansible_delegated_vars': ('ansible_host', 'ansible_port', 'ansible_user', 'ansible_connection')}
23
+ _PRESERVE = {'attempts', 'changed', 'retries', '_ansible_no_log', 'exception', 'warnings', 'deprecations'}
24
+ _SUB_PRESERVE = {'_ansible_delegated_vars': {'ansible_host', 'ansible_port', 'ansible_user', 'ansible_connection'}}
14
25
 
15
26
  # stuff callbacks need
16
27
  CLEAN_EXCEPTIONS = (
17
28
  '_ansible_verbose_always', # for debug and other actions, to always expand data (pretty jsonification)
18
29
  '_ansible_item_label', # to know actual 'item' variable
19
- '_ansible_no_log', # jic we didnt clean up well enough, DON'T LOG
30
+ '_ansible_no_log', # jic we didn't clean up well enough, DON'T LOG
20
31
  '_ansible_verbose_override', # controls display of ansible_facts, gathering would be very noise with -v otherwise
21
32
  )
22
33
 
23
34
 
24
- class TaskResult:
25
- '''
35
+ @t.final
36
+ @dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
37
+ class _WireTaskResult:
38
+ """A thin version of `_RawTaskResult` which can be sent over the worker queue."""
39
+
40
+ host_name: str
41
+ task_uuid: str
42
+ return_data: _c.MutableMapping[str, object]
43
+ task_fields: _c.Mapping[str, object]
44
+
45
+
46
+ class _BaseTaskResult:
47
+ """
26
48
  This class is responsible for interpreting the resulting data
27
49
  from an executed task, and provides helper methods for determining
28
50
  the result of a given task.
29
- '''
51
+ """
30
52
 
31
- def __init__(self, host, task, return_data, task_fields=None):
32
- self._host = host
33
- self._task = task
53
+ def __init__(self, host: Host, task: Task, return_data: _c.MutableMapping[str, t.Any], task_fields: _c.Mapping[str, t.Any]) -> None:
54
+ self.__host = host
55
+ self.__task = task
56
+ self._return_data = return_data # FIXME: this should be immutable, but strategy result processing mutates it in some corner cases
57
+ self.__task_fields = task_fields
34
58
 
35
- if isinstance(return_data, dict):
36
- self._result = return_data.copy()
37
- else:
38
- self._result = DataLoader().load(return_data)
59
+ @property
60
+ def host(self) -> Host:
61
+ """The host associated with this result."""
62
+ return self.__host
39
63
 
40
- if task_fields is None:
41
- self._task_fields = dict()
42
- else:
43
- self._task_fields = task_fields
64
+ @property
65
+ def _host(self) -> Host:
66
+ """Use the `host` property when supporting only ansible-core 2.19 or later."""
67
+ # deprecated: description='Deprecate `_host` in favor of `host`' core_version='2.23'
68
+ return self.__host
69
+
70
+ @property
71
+ def task(self) -> Task:
72
+ """The task associated with this result."""
73
+ return self.__task
74
+
75
+ @property
76
+ def _task(self) -> Task:
77
+ """Use the `task` property when supporting only ansible-core 2.19 or later."""
78
+ # deprecated: description='Deprecate `_task` in favor of `task`' core_version='2.23'
79
+ return self.__task
80
+
81
+ @property
82
+ def task_fields(self) -> _c.Mapping[str, t.Any]:
83
+ """The task fields associated with this result."""
84
+ return self.__task_fields
85
+
86
+ @property
87
+ def _task_fields(self) -> _c.Mapping[str, t.Any]:
88
+ """Use the `task_fields` property when supporting only ansible-core 2.19 or later."""
89
+ # deprecated: description='Deprecate `_task_fields` in favor of `task`' core_version='2.23'
90
+ return self.__task_fields
91
+
92
+ @property
93
+ def exception(self) -> _messages.ErrorSummary | None:
94
+ """The error from this task result, if any."""
95
+ return self._return_data.get('exception')
96
+
97
+ @property
98
+ def warnings(self) -> _c.Sequence[_messages.WarningSummary]:
99
+ """The warnings for this task, if any."""
100
+ return _collection_proxy.SequenceProxy(self._return_data.get('warnings') or [])
44
101
 
45
102
  @property
46
- def task_name(self):
47
- return self._task_fields.get('name', None) or self._task.get_name()
103
+ def deprecations(self) -> _c.Sequence[_messages.DeprecationSummary]:
104
+ """The deprecation warnings for this task, if any."""
105
+ return _collection_proxy.SequenceProxy(self._return_data.get('deprecations') or [])
106
+
107
+ @property
108
+ def _loop_results(self) -> list[_c.MutableMapping[str, t.Any]]:
109
+ """Return a list of loop results. If no loop results are present, an empty list is returned."""
110
+ results = self._return_data.get('results')
111
+
112
+ if not isinstance(results, list):
113
+ return []
48
114
 
49
- def is_changed(self):
115
+ return results
116
+
117
+ @property
118
+ def task_name(self) -> str:
119
+ return str(self.task_fields.get('name', '')) or self.task.get_name()
120
+
121
+ def is_changed(self) -> bool:
50
122
  return self._check_key('changed')
51
123
 
52
- def is_skipped(self):
53
- # loop results
54
- if 'results' in self._result:
55
- results = self._result['results']
124
+ def is_skipped(self) -> bool:
125
+ if self._loop_results:
56
126
  # Loop tasks are only considered skipped if all items were skipped.
57
127
  # some squashed results (eg, dnf) are not dicts and can't be skipped individually
58
- if results and all(isinstance(res, dict) and res.get('skipped', False) for res in results):
128
+ if all(isinstance(loop_res, dict) and loop_res.get('skipped', False) for loop_res in self._loop_results):
59
129
  return True
60
130
 
61
131
  # regular tasks and squashed non-dict results
62
- return self._result.get('skipped', False)
132
+ return bool(self._return_data.get('skipped', False))
63
133
 
64
- def is_failed(self):
65
- if 'failed_when_result' in self._result or \
66
- 'results' in self._result and True in [True for x in self._result['results'] if 'failed_when_result' in x]:
134
+ def is_failed(self) -> bool:
135
+ if 'failed_when_result' in self._return_data or any(isinstance(loop_res, dict) and 'failed_when_result' in loop_res for loop_res in self._loop_results):
67
136
  return self._check_key('failed_when_result')
68
- else:
69
- return self._check_key('failed')
70
137
 
71
- def is_unreachable(self):
138
+ return self._check_key('failed')
139
+
140
+ def is_unreachable(self) -> bool:
72
141
  return self._check_key('unreachable')
73
142
 
74
- def needs_debugger(self, globally_enabled=False):
75
- _debugger = self._task_fields.get('debugger')
76
- _ignore_errors = C.TASK_DEBUGGER_IGNORE_ERRORS and self._task_fields.get('ignore_errors')
143
+ def needs_debugger(self, globally_enabled: bool = False) -> bool:
144
+ _debugger = self.task_fields.get('debugger')
145
+ _ignore_errors = constants.TASK_DEBUGGER_IGNORE_ERRORS and self.task_fields.get('ignore_errors')
77
146
 
78
147
  ret = False
148
+
79
149
  if globally_enabled and ((self.is_failed() and not _ignore_errors) or self.is_unreachable()):
80
150
  ret = True
81
151
 
@@ -92,62 +162,95 @@ class TaskResult:
92
162
 
93
163
  return ret
94
164
 
95
- def _check_key(self, key):
96
- '''get a specific key from the result or its items'''
165
+ def _check_key(self, key: str) -> bool:
166
+ """Fetch a specific named boolean value from the result; if missing, a logical OR of the value from nested loop results; False for non-loop results."""
167
+ if (value := self._return_data.get(key, ...)) is not ...:
168
+ return bool(value)
97
169
 
98
- if isinstance(self._result, dict) and key in self._result:
99
- return self._result.get(key, False)
100
- else:
101
- flag = False
102
- for res in self._result.get('results', []):
103
- if isinstance(res, dict):
104
- flag |= res.get(key, False)
105
- return flag
170
+ return any(isinstance(result, dict) and result.get(key) for result in self._loop_results)
106
171
 
107
- def clean_copy(self):
108
172
 
109
- ''' returns 'clean' taskresult object '''
173
+ @t.final
174
+ class _RawTaskResult(_BaseTaskResult):
175
+ def as_wire_task_result(self) -> _WireTaskResult:
176
+ """Return a `_WireTaskResult` from this instance."""
177
+ return _WireTaskResult(
178
+ host_name=self.host.name,
179
+ task_uuid=self.task._uuid,
180
+ return_data=self._return_data,
181
+ task_fields=self.task_fields,
182
+ )
110
183
 
111
- # FIXME: clean task_fields, _task and _host copies
112
- result = TaskResult(self._host, self._task, {}, self._task_fields)
184
+ def as_callback_task_result(self) -> CallbackTaskResult:
185
+ """Return a `CallbackTaskResult` from this instance."""
186
+ ignore: tuple[str, ...]
113
187
 
114
188
  # statuses are already reflected on the event type
115
- if result._task and result._task.action in C._ACTION_DEBUG:
189
+ if self.task and self.task.action in constants._ACTION_DEBUG:
116
190
  # debug is verbose by default to display vars, no need to add invocation
117
191
  ignore = _IGNORE + ('invocation',)
118
192
  else:
119
193
  ignore = _IGNORE
120
194
 
121
- subset = {}
195
+ subset: dict[str, dict[str, object]] = {}
196
+
122
197
  # preserve subset for later
123
- for sub in _SUB_PRESERVE:
124
- if sub in self._result:
125
- subset[sub] = {}
126
- for key in _SUB_PRESERVE[sub]:
127
- if key in self._result[sub]:
128
- subset[sub][key] = self._result[sub][key]
129
-
130
- if isinstance(self._task.no_log, bool) and self._task.no_log or self._result.get('_ansible_no_log', False):
131
- x = {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}
132
-
133
- # preserve full
134
- for preserve in _PRESERVE:
135
- if preserve in self._result:
136
- x[preserve] = self._result[preserve]
137
-
138
- result._result = x
139
- elif self._result:
140
- result._result = module_response_deepcopy(self._result)
141
-
142
- # actually remove
143
- for remove_key in ignore:
144
- if remove_key in result._result:
145
- del result._result[remove_key]
198
+ for sub, sub_keys in _SUB_PRESERVE.items():
199
+ sub_data = self._return_data.get(sub)
200
+
201
+ if isinstance(sub_data, dict):
202
+ subset[sub] = {key: value for key, value in sub_data.items() if key in sub_keys}
203
+
204
+ # DTFIX-FUTURE: is checking no_log here redundant now that we use _ansible_no_log everywhere?
205
+ if isinstance(self.task.no_log, bool) and self.task.no_log or self._return_data.get('_ansible_no_log'):
206
+ censored_result = censor_result(self._return_data)
207
+
208
+ if self._loop_results:
209
+ # maintain shape for loop results so callback behavior recognizes a loop was performed
210
+ censored_result.update(results=[
211
+ censor_result(loop_res) if isinstance(loop_res, dict) and loop_res.get('_ansible_no_log') else loop_res for loop_res in self._loop_results
212
+ ])
213
+
214
+ return_data = censored_result
215
+ elif self._return_data:
216
+ return_data = {k: v for k, v in module_response_deepcopy(self._return_data).items() if k not in ignore}
146
217
 
147
218
  # remove almost ALL internal keys, keep ones relevant to callback
148
- strip_internal_keys(result._result, exceptions=CLEAN_EXCEPTIONS)
219
+ strip_internal_keys(return_data, exceptions=CLEAN_EXCEPTIONS)
220
+ else:
221
+ return_data = {}
149
222
 
150
223
  # keep subset
151
- result._result.update(subset)
224
+ return_data.update(subset)
225
+
226
+ return CallbackTaskResult(self.host, self.task, return_data, self.task_fields)
227
+
228
+
229
+ @t.final
230
+ class CallbackTaskResult(_BaseTaskResult):
231
+ """Public contract of TaskResult """
232
+
233
+ @property
234
+ def _result(self) -> _c.MutableMapping[str, t.Any]:
235
+ """Use the `result` property when supporting only ansible-core 2.19 or later."""
236
+ # deprecated: description='Deprecate `_result` in favor of `result`' core_version='2.23'
237
+ return self.result
238
+
239
+ @functools.cached_property
240
+ def result(self) -> _c.MutableMapping[str, t.Any]:
241
+ """
242
+ Returns a cached copy of the task result dictionary for consumption by callbacks.
243
+ Internal custom types are transformed to native Python types to facilitate access and serialization.
244
+ """
245
+ return t.cast(_c.MutableMapping[str, t.Any], _vars.transform_to_native_types(self._return_data))
246
+
247
+
248
+ TaskResult = CallbackTaskResult
249
+ """Compatibility name for the pre-2.19 callback-shaped TaskResult passed to callbacks."""
250
+
251
+
252
+ def censor_result(result: _c.Mapping[str, t.Any]) -> dict[str, t.Any]:
253
+ censored_result = {key: value for key in _PRESERVE if (value := result.get(key, ...)) is not ...}
254
+ censored_result.update(censored="the output has been hidden due to the fact that 'no_log: true' was specified for this result")
152
255
 
153
- return result
256
+ return censored_result
@@ -18,7 +18,7 @@
18
18
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
19
19
  #
20
20
  ########################################################################
21
- ''' This manages remote shared Ansible objects, mainly roles'''
21
+ """ This manages remote shared Ansible objects, mainly roles"""
22
22
 
23
23
  from __future__ import annotations
24
24
 
@@ -40,7 +40,7 @@ def get_collections_galaxy_meta_info():
40
40
 
41
41
 
42
42
  class Galaxy(object):
43
- ''' Keeps global galaxy info '''
43
+ """ Keeps global galaxy info """
44
44
 
45
45
  def __init__(self):
46
46
  # TODO: eventually remove this as it contains a mismash of properties that aren't really global
ansible/galaxy/api.py CHANGED
@@ -57,13 +57,13 @@ def should_retry_error(exception):
57
57
  if isinstance(exception, GalaxyError) and exception.http_code in RETRY_HTTP_ERROR_CODES:
58
58
  return True
59
59
 
60
- if isinstance(exception, AnsibleError) and (orig_exc := getattr(exception, 'orig_exc', None)):
60
+ if isinstance(exception, AnsibleError) and (cause := exception.__cause__):
61
61
  # URLError is often a proxy for an underlying error, handle wrapped exceptions
62
- if isinstance(orig_exc, URLError):
63
- orig_exc = orig_exc.reason
62
+ if isinstance(cause, URLError):
63
+ cause = cause.reason
64
64
 
65
65
  # Handle common URL related errors
66
- if isinstance(orig_exc, (TimeoutError, BadStatusLine, IncompleteRead)):
66
+ if isinstance(cause, (TimeoutError, BadStatusLine, IncompleteRead)):
67
67
  return True
68
68
 
69
69
  return False
@@ -92,7 +92,7 @@ def g_connect(versions):
92
92
  try:
93
93
  data = self._call_galaxy(n_url, method='GET', error_context_msg=error_context_msg, cache=True)
94
94
  except (AnsibleError, GalaxyError, ValueError, KeyError) as err:
95
- # Either the URL doesnt exist, or other error. Or the URL exists, but isn't a galaxy API
95
+ # Either the URL doesn't exist, or other error. Or the URL exists, but isn't a galaxy API
96
96
  # root (not JSON, no 'available_versions') so try appending '/api/'
97
97
  if n_url.endswith('/api') or n_url.endswith('/api/'):
98
98
  raise
@@ -138,7 +138,7 @@ def g_connect(versions):
138
138
  'The v2 Ansible Galaxy API is deprecated and no longer supported. '
139
139
  'Ensure that you have configured the ansible-galaxy CLI to utilize an '
140
140
  'updated and supported version of Ansible Galaxy.',
141
- version='2.20'
141
+ version='2.20',
142
142
  )
143
143
 
144
144
  return method(self, *args, **kwargs)
@@ -337,10 +337,7 @@ class GalaxyAPI:
337
337
  if not isinstance(other_galaxy_api, self.__class__):
338
338
  return NotImplemented
339
339
 
340
- return (
341
- self._priority > other_galaxy_api._priority or
342
- self.name < self.name
343
- )
340
+ return self._priority > other_galaxy_api._priority
344
341
 
345
342
  @property # type: ignore[misc] # https://github.com/python/mypy/issues/1362
346
343
  @g_connect(['v1', 'v2', 'v3'])
@@ -408,11 +405,8 @@ class GalaxyAPI:
408
405
  method=method, timeout=self._server_timeout, http_agent=user_agent(), follow_redirects='safe')
409
406
  except HTTPError as e:
410
407
  raise GalaxyError(e, error_context_msg)
411
- except Exception as e:
412
- raise AnsibleError(
413
- "Unknown error when attempting to call Galaxy at '%s': %s" % (url, to_native(e)),
414
- orig_exc=e
415
- )
408
+ except Exception as ex:
409
+ raise AnsibleError(f"Unknown error when attempting to call Galaxy at {url!r}.") from ex
416
410
 
417
411
  resp_data = to_text(resp.read(), errors='surrogate_or_strict')
418
412
  try:
@@ -471,8 +465,8 @@ class GalaxyAPI:
471
465
  resp = open_url(url, data=args, validate_certs=self.validate_certs, method="POST", http_agent=user_agent(), timeout=self._server_timeout)
472
466
  except HTTPError as e:
473
467
  raise GalaxyError(e, 'Attempting to authenticate to galaxy')
474
- except Exception as e:
475
- raise AnsibleError('Unable to authenticate to galaxy: %s' % to_native(e), orig_exc=e)
468
+ except Exception as ex:
469
+ raise AnsibleError('Unable to authenticate to galaxy.') from ex
476
470
 
477
471
  data = json.loads(to_text(resp.read(), errors='surrogate_or_strict'))
478
472
  return data
@@ -817,8 +811,17 @@ class GalaxyAPI:
817
811
 
818
812
  signatures = data.get('signatures') or []
819
813
 
814
+ download_url_info = urlparse(data['download_url'])
815
+ if not download_url_info.scheme and not download_url_info.path.startswith('/'):
816
+ # galaxy does a lot of redirects, with much more complex pathing than we use
817
+ # within this codebase, without updating _call_galaxy to be able to return
818
+ # the final URL, we can't reliably build a relative URL.
819
+ raise AnsibleError(f'Invalid non absolute download_url: {data["download_url"]}')
820
+
821
+ download_url = urljoin(self.api_server, data['download_url'])
822
+
820
823
  return CollectionVersionMetadata(data['namespace']['name'], data['collection']['name'], data['version'],
821
- data['download_url'], data['artifact']['sha256'],
824
+ download_url, data['artifact']['sha256'],
822
825
  data['metadata']['dependencies'], data['href'], signatures)
823
826
 
824
827
  @g_connect(['v2', 'v3'])
@@ -874,7 +877,7 @@ class GalaxyAPI:
874
877
  except GalaxyError as err:
875
878
  if err.http_code != 404:
876
879
  raise
877
- # v3 doesn't raise a 404 so we need to mimick the empty response from APIs that do.
880
+ # v3 doesn't raise a 404 so we need to mimic the empty response from APIs that do.
878
881
  return []
879
882
 
880
883
  if 'data' in data:
@@ -896,12 +899,10 @@ class GalaxyAPI:
896
899
  if not next_link:
897
900
  break
898
901
  elif relative_link:
899
- # TODO: This assumes the pagination result is relative to the root server. Will need to be verified
900
- # with someone who knows the AH API.
901
-
902
- # Remove the query string from the versions_url to use the next_link's query
903
- versions_url = urljoin(versions_url, urlparse(versions_url).path)
904
- next_link = versions_url.replace(versions_url_info.path, next_link)
902
+ next_link_info = urlparse(next_link)
903
+ if not next_link_info.scheme and not next_link_info.path.startswith('/'):
904
+ raise AnsibleError(f'Invalid non absolute pagination link: {next_link}')
905
+ next_link = urljoin(self.api_server, next_link)
905
906
 
906
907
  data = self._call_galaxy(to_native(next_link, errors='surrogate_or_strict'),
907
908
  error_context_msg=error_context_msg, cache=True, cache_key=cache_key)
@@ -5,7 +5,6 @@
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
- import errno
9
8
  import fnmatch
10
9
  import functools
11
10
  import glob
@@ -31,6 +30,7 @@ from dataclasses import dataclass
31
30
  from hashlib import sha256
32
31
  from io import BytesIO
33
32
  from importlib.metadata import distribution
33
+ from importlib.resources import files
34
34
  from itertools import chain
35
35
 
36
36
  try:
@@ -85,7 +85,6 @@ if t.TYPE_CHECKING:
85
85
  FilesManifestType = t.Dict[t.Literal['files', 'format'], t.Union[t.List[FileManifestEntryType], int]]
86
86
 
87
87
  import ansible.constants as C
88
- from ansible.compat.importlib_resources import files
89
88
  from ansible.errors import AnsibleError
90
89
  from ansible.galaxy.api import GalaxyAPI
91
90
  from ansible.galaxy.collection.concrete_artifact_manager import (
@@ -126,13 +125,13 @@ from ansible.galaxy.dependency_resolution.dataclasses import (
126
125
  from ansible.galaxy.dependency_resolution.versioning import meets_requirements
127
126
  from ansible.plugins.loader import get_all_plugin_loaders
128
127
  from ansible.module_utils.common.file import S_IRWU_RG_RO, S_IRWXU_RXG_RXO, S_IXANY
128
+ from ansible.module_utils.common.sentinel import Sentinel
129
129
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
130
130
  from ansible.module_utils.common.collections import is_sequence
131
131
  from ansible.module_utils.common.yaml import yaml_dump
132
132
  from ansible.utils.collection_loader import AnsibleCollectionRef
133
133
  from ansible.utils.display import Display
134
134
  from ansible.utils.hashing import secure_hash, secure_hash_s
135
- from ansible.utils.sentinel import Sentinel
136
135
 
137
136
 
138
137
  display = Display()
@@ -201,9 +200,9 @@ class CollectionSignatureError(Exception):
201
200
 
202
201
  # FUTURE: expose actual verify result details for a collection on this object, maybe reimplement as dataclass on py3.8+
203
202
  class CollectionVerifyResult:
204
- def __init__(self, collection_name): # type: (str) -> None
205
- self.collection_name = collection_name # type: str
206
- self.success = True # type: bool
203
+ def __init__(self, collection_name: str) -> None:
204
+ self.collection_name = collection_name
205
+ self.success = True
207
206
 
208
207
 
209
208
  def verify_local_collection(local_collection, remote_collection, artifacts_manager):
@@ -1433,9 +1432,6 @@ def find_existing_collections(path_filter, artifacts_manager, namespace_filter=N
1433
1432
  :param path: Collection dirs layout search path.
1434
1433
  :param artifacts_manager: Artifacts manager.
1435
1434
  """
1436
- if files is None:
1437
- raise AnsibleError('importlib_resources is not installed and is required')
1438
-
1439
1435
  if path_filter and not is_sequence(path_filter):
1440
1436
  path_filter = [path_filter]
1441
1437
  if namespace_filter and not is_sequence(namespace_filter):
@@ -1692,11 +1688,7 @@ def _extract_tar_dir(tar, dirname, b_dest):
1692
1688
  b_dir_path = os.path.join(b_dest, to_bytes(dirname, errors='surrogate_or_strict'))
1693
1689
 
1694
1690
  b_parent_path = os.path.dirname(b_dir_path)
1695
- try:
1696
- os.makedirs(b_parent_path, mode=S_IRWXU_RXG_RXO)
1697
- except OSError as e:
1698
- if e.errno != errno.EEXIST:
1699
- raise
1691
+ os.makedirs(b_parent_path, mode=S_IRWXU_RXG_RXO, exist_ok=True)
1700
1692
 
1701
1693
  if tar_member.type == tarfile.SYMTYPE:
1702
1694
  b_link_path = to_bytes(tar_member.linkname, errors='surrogate_or_strict')
@@ -35,10 +35,10 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_
35
35
  from ansible.module_utils.api import retry_with_delays_and_condition
36
36
  from ansible.module_utils.api import generate_jittered_backoff
37
37
  from ansible.module_utils.common.process import get_bin_path
38
+ from ansible.module_utils.common.sentinel import Sentinel
38
39
  from ansible.module_utils.common.yaml import yaml_load
39
40
  from ansible.module_utils.urls import open_url
40
41
  from ansible.utils.display import Display
41
- from ansible.utils.sentinel import Sentinel
42
42
 
43
43
  import ansible.constants as C
44
44
 
@@ -449,9 +449,9 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
449
449
  except subprocess.CalledProcessError as proc_err:
450
450
  raise AnsibleError( # should probably be LookupError
451
451
  'Failed to switch a cloned Git repo `{repo_url!s}` '
452
- 'to the requested revision `{commitish!s}`.'.
452
+ 'to the requested revision `{revision!s}`.'.
453
453
  format(
454
- commitish=to_native(version),
454
+ revision=to_native(version),
455
455
  repo_url=to_native(git_url),
456
456
  ),
457
457
  ) from proc_err
@@ -485,16 +485,13 @@ def _download_file(url, b_path, expected_hash, validate_certs, token=None, timeo
485
485
  display.display("Downloading %s to %s" % (url, to_text(b_tarball_dir)))
486
486
  # NOTE: Galaxy redirects downloads to S3 which rejects the request
487
487
  # NOTE: if an Authorization header is attached so don't redirect it
488
- try:
489
- resp = open_url(
490
- to_native(url, errors='surrogate_or_strict'),
491
- validate_certs=validate_certs,
492
- headers=None if token is None else token.headers(),
493
- unredirected_headers=['Authorization'], http_agent=user_agent(),
494
- timeout=timeout
495
- )
496
- except Exception as err:
497
- raise AnsibleError(to_native(err), orig_exc=err)
488
+ resp = open_url(
489
+ to_native(url, errors='surrogate_or_strict'),
490
+ validate_certs=validate_certs,
491
+ headers=None if token is None else token.headers(),
492
+ unredirected_headers=['Authorization'], http_agent=user_agent(),
493
+ timeout=timeout
494
+ )
498
495
 
499
496
  with open(b_file_path, 'wb') as download_file: # type: t.BinaryIO
500
497
  actual_hash = _consume_file(resp, write_to=download_file)
@@ -659,14 +656,8 @@ def _get_json_from_installed_dir(
659
656
  try:
660
657
  with open(b_json_filepath, 'rb') as manifest_fd:
661
658
  b_json_text = manifest_fd.read()
662
- except (IOError, OSError):
663
- raise LookupError(
664
- "The collection {manifest!s} path '{path!s}' does not exist.".
665
- format(
666
- manifest=filename,
667
- path=to_native(b_json_filepath),
668
- )
669
- )
659
+ except OSError as ex:
660
+ raise LookupError(f"The collection {filename!r} path {to_text(b_json_filepath)!r} does not exist.") from ex
670
661
 
671
662
  manifest_txt = to_text(b_json_text, errors='surrogate_or_strict')
672
663
 
@@ -7,6 +7,7 @@
7
7
  from __future__ import annotations
8
8
 
9
9
  import os
10
+ import pathlib
10
11
  import typing as t
11
12
 
12
13
  from collections import namedtuple
@@ -25,6 +26,8 @@ if t.TYPE_CHECKING:
25
26
  '_ComputedReqKindsMixin',
26
27
  )
27
28
 
29
+ import ansible
30
+ import ansible.release
28
31
 
29
32
  from ansible.errors import AnsibleError, AnsibleAssertionError
30
33
  from ansible.galaxy.api import GalaxyAPI
@@ -39,6 +42,7 @@ _ALLOW_CONCRETE_POINTER_IN_SOURCE = False # NOTE: This is a feature flag
39
42
  _GALAXY_YAML = b'galaxy.yml'
40
43
  _MANIFEST_JSON = b'MANIFEST.json'
41
44
  _SOURCE_METADATA_FILE = b'GALAXY.yml'
45
+ _ANSIBLE_PACKAGE_PATH = pathlib.Path(ansible.__file__).parent
42
46
 
43
47
  display = Display()
44
48
 
@@ -224,6 +228,13 @@ class _ComputedReqKindsMixin:
224
228
  if dir_path.endswith(to_bytes(os.path.sep)):
225
229
  dir_path = dir_path.rstrip(to_bytes(os.path.sep))
226
230
  if not _is_collection_dir(dir_path):
231
+ dir_pathlib = pathlib.Path(to_text(dir_path))
232
+
233
+ # special handling for bundled collections without manifests, e.g., ansible._protomatter
234
+ if dir_pathlib.is_relative_to(_ANSIBLE_PACKAGE_PATH):
235
+ req_name = f'{dir_pathlib.parent.name}.{dir_pathlib.name}'
236
+ return cls(req_name, ansible.release.__version__, dir_path, 'dir', None)
237
+
227
238
  display.warning(
228
239
  u"Collection at '{path!s}' does not have a {manifest_json!s} "
229
240
  u'file, nor has it {galaxy_yml!s}: cannot detect version.'.
@@ -578,10 +589,9 @@ class _ComputedReqKindsMixin:
578
589
 
579
590
  See https://github.com/ansible/ansible/pull/81606 for extra context.
580
591
  """
581
- version_string = self.ver[0]
582
- return version_string.isdigit() or not (
583
- version_string == '*' or
584
- version_string.startswith(('<', '>', '!='))
592
+ version_spec_start_char = self.ver[0]
593
+ return version_spec_start_char.isdigit() or not (
594
+ version_spec_start_char.startswith(('<', '>', '!', '*'))
585
595
  )
586
596
 
587
597
  @property