ansible-core 2.18.7__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.7.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.7.dist-info/RECORD +0 -992
  749. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
  750. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
  751. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
  752. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
  753. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  754. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  755. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  756. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  757. {ansible_core-2.18.7.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
@@ -2,23 +2,28 @@
2
2
  # Copyright: (c) 2017, Ansible Project
3
3
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
 
5
+ from __future__ import annotations
5
6
  from __future__ import annotations
6
7
 
7
8
  import copy
8
9
  import os
9
10
  import os.path
11
+ import pathlib
10
12
  import re
11
13
  import tempfile
12
14
  import typing as t
13
15
 
14
16
  from ansible import constants as C
15
17
  from ansible.errors import AnsibleFileNotFound, AnsibleParserError
18
+ from ansible._internal._errors import _error_utils
16
19
  from ansible.module_utils.basic import is_executable
20
+ from ansible._internal._datatag._tags import Origin, TrustedAsTemplate, SourceWasEncrypted
21
+ from ansible.module_utils._internal._datatag import AnsibleTagHelper
17
22
  from ansible.module_utils.six import binary_type, text_type
18
23
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
19
24
  from ansible.parsing.quoting import unquote
20
25
  from ansible.parsing.utils.yaml import from_yaml
21
- from ansible.parsing.vault import VaultLib, is_encrypted, is_encrypted_file, parse_vaulttext_envelope, PromptVaultSecret
26
+ from ansible.parsing.vault import VaultLib, is_encrypted, is_encrypted_file, PromptVaultSecret
22
27
  from ansible.utils.path import unfrackpath
23
28
  from ansible.utils.display import Display
24
29
 
@@ -32,7 +37,7 @@ RE_TASKS = re.compile(u'(?:^|%s)+tasks%s?$' % (os.path.sep, os.path.sep))
32
37
 
33
38
  class DataLoader:
34
39
 
35
- '''
40
+ """
36
41
  The DataLoader class is used to load and parse YAML or JSON content,
37
42
  either from a given file name or from a string that was previously
38
43
  read in through other means. A Vault password can be specified, and
@@ -47,7 +52,7 @@ class DataLoader:
47
52
  # optionally: dl.set_vault_secrets([('default', ansible.parsing.vault.PrompVaultSecret(...),)])
48
53
  ds = dl.load('...')
49
54
  ds = dl.load_from_file('/path/to/file')
50
- '''
55
+ """
51
56
 
52
57
  def __init__(self):
53
58
 
@@ -73,12 +78,19 @@ class DataLoader:
73
78
  def set_vault_secrets(self, vault_secrets: list[tuple[str, PromptVaultSecret]] | None) -> None:
74
79
  self._vault.secrets = vault_secrets
75
80
 
76
- def load(self, data: str, file_name: str = '<string>', show_content: bool = True, json_only: bool = False) -> t.Any:
77
- '''Backwards compat for now'''
78
- return from_yaml(data, file_name, show_content, self._vault.secrets, json_only=json_only)
79
-
80
- def load_from_file(self, file_name: str, cache: str = 'all', unsafe: bool = False, json_only: bool = False) -> t.Any:
81
- '''
81
+ def load(
82
+ self,
83
+ data: str,
84
+ file_name: str | None = None, # DTFIX-FUTURE: consider deprecating this in favor of tagging Origin on data
85
+ show_content: bool = True, # DTFIX-FUTURE: consider future deprecation, but would need RedactAnnotatedSourceContext public
86
+ json_only: bool = False,
87
+ ) -> t.Any:
88
+ """Backwards compat for now"""
89
+ with _error_utils.RedactAnnotatedSourceContext.when(not show_content):
90
+ return from_yaml(data=data, file_name=file_name, json_only=json_only)
91
+
92
+ def load_from_file(self, file_name: str, cache: str = 'all', unsafe: bool = False, json_only: bool = False, trusted_as_template: bool = False) -> t.Any:
93
+ """
82
94
  Loads data from a file, which can contain either JSON or YAML.
83
95
 
84
96
  :param file_name: The name of the file to load data from.
@@ -86,7 +98,7 @@ class DataLoader:
86
98
  :param unsafe: If True, returns the parsed data as-is without deep copying.
87
99
  :param json_only: If True, only loads JSON data from the file.
88
100
  :return: The loaded data, optionally deep-copied for safety.
89
- '''
101
+ """
90
102
 
91
103
  # Resolve the file name
92
104
  file_name = self.path_dwim(file_name)
@@ -98,16 +110,22 @@ class DataLoader:
98
110
  if cache != 'none' and file_name in self._FILE_CACHE:
99
111
  parsed_data = self._FILE_CACHE[file_name]
100
112
  else:
101
- # Read the file contents and load the data structure from them
102
- (b_file_data, show_content) = self._get_file_contents(file_name)
113
+ file_data = self.get_text_file_contents(file_name)
103
114
 
104
- file_data = to_text(b_file_data, errors='surrogate_or_strict')
105
- parsed_data = self.load(data=file_data, file_name=file_name, show_content=show_content, json_only=json_only)
115
+ if trusted_as_template:
116
+ file_data = TrustedAsTemplate().tag(file_data)
117
+
118
+ parsed_data = self.load(data=file_data, file_name=file_name, json_only=json_only)
119
+
120
+ # only tagging the container, used by include_vars to determine if vars should be shown or not
121
+ # this is a temporary measure until a proper data senitivity system is in place
122
+ if SourceWasEncrypted.is_tagged_on(file_data):
123
+ parsed_data = SourceWasEncrypted().tag(parsed_data)
106
124
 
107
125
  # Cache the file contents for next time based on the cache option
108
126
  if cache == 'all':
109
127
  self._FILE_CACHE[file_name] = parsed_data
110
- elif cache == 'vaulted' and not show_content:
128
+ elif cache == 'vaulted' and SourceWasEncrypted.is_tagged_on(file_data):
111
129
  self._FILE_CACHE[file_name] = parsed_data
112
130
 
113
131
  # Return the parsed data, optionally deep-copied for safety
@@ -133,25 +151,51 @@ class DataLoader:
133
151
  return os.listdir(path)
134
152
 
135
153
  def is_executable(self, path: str) -> bool:
136
- '''is the given path executable?'''
154
+ """is the given path executable?"""
137
155
  path = self.path_dwim(path)
138
156
  return is_executable(path)
139
157
 
140
- def _decrypt_if_vault_data(self, b_vault_data: bytes, b_file_name: bytes | None = None) -> tuple[bytes, bool]:
141
- '''Decrypt b_vault_data if encrypted and return b_data and the show_content flag'''
158
+ def _decrypt_if_vault_data(self, b_data: bytes) -> tuple[bytes, bool]:
159
+ """Decrypt b_vault_data if encrypted and return b_data and the show_content flag"""
160
+
161
+ if encrypted_source := is_encrypted(b_data):
162
+ b_data = self._vault.decrypt(b_data)
163
+
164
+ return b_data, not encrypted_source
165
+
166
+ def get_text_file_contents(self, file_name: str, encoding: str | None = None) -> str:
167
+ """
168
+ Returns an `Origin` tagged string with the content of the specified (DWIM-expanded for relative) file path, decrypting if necessary.
169
+ Callers must only specify `encoding` when the user can configure it, as error messages in that case will imply configurability.
170
+ If `encoding` is not specified, UTF-8 will be used.
171
+ """
172
+ bytes_content, source_was_plaintext = self._get_file_contents(file_name)
173
+
174
+ if encoding is None:
175
+ encoding = 'utf-8'
176
+ help_text = 'This file must be UTF-8 encoded.'
177
+ else:
178
+ help_text = 'Ensure the correct encoding was specified.'
179
+
180
+ try:
181
+ str_content = bytes_content.decode(encoding=encoding, errors='strict')
182
+ except UnicodeDecodeError:
183
+ str_content = bytes_content.decode(encoding=encoding, errors='surrogateescape')
142
184
 
143
- if not is_encrypted(b_vault_data):
144
- show_content = True
145
- return b_vault_data, show_content
185
+ display.deprecated(
186
+ msg=f"File {file_name!r} could not be decoded as {encoding!r}. Invalid content has been escaped.",
187
+ version="2.23",
188
+ # obj intentionally omitted since there's no value in showing its contents
189
+ help_text=help_text,
190
+ )
146
191
 
147
- b_ciphertext, b_version, cipher_name, vault_id = parse_vaulttext_envelope(b_vault_data)
148
- b_data = self._vault.decrypt(b_vault_data, filename=b_file_name)
192
+ if not source_was_plaintext:
193
+ str_content = SourceWasEncrypted().tag(str_content)
149
194
 
150
- show_content = False
151
- return b_data, show_content
195
+ return AnsibleTagHelper.tag_copy(bytes_content, str_content)
152
196
 
153
197
  def _get_file_contents(self, file_name: str) -> tuple[bytes, bool]:
154
- '''
198
+ """
155
199
  Reads the file contents from the given file name
156
200
 
157
201
  If the contents are vault-encrypted, it will decrypt them and return
@@ -162,40 +206,41 @@ class DataLoader:
162
206
  :raises AnsibleFileNotFound: if the file_name does not refer to a file
163
207
  :raises AnsibleParserError: if we were unable to read the file
164
208
  :return: Returns a byte string of the file contents
165
- '''
166
- if not file_name or not isinstance(file_name, (binary_type, text_type)):
167
- raise AnsibleParserError("Invalid filename: '%s'" % to_native(file_name))
209
+ """
210
+ if not file_name or not isinstance(file_name, str):
211
+ raise TypeError(f"Invalid filename {file_name!r}.")
168
212
 
169
- b_file_name = to_bytes(self.path_dwim(file_name))
170
- # This is what we really want but have to fix unittests to make it pass
171
- # if not os.path.exists(b_file_name) or not os.path.isfile(b_file_name):
172
- if not self.path_exists(b_file_name):
173
- raise AnsibleFileNotFound("Unable to retrieve file contents", file_name=file_name)
213
+ file_name = self.path_dwim(file_name)
174
214
 
175
215
  try:
176
- with open(b_file_name, 'rb') as f:
177
- data = f.read()
178
- return self._decrypt_if_vault_data(data, b_file_name)
179
- except (IOError, OSError) as e:
180
- raise AnsibleParserError("an error occurred while trying to read the file '%s': %s" % (file_name, to_native(e)), orig_exc=e)
216
+ data = pathlib.Path(file_name).read_bytes()
217
+ except FileNotFoundError as ex:
218
+ # DTFIX-FUTURE: why not just let the builtin one fly?
219
+ raise AnsibleFileNotFound("Unable to retrieve file contents.", file_name=file_name) from ex
220
+ except OSError as ex:
221
+ raise AnsibleParserError(f"An error occurred while trying to read the file {file_name!r}.") from ex
222
+
223
+ data = Origin(path=file_name).tag(data)
224
+
225
+ return self._decrypt_if_vault_data(data)
181
226
 
182
227
  def get_basedir(self) -> str:
183
- ''' returns the current basedir '''
228
+ """ returns the current basedir """
184
229
  return self._basedir
185
230
 
186
231
  def set_basedir(self, basedir: str) -> None:
187
- ''' sets the base directory, used to find files when a relative path is given '''
232
+ """ sets the base directory, used to find files when a relative path is given """
188
233
 
189
234
  if basedir is not None:
190
235
  self._basedir = to_text(basedir)
191
236
 
192
237
  def path_dwim(self, given: str) -> str:
193
- '''
238
+ """
194
239
  make relative paths work like folks expect.
195
- '''
240
+ """
196
241
 
197
- given = unquote(given)
198
242
  given = to_text(given, errors='surrogate_or_strict')
243
+ given = unquote(given)
199
244
 
200
245
  if given.startswith(to_text(os.path.sep)) or given.startswith(u'~'):
201
246
  path = given
@@ -206,7 +251,7 @@ class DataLoader:
206
251
  return unfrackpath(path, follow=False)
207
252
 
208
253
  def _is_role(self, path: str) -> bool:
209
- ''' imperfect role detection, roles are still valid w/o tasks|meta/main.yml|yaml|etc '''
254
+ """ imperfect role detection, roles are still valid w/o tasks|meta/main.yml|yaml|etc """
210
255
 
211
256
  b_path = to_bytes(path, errors='surrogate_or_strict')
212
257
  b_path_dirname = os.path.dirname(b_path)
@@ -240,13 +285,13 @@ class DataLoader:
240
285
  return False
241
286
 
242
287
  def path_dwim_relative(self, path: str, dirname: str, source: str, is_role: bool = False) -> str:
243
- '''
288
+ """
244
289
  find one file in either a role or playbook dir with or without
245
290
  explicitly named dirname subdirs
246
291
 
247
292
  Used in action plugins and lookups to find supplemental files that
248
293
  could be in either place.
249
- '''
294
+ """
250
295
 
251
296
  search = []
252
297
  source = to_text(source, errors='surrogate_or_strict')
@@ -295,7 +340,7 @@ class DataLoader:
295
340
  return candidate
296
341
 
297
342
  def path_dwim_relative_stack(self, paths: list[str], dirname: str, source: str, is_role: bool = False) -> str:
298
- '''
343
+ """
299
344
  find one file in first path in stack taking roles into account and adding play basedir as fallback
300
345
 
301
346
  :arg paths: A list of text strings which are the paths to look for the filename in.
@@ -305,7 +350,7 @@ class DataLoader:
305
350
  :rtype: A text string
306
351
  :returns: An absolute path to the filename ``source`` if found
307
352
  :raises: An AnsibleFileNotFound Exception if the file is found to exist in the search paths
308
- '''
353
+ """
309
354
  b_dirname = to_bytes(dirname, errors='surrogate_or_strict')
310
355
  b_source = to_bytes(source, errors='surrogate_or_strict')
311
356
 
@@ -353,7 +398,7 @@ class DataLoader:
353
398
  return result
354
399
 
355
400
  def _create_content_tempfile(self, content: str | bytes) -> str:
356
- ''' Create a tempfile containing defined content '''
401
+ """ Create a tempfile containing defined content """
357
402
  fd, content_tempfile = tempfile.mkstemp(dir=C.DEFAULT_LOCAL_TMP)
358
403
  f = os.fdopen(fd, 'wb')
359
404
  content = to_bytes(content)
@@ -392,19 +437,19 @@ class DataLoader:
392
437
  # if the file is encrypted and no password was specified,
393
438
  # the decrypt call would throw an error, but we check first
394
439
  # since the decrypt function doesn't know the file name
395
- data = f.read()
440
+ data = Origin(path=real_path).tag(f.read())
396
441
  if not self._vault.secrets:
397
442
  raise AnsibleParserError("A vault password or secret must be specified to decrypt %s" % to_native(file_path))
398
443
 
399
- data = self._vault.decrypt(data, filename=real_path)
444
+ data = self._vault.decrypt(data)
400
445
  # Make a temp file
401
446
  real_path = self._create_content_tempfile(data)
402
447
  self._tempfiles.add(real_path)
403
448
 
404
449
  return real_path
405
450
 
406
- except (IOError, OSError) as e:
407
- raise AnsibleParserError("an error occurred while trying to read the file '%s': %s" % (to_native(real_path), to_native(e)), orig_exc=e)
451
+ except OSError as ex:
452
+ raise AnsibleParserError(f"an error occurred while trying to read the file {to_text(real_path)!r}.") from ex
408
453
 
409
454
  def cleanup_tmp_file(self, file_path: str) -> None:
410
455
  """
@@ -19,16 +19,18 @@ from __future__ import annotations
19
19
 
20
20
  import ansible.constants as C
21
21
  from ansible.errors import AnsibleParserError, AnsibleError, AnsibleAssertionError
22
- from ansible.module_utils.six import string_types
22
+ from ansible.module_utils._internal._datatag import AnsibleTagHelper
23
+ from ansible.module_utils.common.sentinel import Sentinel
23
24
  from ansible.module_utils.common.text.converters import to_text
24
25
  from ansible.parsing.splitter import parse_kv, split_args
26
+ from ansible.parsing.vault import EncryptedString
25
27
  from ansible.plugins.loader import module_loader, action_loader
26
- from ansible.template import Templar
28
+ from ansible._internal._templating import _jinja_bits
29
+ from ansible.utils.display import Display
27
30
  from ansible.utils.fqcn import add_internal_fqcns
28
- from ansible.utils.sentinel import Sentinel
29
31
 
30
32
 
31
- # modules formated for user msg
33
+ # modules formatted for user msg
32
34
  _BUILTIN_RAW_PARAM_MODULES_SIMPLE = set([
33
35
  'include_vars',
34
36
  'include_tasks',
@@ -129,59 +131,64 @@ class ModuleArgsParser:
129
131
  self._task_attrs.update(['local_action', 'static'])
130
132
  self._task_attrs = frozenset(self._task_attrs)
131
133
 
132
- self.resolved_action = None
133
-
134
- def _split_module_string(self, module_string):
135
- '''
134
+ def _split_module_string(self, module_string: str) -> tuple[str, str]:
135
+ """
136
136
  when module names are expressed like:
137
137
  action: copy src=a dest=b
138
138
  the first part of the string is the name of the module
139
139
  and the rest are strings pertaining to the arguments.
140
- '''
140
+ """
141
141
 
142
142
  tokens = split_args(module_string)
143
143
  if len(tokens) > 1:
144
- return (tokens[0].strip(), " ".join(tokens[1:]))
144
+ result = (tokens[0].strip(), " ".join(tokens[1:]))
145
145
  else:
146
- return (tokens[0].strip(), "")
146
+ result = (tokens[0].strip(), "")
147
+
148
+ return AnsibleTagHelper.tag_copy(module_string, result[0]), AnsibleTagHelper.tag_copy(module_string, result[1])
147
149
 
148
150
  def _normalize_parameters(self, thing, action=None, additional_args=None):
149
- '''
151
+ """
150
152
  arguments can be fuzzy. Deal with all the forms.
151
- '''
152
-
153
- additional_args = {} if additional_args is None else additional_args
153
+ """
154
154
 
155
155
  # final args are the ones we'll eventually return, so first update
156
156
  # them with any additional args specified, which have lower priority
157
157
  # than those which may be parsed/normalized next
158
158
  final_args = dict()
159
- if additional_args:
160
- if isinstance(additional_args, string_types):
161
- templar = Templar(loader=None)
162
- if templar.is_template(additional_args):
163
- final_args['_variable_params'] = additional_args
164
- else:
165
- raise AnsibleParserError("Complex args containing variables cannot use bare variables (without Jinja2 delimiters), "
166
- "and must use the full variable style ('{{var_name}}')")
159
+
160
+ if additional_args is not Sentinel:
161
+ if isinstance(additional_args, str) and _jinja_bits.is_possibly_all_template(additional_args):
162
+ final_args['_variable_params'] = additional_args
167
163
  elif isinstance(additional_args, dict):
168
164
  final_args.update(additional_args)
165
+ elif additional_args is None:
166
+ Display().deprecated(
167
+ msg="Ignoring empty task `args` keyword.",
168
+ version="2.23",
169
+ help_text='A mapping or template which resolves to a mapping is required.',
170
+ obj=self._task_ds,
171
+ )
169
172
  else:
170
- raise AnsibleParserError('Complex args must be a dictionary or variable string ("{{var}}").')
173
+ raise AnsibleParserError(
174
+ message='The value of the task `args` keyword is invalid.',
175
+ help_text='A mapping or template which resolves to a mapping is required.',
176
+ obj=additional_args,
177
+ )
171
178
 
172
179
  # how we normalize depends if we figured out what the module name is
173
180
  # yet. If we have already figured it out, it's a 'new style' invocation.
174
181
  # otherwise, it's not
175
182
 
176
183
  if action is not None:
177
- args = self._normalize_new_style_args(thing, action)
184
+ args = self._normalize_new_style_args(thing, action, additional_args)
178
185
  else:
179
186
  (action, args) = self._normalize_old_style_args(thing)
180
187
 
181
188
  # this can occasionally happen, simplify
182
189
  if args and 'args' in args:
183
190
  tmp_args = args.pop('args')
184
- if isinstance(tmp_args, string_types):
191
+ if isinstance(tmp_args, str):
185
192
  tmp_args = parse_kv(tmp_args)
186
193
  args.update(tmp_args)
187
194
 
@@ -204,8 +211,8 @@ class ModuleArgsParser:
204
211
 
205
212
  return (action, final_args)
206
213
 
207
- def _normalize_new_style_args(self, thing, action):
208
- '''
214
+ def _normalize_new_style_args(self, thing, action, additional_args):
215
+ """
209
216
  deals with fuzziness in new style module invocations
210
217
  accepting key=value pairs and dictionaries, and returns
211
218
  a dictionary of arguments
@@ -215,15 +222,29 @@ class ModuleArgsParser:
215
222
  {'region': 'xyz'}, 'ec2'
216
223
  standardized outputs like:
217
224
  { _raw_params: 'echo hi', _uses_shell: True }
218
- '''
225
+ """
219
226
 
220
227
  if isinstance(thing, dict):
221
228
  # form is like: { xyz: { x: 2, y: 3 } }
222
229
  args = thing
223
- elif isinstance(thing, string_types):
230
+ elif isinstance(thing, str):
224
231
  # form is like: copy: src=a dest=b
225
232
  check_raw = action in FREEFORM_ACTIONS
226
233
  args = parse_kv(thing, check_raw=check_raw)
234
+ args_keys = set(args) - {'_raw_params'}
235
+
236
+ if args_keys and additional_args is not Sentinel:
237
+ kv_args = ', '.join(repr(arg) for arg in sorted(args_keys))
238
+
239
+ Display().deprecated(
240
+ msg=f"Merging legacy k=v args ({kv_args}) into task args.",
241
+ help_text="Include all task args in the task `args` mapping.",
242
+ version="2.23",
243
+ obj=thing,
244
+ )
245
+ elif isinstance(thing, EncryptedString):
246
+ # k=v parsing intentionally omitted
247
+ args = dict(_raw_params=thing)
227
248
  elif thing is None:
228
249
  # this can happen with modules which take no params, like ping:
229
250
  args = None
@@ -232,7 +253,7 @@ class ModuleArgsParser:
232
253
  return args
233
254
 
234
255
  def _normalize_old_style_args(self, thing):
235
- '''
256
+ """
236
257
  deals with fuzziness in old-style (action/local_action) module invocations
237
258
  returns tuple of (module_name, dictionary_args)
238
259
 
@@ -242,13 +263,14 @@ class ModuleArgsParser:
242
263
  {'module': 'ec2', 'x': 1 }
243
264
  standardized outputs like:
244
265
  ('ec2', { 'x': 1} )
245
- '''
266
+ """
246
267
 
247
268
  action = None
248
269
  args = None
249
270
 
250
271
  if isinstance(thing, dict):
251
272
  # form is like: action: { module: 'copy', src: 'a', dest: 'b' }
273
+ Display().deprecated("Using a mapping for `action` is deprecated.", version='2.23', help_text='Use a string value for `action`.', obj=thing)
252
274
  thing = thing.copy()
253
275
  if 'module' in thing:
254
276
  action, module_args = self._split_module_string(thing['module'])
@@ -257,7 +279,7 @@ class ModuleArgsParser:
257
279
  args.update(parse_kv(module_args, check_raw=check_raw))
258
280
  del args['module']
259
281
 
260
- elif isinstance(thing, string_types):
282
+ elif isinstance(thing, str):
261
283
  # form is like: action: copy src=a dest=b
262
284
  (action, args) = self._split_module_string(thing)
263
285
  check_raw = action in FREEFORM_ACTIONS
@@ -270,13 +292,11 @@ class ModuleArgsParser:
270
292
  return (action, args)
271
293
 
272
294
  def parse(self, skip_action_validation=False):
273
- '''
295
+ """
274
296
  Given a task in one of the supported forms, parses and returns
275
297
  returns the action, arguments, and delegate_to values for the
276
298
  task, dealing with all sorts of levels of fuzziness.
277
- '''
278
-
279
- thing = None
299
+ """
280
300
 
281
301
  action = None
282
302
  delegate_to = self._task_ds.get('delegate_to', Sentinel)
@@ -285,14 +305,14 @@ class ModuleArgsParser:
285
305
  # This is the standard YAML form for command-type modules. We grab
286
306
  # the args and pass them in as additional arguments, which can/will
287
307
  # be overwritten via dict updates from the other arg sources below
288
- additional_args = self._task_ds.get('args', dict())
308
+ additional_args = self._task_ds.get('args', Sentinel)
289
309
 
290
310
  # We can have one of action, local_action, or module specified
291
311
  # action
292
312
  if 'action' in self._task_ds:
293
313
  # an old school 'action' statement
294
314
  thing = self._task_ds['action']
295
- action, args = self._normalize_parameters(thing, action=action, additional_args=additional_args)
315
+ action, args = self._normalize_parameters(thing, additional_args=additional_args)
296
316
 
297
317
  # local_action
298
318
  if 'local_action' in self._task_ds:
@@ -301,12 +321,7 @@ class ModuleArgsParser:
301
321
  raise AnsibleParserError("action and local_action are mutually exclusive", obj=self._task_ds)
302
322
  thing = self._task_ds.get('local_action', '')
303
323
  delegate_to = 'localhost'
304
- action, args = self._normalize_parameters(thing, action=action, additional_args=additional_args)
305
-
306
- if action is not None and not skip_action_validation:
307
- context = _get_action_context(action, self._collection_list)
308
- if context is not None and context.resolved:
309
- self.resolved_action = context.resolved_fqcn
324
+ action, args = self._normalize_parameters(thing, additional_args=additional_args)
310
325
 
311
326
  # module: <stuff> is the more new-style invocation
312
327
 
@@ -315,14 +330,13 @@ class ModuleArgsParser:
315
330
 
316
331
  # walk the filtered input dictionary to see if we recognize a module name
317
332
  for item, value in non_task_ds.items():
318
- context = None
319
- is_action_candidate = False
320
333
  if item in BUILTIN_TASKS:
321
334
  is_action_candidate = True
322
335
  elif skip_action_validation:
323
336
  is_action_candidate = True
324
337
  else:
325
338
  try:
339
+ # DTFIX-FUTURE: extract to a helper method, shared with Task.post_validate_args
326
340
  context = _get_action_context(item, self._collection_list)
327
341
  except AnsibleError as e:
328
342
  if e.obj is None:
@@ -336,9 +350,6 @@ class ModuleArgsParser:
336
350
  if action is not None:
337
351
  raise AnsibleParserError("conflicting action statements: %s, %s" % (action, item), obj=self._task_ds)
338
352
 
339
- if context is not None and context.resolved:
340
- self.resolved_action = context.resolved_fqcn
341
-
342
353
  action = item
343
354
  thing = value
344
355
  action, args = self._normalize_parameters(thing, action=action, additional_args=additional_args)
@@ -353,14 +364,5 @@ class ModuleArgsParser:
353
364
  else:
354
365
  raise AnsibleParserError("no module/action detected in task.",
355
366
  obj=self._task_ds)
356
- elif args.get('_raw_params', '') != '' and action not in RAW_PARAM_MODULES:
357
- templar = Templar(loader=None)
358
- raw_params = args.pop('_raw_params')
359
- if templar.is_template(raw_params):
360
- args['_variable_params'] = raw_params
361
- else:
362
- raise AnsibleParserError(
363
- "this task '%s' has extra params, which is only allowed in the following modules: %s" % (action, ", ".join(RAW_PARAM_MODULES_SIMPLE)),
364
- obj=self._task_ds)
365
367
 
366
- return (action, args, delegate_to)
368
+ return action, args, delegate_to