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
@@ -16,6 +16,8 @@
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
  from __future__ import annotations
18
18
 
19
+ import typing as t
20
+
19
21
  from collections.abc import Mapping, MutableMapping
20
22
  from enum import Enum
21
23
  from itertools import chain
@@ -24,10 +26,15 @@ from ansible import constants as C
24
26
  from ansible.errors import AnsibleError
25
27
  from ansible.module_utils.common.text.converters import to_native, to_text
26
28
  from ansible.utils.display import Display
27
- from ansible.utils.vars import combine_vars
29
+ from ansible.utils.vars import combine_vars, validate_variable_name
30
+
31
+ from . import helpers # this is left as a module import to facilitate easier unit test patching
28
32
 
29
33
  display = Display()
30
34
 
35
+ if t.TYPE_CHECKING:
36
+ from .host import Host
37
+
31
38
 
32
39
  def to_safe_group_name(name, replacer="_", force=False, silent=False):
33
40
  # Converts 'bad' characters in a string to underscores (or provided replacer) so they can be used as Ansible hosts or groups
@@ -59,22 +66,23 @@ class InventoryObjectType(Enum):
59
66
 
60
67
 
61
68
  class Group:
62
- ''' a group of ansible hosts '''
69
+ """A group of ansible hosts."""
63
70
  base_type = InventoryObjectType.GROUP
64
71
 
65
72
  # __slots__ = [ 'name', 'hosts', 'vars', 'child_groups', 'parent_groups', 'depth', '_hosts_cache' ]
66
73
 
67
- def __init__(self, name=None):
74
+ def __init__(self, name: str) -> None:
75
+ name = helpers.remove_trust(name)
68
76
 
69
- self.depth = 0
70
- self.name = to_safe_group_name(name)
71
- self.hosts = []
72
- self._hosts = None
73
- self.vars = {}
74
- self.child_groups = []
75
- self.parent_groups = []
76
- self._hosts_cache = None
77
- self.priority = 1
77
+ self.depth: int = 0
78
+ self.name: str = to_safe_group_name(name)
79
+ self.hosts: list[Host] = []
80
+ self._hosts: set[str] | None = None
81
+ self.vars: dict[str, t.Any] = {}
82
+ self.child_groups: list[Group] = []
83
+ self.parent_groups: list[Group] = []
84
+ self._hosts_cache: list[Host] | None = None
85
+ self.priority: int = 1
78
86
 
79
87
  def __repr__(self):
80
88
  return self.get_name()
@@ -82,45 +90,8 @@ class Group:
82
90
  def __str__(self):
83
91
  return self.get_name()
84
92
 
85
- def __getstate__(self):
86
- return self.serialize()
87
-
88
- def __setstate__(self, data):
89
- return self.deserialize(data)
90
-
91
- def serialize(self):
92
- parent_groups = []
93
- for parent in self.parent_groups:
94
- parent_groups.append(parent.serialize())
95
-
96
- self._hosts = None
97
-
98
- result = dict(
99
- name=self.name,
100
- vars=self.vars.copy(),
101
- parent_groups=parent_groups,
102
- depth=self.depth,
103
- hosts=self.hosts,
104
- )
105
-
106
- return result
107
-
108
- def deserialize(self, data):
109
- self.__init__() # used by __setstate__ to deserialize in place # pylint: disable=unnecessary-dunder-call
110
- self.name = data.get('name')
111
- self.vars = data.get('vars', dict())
112
- self.depth = data.get('depth', 0)
113
- self.hosts = data.get('hosts', [])
114
- self._hosts = None
115
-
116
- parent_groups = data.get('parent_groups', [])
117
- for parent_data in parent_groups:
118
- g = Group()
119
- g.deserialize(parent_data)
120
- self.parent_groups.append(g)
121
-
122
- def _walk_relationship(self, rel, include_self=False, preserve_ordering=False):
123
- '''
93
+ def _walk_relationship(self, rel, include_self=False, preserve_ordering=False) -> set[Group] | list[Group]:
94
+ """
124
95
  Given `rel` that is an iterable property of Group,
125
96
  consitituting a directed acyclic graph among all groups,
126
97
  Returns a set of all groups in full tree
@@ -132,13 +103,13 @@ class Group:
132
103
  | / are directed upward
133
104
  F
134
105
  Called on F, returns set of (A, B, C, D, E)
135
- '''
136
- seen = set([])
106
+ """
107
+ seen: set[Group] = set([])
137
108
  unprocessed = set(getattr(self, rel))
138
109
  if include_self:
139
110
  unprocessed.add(self)
140
111
  if preserve_ordering:
141
- ordered = [self] if include_self else []
112
+ ordered: list[Group] = [self] if include_self else []
142
113
  ordered.extend(getattr(self, rel))
143
114
 
144
115
  while unprocessed:
@@ -158,22 +129,22 @@ class Group:
158
129
  return ordered
159
130
  return seen
160
131
 
161
- def get_ancestors(self):
162
- return self._walk_relationship('parent_groups')
132
+ def get_ancestors(self) -> set[Group]:
133
+ return t.cast(set, self._walk_relationship('parent_groups'))
163
134
 
164
- def get_descendants(self, **kwargs):
135
+ def get_descendants(self, **kwargs) -> set[Group] | list[Group]:
165
136
  return self._walk_relationship('child_groups', **kwargs)
166
137
 
167
138
  @property
168
- def host_names(self):
139
+ def host_names(self) -> set[str]:
169
140
  if self._hosts is None:
170
- self._hosts = set(self.hosts)
141
+ self._hosts = {h.name for h in self.hosts}
171
142
  return self._hosts
172
143
 
173
- def get_name(self):
144
+ def get_name(self) -> str:
174
145
  return self.name
175
146
 
176
- def add_child_group(self, group):
147
+ def add_child_group(self, group: Group) -> bool:
177
148
  added = False
178
149
  if self == group:
179
150
  raise Exception("can't add group to itself")
@@ -208,7 +179,7 @@ class Group:
208
179
  self.clear_hosts_cache()
209
180
  return added
210
181
 
211
- def _check_children_depth(self):
182
+ def _check_children_depth(self) -> None:
212
183
 
213
184
  depth = self.depth
214
185
  start_depth = self.depth # self.depth could change over loop
@@ -227,7 +198,7 @@ class Group:
227
198
  if depth - start_depth > len(seen):
228
199
  raise AnsibleError("The group named '%s' has a recursive dependency loop." % to_native(self.name))
229
200
 
230
- def add_host(self, host):
201
+ def add_host(self, host: Host) -> bool:
231
202
  added = False
232
203
  if host.name not in self.host_names:
233
204
  self.hosts.append(host)
@@ -237,7 +208,7 @@ class Group:
237
208
  added = True
238
209
  return added
239
210
 
240
- def remove_host(self, host):
211
+ def remove_host(self, host: Host) -> bool:
241
212
  removed = False
242
213
  if host.name in self.host_names:
243
214
  self.hosts.remove(host)
@@ -247,7 +218,13 @@ class Group:
247
218
  removed = True
248
219
  return removed
249
220
 
250
- def set_variable(self, key, value):
221
+ def set_variable(self, key: str, value: t.Any) -> None:
222
+ key = helpers.remove_trust(key)
223
+
224
+ try:
225
+ validate_variable_name(key)
226
+ except AnsibleError as ex:
227
+ Display().deprecated(msg=f'Accepting inventory variable with invalid name {key!r}.', version='2.23', help_text=ex._help_text, obj=ex.obj)
251
228
 
252
229
  if key == 'ansible_group_priority':
253
230
  self.set_priority(int(value))
@@ -257,36 +234,36 @@ class Group:
257
234
  else:
258
235
  self.vars[key] = value
259
236
 
260
- def clear_hosts_cache(self):
237
+ def clear_hosts_cache(self) -> None:
261
238
 
262
239
  self._hosts_cache = None
263
240
  for g in self.get_ancestors():
264
241
  g._hosts_cache = None
265
242
 
266
- def get_hosts(self):
243
+ def get_hosts(self) -> list[Host]:
267
244
 
268
245
  if self._hosts_cache is None:
269
246
  self._hosts_cache = self._get_hosts()
270
247
  return self._hosts_cache
271
248
 
272
- def _get_hosts(self):
249
+ def _get_hosts(self) -> list[Host]:
273
250
 
274
- hosts = []
275
- seen = {}
251
+ hosts: list[Host] = []
252
+ seen: set[Host] = set()
276
253
  for kid in self.get_descendants(include_self=True, preserve_ordering=True):
277
254
  kid_hosts = kid.hosts
278
255
  for kk in kid_hosts:
279
256
  if kk not in seen:
280
- seen[kk] = 1
257
+ seen.add(kk)
281
258
  if self.name == 'all' and kk.implicit:
282
259
  continue
283
260
  hosts.append(kk)
284
261
  return hosts
285
262
 
286
- def get_vars(self):
263
+ def get_vars(self) -> dict[str, t.Any]:
287
264
  return self.vars.copy()
288
265
 
289
- def set_priority(self, priority):
266
+ def set_priority(self, priority: int | str) -> None:
290
267
  try:
291
268
  self.priority = int(priority)
292
269
  except TypeError:
@@ -18,6 +18,7 @@
18
18
  #############################################
19
19
  from __future__ import annotations
20
20
 
21
+ from ansible._internal._datatag._tags import TrustedAsTemplate
21
22
  from ansible.utils.vars import combine_vars
22
23
 
23
24
 
@@ -37,3 +38,11 @@ def get_group_vars(groups):
37
38
  results = combine_vars(results, group.get_vars())
38
39
 
39
40
  return results
41
+
42
+
43
+ def remove_trust(value: str) -> str:
44
+ """
45
+ Remove trust from strings which should not be trusted.
46
+ This exists to centralize the untagging call which facilitate patching it out in unit tests.
47
+ """
48
+ return TrustedAsTemplate.untag(value)
ansible/inventory/host.py CHANGED
@@ -17,28 +17,28 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
+ import collections.abc as c
21
+ import typing as t
22
+
20
23
  from collections.abc import Mapping, MutableMapping
21
24
 
25
+ from ansible.errors import AnsibleError
22
26
  from ansible.inventory.group import Group, InventoryObjectType
23
27
  from ansible.parsing.utils.addresses import patterns
24
- from ansible.utils.vars import combine_vars, get_unique_id
28
+ from ansible.utils.display import Display
29
+ from ansible.utils.vars import combine_vars, get_unique_id, validate_variable_name
25
30
 
31
+ from . import helpers # this is left as a module import to facilitate easier unit test patching
26
32
 
27
33
  __all__ = ['Host']
28
34
 
29
35
 
30
36
  class Host:
31
- ''' a single ansible host '''
37
+ """A single ansible host."""
32
38
  base_type = InventoryObjectType.HOST
33
39
 
34
40
  # __slots__ = [ 'name', 'vars', 'groups' ]
35
41
 
36
- def __getstate__(self):
37
- return self.serialize()
38
-
39
- def __setstate__(self, data):
40
- return self.deserialize(data)
41
-
42
42
  def __eq__(self, other):
43
43
  if not isinstance(other, Host):
44
44
  return False
@@ -56,55 +56,28 @@ class Host:
56
56
  def __repr__(self):
57
57
  return self.get_name()
58
58
 
59
- def serialize(self):
60
- groups = []
61
- for group in self.groups:
62
- groups.append(group.serialize())
63
-
64
- return dict(
65
- name=self.name,
66
- vars=self.vars.copy(),
67
- address=self.address,
68
- uuid=self._uuid,
69
- groups=groups,
70
- implicit=self.implicit,
71
- )
72
-
73
- def deserialize(self, data):
74
- self.__init__(gen_uuid=False) # used by __setstate__ to deserialize in place # pylint: disable=unnecessary-dunder-call
75
-
76
- self.name = data.get('name')
77
- self.vars = data.get('vars', dict())
78
- self.address = data.get('address', '')
79
- self._uuid = data.get('uuid', None)
80
- self.implicit = data.get('implicit', False)
81
-
82
- groups = data.get('groups', [])
83
- for group_data in groups:
84
- g = Group()
85
- g.deserialize(group_data)
86
- self.groups.append(g)
59
+ def __init__(self, name: str, port: int | str | None = None, gen_uuid: bool = True) -> None:
60
+ name = helpers.remove_trust(name)
87
61
 
88
- def __init__(self, name=None, port=None, gen_uuid=True):
62
+ self.vars: dict[str, t.Any] = {}
63
+ self.groups: list[Group] = []
64
+ self._uuid: str | None = None
89
65
 
90
- self.vars = {}
91
- self.groups = []
92
- self._uuid = None
93
-
94
- self.name = name
95
- self.address = name
66
+ self.name: str = name
67
+ self.address: str = name
96
68
 
97
69
  if port:
98
70
  self.set_variable('ansible_port', int(port))
99
71
 
100
72
  if gen_uuid:
101
73
  self._uuid = get_unique_id()
102
- self.implicit = False
103
74
 
104
- def get_name(self):
75
+ self.implicit: bool = False
76
+
77
+ def get_name(self) -> str:
105
78
  return self.name
106
79
 
107
- def populate_ancestors(self, additions=None):
80
+ def populate_ancestors(self, additions: c.Iterable[Group] | None = None) -> None:
108
81
  # populate ancestors
109
82
  if additions is None:
110
83
  for group in self.groups:
@@ -114,7 +87,7 @@ class Host:
114
87
  if group not in self.groups:
115
88
  self.groups.append(group)
116
89
 
117
- def add_group(self, group):
90
+ def add_group(self, group: Group) -> bool:
118
91
  added = False
119
92
  # populate ancestors first
120
93
  for oldg in group.get_ancestors():
@@ -127,7 +100,7 @@ class Host:
127
100
  added = True
128
101
  return added
129
102
 
130
- def remove_group(self, group):
103
+ def remove_group(self, group: Group) -> bool:
131
104
  removed = False
132
105
  if group in self.groups:
133
106
  self.groups.remove(group)
@@ -143,18 +116,28 @@ class Host:
143
116
  self.remove_group(oldg)
144
117
  return removed
145
118
 
146
- def set_variable(self, key, value):
119
+ def set_variable(self, key: str, value: t.Any) -> None:
120
+ key = helpers.remove_trust(key)
121
+
122
+ try:
123
+ validate_variable_name(key)
124
+ except AnsibleError as ex:
125
+ Display().deprecated(msg=f'Accepting inventory variable with invalid name {key!r}.', version='2.23', help_text=ex._help_text, obj=ex.obj)
126
+
147
127
  if key in self.vars and isinstance(self.vars[key], MutableMapping) and isinstance(value, Mapping):
148
128
  self.vars = combine_vars(self.vars, {key: value})
149
129
  else:
150
130
  self.vars[key] = value
151
131
 
152
- def get_groups(self):
132
+ def get_groups(self) -> list[Group]:
153
133
  return self.groups
154
134
 
155
- def get_magic_vars(self):
156
- results = {}
157
- results['inventory_hostname'] = self.name
135
+ def get_magic_vars(self) -> dict[str, t.Any]:
136
+ results: dict[str, t.Any] = dict(
137
+ inventory_hostname=self.name,
138
+ )
139
+
140
+ # FUTURE: these values should be dynamically calculated on access ala the rest of magic vars
158
141
  if patterns['ipv4'].match(self.name) or patterns['ipv6'].match(self.name):
159
142
  results['inventory_hostname_short'] = self.name
160
143
  else:
@@ -164,5 +147,5 @@ class Host:
164
147
 
165
148
  return results
166
149
 
167
- def get_vars(self):
150
+ def get_vars(self) -> dict[str, t.Any]:
168
151
  return combine_vars(self.vars, self.get_magic_vars())
@@ -19,28 +19,34 @@
19
19
  from __future__ import annotations
20
20
 
21
21
  import fnmatch
22
+ import functools
22
23
  import os
23
- import sys
24
24
  import re
25
25
  import itertools
26
- import traceback
26
+ import typing as t
27
27
 
28
28
  from operator import attrgetter
29
29
  from random import shuffle
30
30
 
31
31
  from ansible import constants as C
32
- from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
32
+ from ansible._internal import _json, _wrapt
33
+ from ansible._internal._json import EncryptedStringBehavior
34
+ from ansible.errors import AnsibleError, AnsibleOptionsError
33
35
  from ansible.inventory.data import InventoryData
34
36
  from ansible.module_utils.six import string_types
35
37
  from ansible.module_utils.common.text.converters import to_bytes, to_text
36
38
  from ansible.parsing.utils.addresses import parse_address
37
39
  from ansible.plugins.loader import inventory_loader
40
+ from ansible._internal._datatag._tags import Origin
38
41
  from ansible.utils.helpers import deduplicate_list
39
42
  from ansible.utils.path import unfrackpath
40
43
  from ansible.utils.display import Display
41
44
  from ansible.utils.vars import combine_vars
42
45
  from ansible.vars.plugins import get_vars_from_inventory_sources
43
46
 
47
+ if t.TYPE_CHECKING:
48
+ from ansible.plugins.inventory import BaseInventoryPlugin
49
+
44
50
  display = Display()
45
51
 
46
52
  IGNORED_ALWAYS = [br"^\.", b"^host_vars$", b"^group_vars$", b"^vars_plugins$"]
@@ -50,7 +56,7 @@ IGNORED_EXTS = [b'%s$' % to_bytes(re.escape(x)) for x in C.INVENTORY_IGNORE_EXTS
50
56
  IGNORED = re.compile(b'|'.join(IGNORED_ALWAYS + IGNORED_PATTERNS + IGNORED_EXTS))
51
57
 
52
58
  PATTERN_WITH_SUBSCRIPT = re.compile(
53
- r'''^
59
+ r"""^
54
60
  (.+) # A pattern expression ending with...
55
61
  \[(?: # A [subscript] expression comprising:
56
62
  (-?[0-9]+)| # A single positive or negative number
@@ -58,12 +64,12 @@ PATTERN_WITH_SUBSCRIPT = re.compile(
58
64
  ([0-9]*)
59
65
  )\]
60
66
  $
61
- ''', re.X
67
+ """, re.X
62
68
  )
63
69
 
64
70
 
65
71
  def order_patterns(patterns):
66
- ''' takes a list of patterns and reorders them by modifier to apply them consistently '''
72
+ """ takes a list of patterns and reorders them by modifier to apply them consistently """
67
73
 
68
74
  # FIXME: this goes away if we apply patterns incrementally or by groups
69
75
  pattern_regular = []
@@ -125,19 +131,19 @@ def split_host_pattern(pattern):
125
131
  # This mishandles IPv6 addresses, and is retained only for backwards
126
132
  # compatibility.
127
133
  patterns = re.findall(
128
- to_text(r'''(?: # We want to match something comprising:
134
+ to_text(r"""(?: # We want to match something comprising:
129
135
  [^\s:\[\]] # (anything other than whitespace or ':[]'
130
136
  | # ...or...
131
137
  \[[^\]]*\] # a single complete bracketed expression)
132
138
  )+ # occurring once or more
133
- '''), pattern, re.X
139
+ """), pattern, re.X
134
140
  )
135
141
 
136
142
  return [p.strip() for p in patterns if p.strip()]
137
143
 
138
144
 
139
145
  class InventoryManager(object):
140
- ''' Creates and manages inventory '''
146
+ """ Creates and manages inventory """
141
147
 
142
148
  def __init__(self, loader, sources=None, parse=True, cache=True):
143
149
 
@@ -196,12 +202,12 @@ class InventoryManager(object):
196
202
  def get_host(self, hostname):
197
203
  return self._inventory.get_host(hostname)
198
204
 
199
- def _fetch_inventory_plugins(self):
200
- ''' sets up loaded inventory plugins for usage '''
205
+ def _fetch_inventory_plugins(self) -> list[BaseInventoryPlugin]:
206
+ """ sets up loaded inventory plugins for usage """
201
207
 
202
208
  display.vvvv('setting up inventory plugins')
203
209
 
204
- plugins = []
210
+ plugins: list[BaseInventoryPlugin] = []
205
211
  for name in C.INVENTORY_ENABLED:
206
212
  plugin = inventory_loader.get(name)
207
213
  if plugin:
@@ -215,7 +221,7 @@ class InventoryManager(object):
215
221
  return plugins
216
222
 
217
223
  def parse_sources(self, cache=False):
218
- ''' iterate over inventory sources and parse each one to populate it'''
224
+ """ iterate over inventory sources and parse each one to populate it"""
219
225
 
220
226
  parsed = False
221
227
  # allow for multiple inventory parsing
@@ -243,7 +249,7 @@ class InventoryManager(object):
243
249
  host.vars = combine_vars(host.vars, get_vars_from_inventory_sources(self._loader, self._sources, [host], 'inventory'))
244
250
 
245
251
  def parse_source(self, source, cache=False):
246
- ''' Generate or update inventory for the source provided '''
252
+ """ Generate or update inventory for the source provided """
247
253
 
248
254
  parsed = False
249
255
  failures = []
@@ -276,7 +282,6 @@ class InventoryManager(object):
276
282
 
277
283
  # try source with each plugin
278
284
  for plugin in self._fetch_inventory_plugins():
279
-
280
285
  plugin_name = to_text(getattr(plugin, '_load_name', getattr(plugin, '_original_path', '')))
281
286
  display.debug(u'Attempting to use plugin %s (%s)' % (plugin_name, plugin._original_path))
282
287
 
@@ -287,9 +292,14 @@ class InventoryManager(object):
287
292
  plugin_wants = False
288
293
 
289
294
  if plugin_wants:
295
+ # have this tag ready to apply to errors or output; str-ify source since it is often tagged by the CLI
296
+ origin = Origin(description=f'<inventory plugin {plugin_name!r} with source {str(source)!r}>')
290
297
  try:
291
- # FIXME in case plugin fails 1/2 way we have partial inventory
292
- plugin.parse(self._inventory, self._loader, source, cache=cache)
298
+ inventory_wrapper = _InventoryDataWrapper(self._inventory, target_plugin=plugin, origin=origin)
299
+
300
+ # FUTURE: now that we have a wrapper around inventory, we can have it use ChainMaps to preview the in-progress inventory,
301
+ # but be able to roll back partial inventory failures by discarding the outermost layer
302
+ plugin.parse(inventory_wrapper, self._loader, source, cache=cache)
293
303
  try:
294
304
  plugin.update_cache_if_changed()
295
305
  except AttributeError:
@@ -298,14 +308,17 @@ class InventoryManager(object):
298
308
  parsed = True
299
309
  display.vvv('Parsed %s inventory source with %s plugin' % (source, plugin_name))
300
310
  break
301
- except AnsibleParserError as e:
302
- display.debug('%s was not parsable by %s' % (source, plugin_name))
303
- tb = ''.join(traceback.format_tb(sys.exc_info()[2]))
304
- failures.append({'src': source, 'plugin': plugin_name, 'exc': e, 'tb': tb})
305
- except Exception as e:
306
- display.debug('%s failed while attempting to parse %s' % (plugin_name, source))
307
- tb = ''.join(traceback.format_tb(sys.exc_info()[2]))
308
- failures.append({'src': source, 'plugin': plugin_name, 'exc': AnsibleError(e), 'tb': tb})
311
+ except AnsibleError as ex:
312
+ if not ex.obj:
313
+ ex.obj = origin
314
+ failures.append({'src': source, 'plugin': plugin_name, 'exc': ex})
315
+ except Exception as ex:
316
+ # DTFIX-FUTURE: fix this error handling to correctly deal with messaging
317
+ try:
318
+ # omit line number to prevent contextual display of script or possibly sensitive info
319
+ raise AnsibleError(str(ex), obj=origin) from ex
320
+ except AnsibleError as ex:
321
+ failures.append({'src': source, 'plugin': plugin_name, 'exc': ex})
309
322
  else:
310
323
  display.vvv("%s declined parsing %s as it did not pass its verify_file() method" % (plugin_name, source))
311
324
 
@@ -319,9 +332,8 @@ class InventoryManager(object):
319
332
  if failures:
320
333
  # only if no plugin processed files should we show errors.
321
334
  for fail in failures:
322
- display.warning(u'\n* Failed to parse %s with %s plugin: %s' % (to_text(fail['src']), fail['plugin'], to_text(fail['exc'])))
323
- if 'tb' in fail:
324
- display.vvv(to_text(fail['tb']))
335
+ # `obj` should always be set
336
+ display.error_as_warning(msg=f'Failed to parse inventory with {fail["plugin"]!r} plugin.', exception=fail['exc'])
325
337
 
326
338
  # final error/warning on inventory source failure
327
339
  if C.INVENTORY_ANY_UNPARSED_IS_FAILED:
@@ -335,12 +347,12 @@ class InventoryManager(object):
335
347
  return parsed
336
348
 
337
349
  def clear_caches(self):
338
- ''' clear all caches '''
350
+ """ clear all caches """
339
351
  self._hosts_patterns_cache = {}
340
352
  self._pattern_cache = {}
341
353
 
342
354
  def refresh_inventory(self):
343
- ''' recalculate inventory '''
355
+ """ recalculate inventory """
344
356
 
345
357
  self.clear_caches()
346
358
  self._inventory = InventoryData()
@@ -657,9 +669,9 @@ class InventoryManager(object):
657
669
  self._pattern_cache = {}
658
670
 
659
671
  def add_dynamic_host(self, host_info, result_item):
660
- '''
672
+ """
661
673
  Helper function to add a new host to inventory based on a task result.
662
- '''
674
+ """
663
675
 
664
676
  changed = False
665
677
  if not result_item.get('refresh'):
@@ -697,10 +709,10 @@ class InventoryManager(object):
697
709
  result_item['changed'] = changed
698
710
 
699
711
  def add_dynamic_group(self, host, result_item):
700
- '''
712
+ """
701
713
  Helper function to add a group (if it does not exist), and to assign the
702
714
  specified host to that group.
703
- '''
715
+ """
704
716
 
705
717
  changed = False
706
718
 
@@ -749,3 +761,36 @@ class InventoryManager(object):
749
761
  self.reconcile_inventory()
750
762
 
751
763
  result_item['changed'] = changed
764
+
765
+
766
+ class _InventoryDataWrapper(_wrapt.ObjectProxy):
767
+ """
768
+ Proxy wrapper around InventoryData.
769
+ Allows `set_variable` calls to automatically apply template trust for plugins that don't know how.
770
+ """
771
+
772
+ # declared as class attrs to signal to ObjectProxy that we want them stored on the proxy, not the wrapped value
773
+ _target_plugin = None
774
+ _default_origin = None
775
+
776
+ def __init__(self, referent: InventoryData, target_plugin: BaseInventoryPlugin, origin: Origin) -> None:
777
+ super().__init__(referent)
778
+ self._target_plugin = target_plugin
779
+ # fallback origin to ensure that vars are tagged with at least the file they came from
780
+ self._default_origin = origin
781
+
782
+ @functools.cached_property
783
+ def _inspector(self) -> _json.AnsibleVariableVisitor:
784
+ """
785
+ Inventory plugins can delegate to other plugins (e.g. `auto`).
786
+ This hack defers sampling the target plugin's `trusted_by_default` attr until `set_variable` is called, typically inside `parse`.
787
+ Trust is then optionally applied based on the plugin's declared intent via `trusted_by_default`.
788
+ """
789
+ return _json.AnsibleVariableVisitor(
790
+ trusted_as_template=self._target_plugin.trusted_by_default,
791
+ origin=self._default_origin,
792
+ encrypted_string_behavior=EncryptedStringBehavior.PRESERVE,
793
+ )
794
+
795
+ def set_variable(self, entity: str, varname: str, value: t.Any) -> None:
796
+ self.__wrapped__.set_variable(entity, varname, self._inspector.visit(value))