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
@@ -21,35 +21,42 @@ import os
21
21
 
22
22
  from ansible import constants as C
23
23
  from ansible.errors import AnsibleError
24
- from ansible.executor.task_executor import remove_omit
24
+ from ansible.executor.task_result import _RawTaskResult
25
+ from ansible.inventory.host import Host
25
26
  from ansible.module_utils.common.text.converters import to_text
27
+ from ansible.parsing.dataloader import DataLoader
26
28
  from ansible.playbook.handler import Handler
27
29
  from ansible.playbook.task_include import TaskInclude
28
30
  from ansible.playbook.role_include import IncludeRole
29
- from ansible.template import Templar
31
+ from ansible._internal._templating._engine import TemplateEngine
30
32
  from ansible.utils.display import Display
33
+ from ansible.vars.manager import VariableManager
31
34
 
32
35
  display = Display()
33
36
 
34
37
 
35
38
  class IncludedFile:
36
39
 
37
- def __init__(self, filename, args, vars, task, is_role=False):
40
+ def __init__(self, filename, args, vars, task, is_role: bool = False) -> None:
38
41
  self._filename = filename
39
42
  self._args = args
40
43
  self._vars = vars
41
44
  self._task = task
42
- self._hosts = []
45
+ self._hosts: list[Host] = []
43
46
  self._is_role = is_role
44
- self._results = []
47
+ self._results: list[_RawTaskResult] = []
45
48
 
46
- def add_host(self, host):
49
+ def add_host(self, host: Host) -> None:
47
50
  if host not in self._hosts:
48
51
  self._hosts.append(host)
49
52
  return
53
+
50
54
  raise ValueError()
51
55
 
52
56
  def __eq__(self, other):
57
+ if not isinstance(other, IncludedFile):
58
+ return False
59
+
53
60
  return (other._filename == self._filename and
54
61
  other._args == self._args and
55
62
  other._vars == self._vars and
@@ -60,23 +67,28 @@ class IncludedFile:
60
67
  return "%s (args=%s vars=%s): %s" % (self._filename, self._args, self._vars, self._hosts)
61
68
 
62
69
  @staticmethod
63
- def process_include_results(results, iterator, loader, variable_manager):
64
- included_files = []
65
- task_vars_cache = {}
70
+ def process_include_results(
71
+ results: list[_RawTaskResult],
72
+ iterator,
73
+ loader: DataLoader,
74
+ variable_manager: VariableManager,
75
+ ) -> list[IncludedFile]:
76
+ included_files: list[IncludedFile] = []
77
+ task_vars_cache: dict[tuple, dict] = {}
66
78
 
67
79
  for res in results:
68
80
 
69
- original_host = res._host
70
- original_task = res._task
81
+ original_host = res.host
82
+ original_task = res.task
71
83
 
72
84
  if original_task.action in C._ACTION_ALL_INCLUDES:
73
85
 
74
86
  if original_task.loop:
75
- if 'results' not in res._result:
87
+ if 'results' not in res._return_data:
76
88
  continue
77
- include_results = res._result['results']
89
+ include_results = res._loop_results
78
90
  else:
79
- include_results = [res._result]
91
+ include_results = [res._return_data]
80
92
 
81
93
  for include_result in include_results:
82
94
  # if the task result was skipped or failed, continue
@@ -114,7 +126,7 @@ class IncludedFile:
114
126
  if loader.get_basedir() not in task_vars['ansible_search_path']:
115
127
  task_vars['ansible_search_path'].append(loader.get_basedir())
116
128
 
117
- templar = Templar(loader=loader, variables=task_vars)
129
+ templar = TemplateEngine(loader=loader, variables=task_vars)
118
130
 
119
131
  if original_task.action in C._ACTION_INCLUDE_TASKS:
120
132
  include_file = None
@@ -132,6 +144,8 @@ class IncludedFile:
132
144
  parent_include_dir = parent_include._role_path
133
145
  else:
134
146
  try:
147
+ # FUTURE: Since the parent include path has already been resolved, it should be used here.
148
+ # Unfortunately it's not currently stored anywhere, so it must be calculated again.
135
149
  parent_include_dir = os.path.dirname(templar.template(parent_include.args.get('_raw_params')))
136
150
  except AnsibleError as e:
137
151
  parent_include_dir = ''
@@ -144,7 +158,7 @@ class IncludedFile:
144
158
  cumulative_path = os.path.join(parent_include_dir, cumulative_path)
145
159
  else:
146
160
  cumulative_path = parent_include_dir
147
- include_target = templar.template(include_result['include'])
161
+ include_target = include_result['include']
148
162
  if original_task._role:
149
163
  dirname = 'handlers' if isinstance(original_task, Handler) else 'tasks'
150
164
  new_basedir = os.path.join(original_task._role._role_path, dirname, cumulative_path)
@@ -170,7 +184,7 @@ class IncludedFile:
170
184
 
171
185
  if include_file is None:
172
186
  if original_task._role:
173
- include_target = templar.template(include_result['include'])
187
+ include_target = include_result['include']
174
188
  include_file = loader.path_dwim_relative(
175
189
  original_task._role._role_path,
176
190
  'handlers' if isinstance(original_task, Handler) else 'tasks',
@@ -179,25 +193,17 @@ class IncludedFile:
179
193
  else:
180
194
  include_file = loader.path_dwim(include_result['include'])
181
195
 
182
- include_file = templar.template(include_file)
183
196
  inc_file = IncludedFile(include_file, include_args, special_vars, original_task)
184
197
  else:
185
198
  # template the included role's name here
186
199
  role_name = include_args.pop('name', include_args.pop('role', None))
187
- if role_name is not None:
188
- role_name = templar.template(role_name)
189
-
190
200
  new_task = original_task.copy()
191
201
  new_task.post_validate(templar=templar)
192
202
  new_task._role_name = role_name
193
203
  for from_arg in new_task.FROM_ARGS:
194
204
  if from_arg in include_args:
195
205
  from_key = from_arg.removesuffix('_from')
196
- new_task._from_files[from_key] = templar.template(include_args.pop(from_arg))
197
-
198
- omit_token = task_vars.get('omit')
199
- if omit_token:
200
- new_task._from_files = remove_omit(new_task._from_files, omit_token)
206
+ new_task._from_files[from_key] = include_args.pop(from_arg)
201
207
 
202
208
  inc_file = IncludedFile(role_name, include_args, special_vars, new_task, is_role=True)
203
209
 
@@ -40,8 +40,8 @@ class LoopControl(FieldAttributeBase):
40
40
  return t.load_data(data, variable_manager=variable_manager, loader=loader)
41
41
 
42
42
  def _post_validate_break_when(self, attr, value, templar):
43
- '''
43
+ """
44
44
  break_when is evaluated after the execution of the loop is complete,
45
45
  and should not be templated during the regular post_validate step.
46
- '''
46
+ """
47
47
  return value
ansible/playbook/play.py CHANGED
@@ -19,8 +19,8 @@ from __future__ import annotations
19
19
 
20
20
  from ansible import constants as C
21
21
  from ansible import context
22
+ from ansible.errors import AnsibleError
22
23
  from ansible.errors import AnsibleParserError, AnsibleAssertionError
23
- from ansible.module_utils.common.text.converters import to_native
24
24
  from ansible.module_utils.common.collections import is_sequence
25
25
  from ansible.module_utils.six import binary_type, string_types, text_type
26
26
  from ansible.playbook.attribute import NonInheritableFieldAttribute
@@ -31,6 +31,7 @@ from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles
31
31
  from ansible.playbook.role import Role
32
32
  from ansible.playbook.task import Task
33
33
  from ansible.playbook.taggable import Taggable
34
+ from ansible.parsing.vault import EncryptedString
34
35
  from ansible.utils.display import Display
35
36
 
36
37
  display = Display()
@@ -99,6 +100,15 @@ class Play(Base, Taggable, CollectionSearch):
99
100
  def __repr__(self):
100
101
  return self.get_name()
101
102
 
103
+ def _get_cached_role(self, role):
104
+ role_path = role.get_role_path()
105
+ role_cache = self.role_cache[role_path]
106
+ try:
107
+ idx = role_cache.index(role)
108
+ return role_cache[idx]
109
+ except ValueError:
110
+ raise AnsibleError(f'Cannot locate {role.get_name()} in role cache')
111
+
102
112
  def _validate_hosts(self, attribute, name, value):
103
113
  # Only validate 'hosts' if a value was passed in to original data set.
104
114
  if 'hosts' in self._ds:
@@ -113,11 +123,11 @@ class Play(Base, Taggable, CollectionSearch):
113
123
  elif not isinstance(entry, (binary_type, text_type)):
114
124
  raise AnsibleParserError("Hosts list contains an invalid host value: '{host!s}'".format(host=entry))
115
125
 
116
- elif not isinstance(value, (binary_type, text_type)):
126
+ elif not isinstance(value, (binary_type, text_type, EncryptedString)):
117
127
  raise AnsibleParserError("Hosts list must be a sequence or string. Please check your playbook.")
118
128
 
119
129
  def get_name(self):
120
- ''' return the name of the Play '''
130
+ """ return the name of the Play """
121
131
  if self.name:
122
132
  return self.name
123
133
 
@@ -136,9 +146,9 @@ class Play(Base, Taggable, CollectionSearch):
136
146
  return p.load_data(data, variable_manager=variable_manager, loader=loader)
137
147
 
138
148
  def preprocess_data(self, ds):
139
- '''
149
+ """
140
150
  Adjusts play datastructure to cleanup old/legacy items
141
- '''
151
+ """
142
152
 
143
153
  if not isinstance(ds, dict):
144
154
  raise AnsibleAssertionError('while preprocessing data (%s), ds should be a dict but was a %s' % (ds, type(ds)))
@@ -158,55 +168,57 @@ class Play(Base, Taggable, CollectionSearch):
158
168
 
159
169
  return super(Play, self).preprocess_data(ds)
160
170
 
171
+ # DTFIX-FUTURE: these do nothing but augment the exception message; DRY and nuke
172
+
161
173
  def _load_tasks(self, attr, ds):
162
- '''
174
+ """
163
175
  Loads a list of blocks from a list which may be mixed tasks/blocks.
164
176
  Bare tasks outside of a block are given an implicit block.
165
- '''
177
+ """
166
178
  try:
167
179
  return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
168
- except AssertionError as e:
169
- raise AnsibleParserError("A malformed block was encountered while loading tasks: %s" % to_native(e), obj=self._ds, orig_exc=e)
180
+ except AssertionError as ex:
181
+ raise AnsibleParserError("A malformed block was encountered while loading tasks.", obj=self._ds) from ex
170
182
 
171
183
  def _load_pre_tasks(self, attr, ds):
172
- '''
184
+ """
173
185
  Loads a list of blocks from a list which may be mixed tasks/blocks.
174
186
  Bare tasks outside of a block are given an implicit block.
175
- '''
187
+ """
176
188
  try:
177
189
  return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
178
- except AssertionError as e:
179
- raise AnsibleParserError("A malformed block was encountered while loading pre_tasks", obj=self._ds, orig_exc=e)
190
+ except AssertionError as ex:
191
+ raise AnsibleParserError("A malformed block was encountered while loading pre_tasks.", obj=self._ds) from ex
180
192
 
181
193
  def _load_post_tasks(self, attr, ds):
182
- '''
194
+ """
183
195
  Loads a list of blocks from a list which may be mixed tasks/blocks.
184
196
  Bare tasks outside of a block are given an implicit block.
185
- '''
197
+ """
186
198
  try:
187
199
  return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
188
- except AssertionError as e:
189
- raise AnsibleParserError("A malformed block was encountered while loading post_tasks", obj=self._ds, orig_exc=e)
200
+ except AssertionError as ex:
201
+ raise AnsibleParserError("A malformed block was encountered while loading post_tasks.", obj=self._ds) from ex
190
202
 
191
203
  def _load_handlers(self, attr, ds):
192
- '''
204
+ """
193
205
  Loads a list of blocks from a list which may be mixed handlers/blocks.
194
206
  Bare handlers outside of a block are given an implicit block.
195
- '''
207
+ """
196
208
  try:
197
209
  return self._extend_value(
198
210
  self.handlers,
199
211
  load_list_of_blocks(ds=ds, play=self, use_handlers=True, variable_manager=self._variable_manager, loader=self._loader),
200
212
  prepend=True
201
213
  )
202
- except AssertionError as e:
203
- raise AnsibleParserError("A malformed block was encountered while loading handlers", obj=self._ds, orig_exc=e)
214
+ except AssertionError as ex:
215
+ raise AnsibleParserError("A malformed block was encountered while loading handlers.", obj=self._ds) from ex
204
216
 
205
217
  def _load_roles(self, attr, ds):
206
- '''
218
+ """
207
219
  Loads and returns a list of RoleInclude objects from the datastructure
208
220
  list of role definitions and creates the Role from those objects
209
- '''
221
+ """
210
222
 
211
223
  if ds is None:
212
224
  ds = []
@@ -214,8 +226,8 @@ class Play(Base, Taggable, CollectionSearch):
214
226
  try:
215
227
  role_includes = load_list_of_roles(ds, play=self, variable_manager=self._variable_manager,
216
228
  loader=self._loader, collection_search_list=self.collections)
217
- except AssertionError as e:
218
- raise AnsibleParserError("A malformed role declaration was encountered.", obj=self._ds, orig_exc=e)
229
+ except AssertionError as ex:
230
+ raise AnsibleParserError("A malformed role declaration was encountered.", obj=self._ds) from ex
219
231
 
220
232
  roles = []
221
233
  for ri in role_includes:
@@ -242,13 +254,13 @@ class Play(Base, Taggable, CollectionSearch):
242
254
  return vars_prompts
243
255
 
244
256
  def _compile_roles(self):
245
- '''
257
+ """
246
258
  Handles the role compilation step, returning a flat list of tasks
247
259
  with the lowest level dependencies first. For example, if a role R
248
260
  has a dependency D1, which also has a dependency D2, the tasks from
249
261
  D2 are merged first, followed by D1, and lastly by the tasks from
250
262
  the parent role R last. This is done for all roles in the Play.
251
- '''
263
+ """
252
264
 
253
265
  block_list = []
254
266
 
@@ -263,10 +275,10 @@ class Play(Base, Taggable, CollectionSearch):
263
275
  return block_list
264
276
 
265
277
  def compile_roles_handlers(self):
266
- '''
278
+ """
267
279
  Handles the role handler compilation step, returning a flat list of Handlers
268
280
  This is done for all roles in the Play.
269
- '''
281
+ """
270
282
 
271
283
  block_list = []
272
284
 
@@ -279,25 +291,39 @@ class Play(Base, Taggable, CollectionSearch):
279
291
  return block_list
280
292
 
281
293
  def compile(self):
282
- '''
294
+ """
283
295
  Compiles and returns the task list for this play, compiled from the
284
296
  roles (which are themselves compiled recursively) and/or the list of
285
297
  tasks specified in the play.
286
- '''
287
-
298
+ """
288
299
  # create a block containing a single flush handlers meta
289
300
  # task, so we can be sure to run handlers at certain points
290
301
  # of the playbook execution
291
- flush_block = Block.load(
292
- data={'meta': 'flush_handlers'},
293
- play=self,
294
- variable_manager=self._variable_manager,
295
- loader=self._loader
296
- )
297
-
298
- for task in flush_block.block:
299
- task.implicit = True
302
+ flush_block = Block(play=self)
303
+
304
+ t = Task(block=flush_block)
305
+ t.action = 'meta'
306
+ t.resolved_action = 'ansible.builtin.meta'
307
+ t.args['_raw_params'] = 'flush_handlers'
308
+ t.implicit = True
309
+ t.set_loader(self._loader)
310
+
311
+ if self.tags:
312
+ # Avoid calling flush_handlers in case the whole play is skipped on tags,
313
+ # this could be performance improvement since calling flush_handlers on
314
+ # large inventories could be expensive even if no hosts are notified
315
+ # since we call flush_handlers per host.
316
+ # Block.filter_tagged_tasks ignores evaluating tags on implicit meta
317
+ # tasks so we need to explicitly call Task.evaluate_tags here.
318
+ t.tags = self.tags
319
+ if t.evaluate_tags(self.only_tags, self.skip_tags, all_vars=self.vars):
320
+ flush_block.block = [t]
321
+ else:
322
+ flush_block.block = [t]
300
323
 
324
+ # NOTE keep flush_handlers tasks even if a section has no regular tasks,
325
+ # there may be notified handlers from the previous section
326
+ # (typically when a handler notifies a handler defined before)
301
327
  block_list = []
302
328
  if self.force_handlers:
303
329
  noop_task = Task()
@@ -307,18 +333,33 @@ class Play(Base, Taggable, CollectionSearch):
307
333
  noop_task.set_loader(self._loader)
308
334
 
309
335
  b = Block(play=self)
310
- b.block = self.pre_tasks or [noop_task]
336
+ if self.pre_tasks:
337
+ b.block = self.pre_tasks
338
+ else:
339
+ nt = noop_task.copy(exclude_parent=True)
340
+ nt._parent = b
341
+ b.block = [nt]
311
342
  b.always = [flush_block]
312
343
  block_list.append(b)
313
344
 
314
345
  tasks = self._compile_roles() + self.tasks
315
346
  b = Block(play=self)
316
- b.block = tasks or [noop_task]
347
+ if tasks:
348
+ b.block = tasks
349
+ else:
350
+ nt = noop_task.copy(exclude_parent=True)
351
+ nt._parent = b
352
+ b.block = [nt]
317
353
  b.always = [flush_block]
318
354
  block_list.append(b)
319
355
 
320
356
  b = Block(play=self)
321
- b.block = self.post_tasks or [noop_task]
357
+ if self.post_tasks:
358
+ b.block = self.post_tasks
359
+ else:
360
+ nt = noop_task.copy(exclude_parent=True)
361
+ nt._parent = b
362
+ b.block = [nt]
322
363
  b.always = [flush_block]
323
364
  block_list.append(b)
324
365
 
@@ -65,11 +65,13 @@ RESET_VARS = (
65
65
 
66
66
  class PlayContext(Base):
67
67
 
68
- '''
68
+ """
69
69
  This class is used to consolidate the connection information for
70
70
  hosts in a play and child tasks, where the task may override some
71
71
  connection/authentication information.
72
- '''
72
+ """
73
+
74
+ _post_validate_object = True
73
75
 
74
76
  # base
75
77
  module_compression = FieldAttribute(isa='string', default=C.DEFAULT_MODULE_COMPRESSION)
@@ -88,7 +90,7 @@ class PlayContext(Base):
88
90
  # networking modules
89
91
  network_os = FieldAttribute(isa='string')
90
92
 
91
- # docker FIXME: remove these
93
+ # FIXME: docker - remove these
92
94
  docker_extra_args = FieldAttribute(isa='string')
93
95
 
94
96
  # ???
@@ -103,10 +105,6 @@ class PlayContext(Base):
103
105
  become_flags = FieldAttribute(isa='string', default=C.DEFAULT_BECOME_FLAGS)
104
106
  prompt = FieldAttribute(isa='string')
105
107
 
106
- # general flags
107
- only_tags = FieldAttribute(isa='set', default=set)
108
- skip_tags = FieldAttribute(isa='set', default=set)
109
-
110
108
  start_at_task = FieldAttribute(isa='string')
111
109
  step = FieldAttribute(isa='bool', default=False)
112
110
 
@@ -158,11 +156,11 @@ class PlayContext(Base):
158
156
  self.force_handlers = play.force_handlers
159
157
 
160
158
  def set_attributes_from_cli(self):
161
- '''
159
+ """
162
160
  Configures this connection information instance with data from
163
161
  options specified by the user on the command line. These have a
164
162
  lower precedence than those set on the play or host.
165
- '''
163
+ """
166
164
  if context.CLIARGS.get('timeout', False):
167
165
  self.timeout = int(context.CLIARGS['timeout'])
168
166
 
@@ -175,14 +173,14 @@ class PlayContext(Base):
175
173
  self.start_at_task = context.CLIARGS.get('start_at_task', None) # Else default
176
174
 
177
175
  def set_task_and_variable_override(self, task, variables, templar):
178
- '''
176
+ """
179
177
  Sets attributes from the task if they are set, which will override
180
178
  those from the play.
181
179
 
182
180
  :arg task: the task object with the parameters that were set on it
183
181
  :arg variables: variables from inventory
184
182
  :arg templar: templar instance if templating variables is needed
185
- '''
183
+ """
186
184
 
187
185
  new_info = self.copy()
188
186
 
@@ -201,8 +199,7 @@ class PlayContext(Base):
201
199
  # In the case of a loop, the delegated_to host may have been
202
200
  # templated based on the loop variable, so we try and locate
203
201
  # the host name in the delegated variable dictionary here
204
- delegated_host_name = templar.template(task.delegate_to)
205
- delegated_vars = variables.get('ansible_delegated_vars', dict()).get(delegated_host_name, dict())
202
+ delegated_vars = variables.get('ansible_delegated_vars', dict()).get(task.delegate_to, dict())
206
203
 
207
204
  delegated_transport = C.DEFAULT_TRANSPORT
208
205
  for transport_var in C.MAGIC_VARIABLE_MAPPING.get('connection'):
@@ -218,8 +215,8 @@ class PlayContext(Base):
218
215
  if address_var in delegated_vars:
219
216
  break
220
217
  else:
221
- display.debug("no remote address found for delegated host %s\nusing its name, so success depends on DNS resolution" % delegated_host_name)
222
- delegated_vars['ansible_host'] = delegated_host_name
218
+ display.debug("no remote address found for delegated host %s\nusing its name, so success depends on DNS resolution" % task.delegate_to)
219
+ delegated_vars['ansible_host'] = task.delegate_to
223
220
 
224
221
  # reset the port back to the default if none was specified, to prevent
225
222
  # the delegated host from inheriting the original host's setting
@@ -312,10 +309,10 @@ class PlayContext(Base):
312
309
  self._become_plugin = plugin
313
310
 
314
311
  def update_vars(self, variables):
315
- '''
312
+ """
316
313
  Adds 'magic' variables relating to connections to the variable dictionary provided.
317
314
  In case users need to access from the play, this is a legacy from runner.
318
- '''
315
+ """
319
316
 
320
317
  for prop, var_list in C.MAGIC_VARIABLE_MAPPING.items():
321
318
  try:
@@ -19,38 +19,45 @@ from __future__ import annotations
19
19
 
20
20
  import os
21
21
 
22
- import ansible.constants as C
23
- from ansible.errors import AnsibleParserError, AnsibleAssertionError
24
22
  from ansible.module_utils.common.text.converters import to_bytes
25
- from ansible.module_utils.six import string_types
26
- from ansible.parsing.splitter import split_args
27
- from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping
28
23
  from ansible.playbook.attribute import NonInheritableFieldAttribute
29
24
  from ansible.playbook.base import Base
30
25
  from ansible.playbook.conditional import Conditional
31
26
  from ansible.playbook.taggable import Taggable
32
27
  from ansible.utils.collection_loader import AnsibleCollectionConfig
33
28
  from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path, _get_collection_playbook_path
34
- from ansible.template import Templar
35
- from ansible.utils.display import Display
36
-
37
- display = Display()
29
+ from ansible._internal._templating._engine import TemplateEngine
30
+ from ansible.errors import AnsibleError
31
+ from ansible import constants as C
38
32
 
39
33
 
40
34
  class PlaybookInclude(Base, Conditional, Taggable):
41
35
 
42
- import_playbook = NonInheritableFieldAttribute(isa='string')
43
- vars_val = NonInheritableFieldAttribute(isa='dict', default=dict, alias='vars')
36
+ import_playbook = NonInheritableFieldAttribute(isa='string', required=True)
37
+
38
+ _post_validate_object = True # manually post_validate to get free arg validation/coercion
39
+
40
+ def preprocess_data(self, ds):
41
+ keys = {action for action in C._ACTION_IMPORT_PLAYBOOK if action in ds}
42
+
43
+ if len(keys) != 1:
44
+ raise AnsibleError(f'Found conflicting import_playbook actions: {", ".join(sorted(keys))}')
45
+
46
+ key = next(iter(keys))
47
+
48
+ ds['import_playbook'] = ds.pop(key)
49
+
50
+ return ds
44
51
 
45
52
  @staticmethod
46
53
  def load(data, basedir, variable_manager=None, loader=None):
47
54
  return PlaybookInclude().load_data(ds=data, basedir=basedir, variable_manager=variable_manager, loader=loader)
48
55
 
49
56
  def load_data(self, ds, variable_manager=None, loader=None, basedir=None):
50
- '''
57
+ """
51
58
  Overrides the base load_data(), as we're actually going to return a new
52
59
  Playbook() object rather than a PlaybookInclude object
53
- '''
60
+ """
54
61
 
55
62
  # import here to avoid a dependency loop
56
63
  from ansible.playbook import Playbook
@@ -62,18 +69,22 @@ class PlaybookInclude(Base, Conditional, Taggable):
62
69
  new_obj = super(PlaybookInclude, self).load_data(ds, variable_manager, loader)
63
70
 
64
71
  all_vars = self.vars.copy()
72
+
65
73
  if variable_manager:
66
74
  all_vars |= variable_manager.get_vars()
67
75
 
68
- templar = Templar(loader=loader, variables=all_vars)
76
+ templar = TemplateEngine(loader=loader, variables=all_vars)
77
+
78
+ new_obj.post_validate(templar)
69
79
 
70
80
  # then we use the object to load a Playbook
71
81
  pb = Playbook(loader=loader)
72
82
 
73
- file_name = templar.template(new_obj.import_playbook)
83
+ file_name = new_obj.import_playbook
74
84
 
75
85
  # check for FQCN
76
86
  resource = _get_collection_playbook_path(file_name)
87
+
77
88
  if resource is not None:
78
89
  playbook = resource[1]
79
90
  playbook_collection = resource[2]
@@ -92,6 +103,7 @@ class PlaybookInclude(Base, Conditional, Taggable):
92
103
  else:
93
104
  # it is NOT a collection playbook, setup adjacent paths
94
105
  AnsibleCollectionConfig.playbook_paths.append(os.path.dirname(os.path.abspath(to_bytes(playbook, errors='surrogate_or_strict'))))
106
+ # broken, see: https://github.com/ansible/ansible/issues/85357
95
107
 
96
108
  pb._load_playbook_data(file_name=playbook, variable_manager=variable_manager, vars=self.vars.copy())
97
109
 
@@ -120,50 +132,3 @@ class PlaybookInclude(Base, Conditional, Taggable):
120
132
  task_block._when = new_obj.when[:] + task_block.when[:]
121
133
 
122
134
  return pb
123
-
124
- def preprocess_data(self, ds):
125
- '''
126
- Reorganizes the data for a PlaybookInclude datastructure to line
127
- up with what we expect the proper attributes to be
128
- '''
129
-
130
- if not isinstance(ds, dict):
131
- raise AnsibleAssertionError('ds (%s) should be a dict but was a %s' % (ds, type(ds)))
132
-
133
- # the new, cleaned datastructure, which will have legacy
134
- # items reduced to a standard structure
135
- new_ds = AnsibleMapping()
136
- if isinstance(ds, AnsibleBaseYAMLObject):
137
- new_ds.ansible_pos = ds.ansible_pos
138
-
139
- for (k, v) in ds.items():
140
- if k in C._ACTION_IMPORT_PLAYBOOK:
141
- self._preprocess_import(ds, new_ds, k, v)
142
- else:
143
- # some basic error checking, to make sure vars are properly
144
- # formatted and do not conflict with k=v parameters
145
- if k == 'vars':
146
- if 'vars' in new_ds:
147
- raise AnsibleParserError("import_playbook parameters cannot be mixed with 'vars' entries for import statements", obj=ds)
148
- elif not isinstance(v, dict):
149
- raise AnsibleParserError("vars for import_playbook statements must be specified as a dictionary", obj=ds)
150
- new_ds[k] = v
151
-
152
- return super(PlaybookInclude, self).preprocess_data(new_ds)
153
-
154
- def _preprocess_import(self, ds, new_ds, k, v):
155
- '''
156
- Splits the playbook import line up into filename and parameters
157
- '''
158
- if v is None:
159
- raise AnsibleParserError("playbook import parameter is missing", obj=ds)
160
- elif not isinstance(v, string_types):
161
- raise AnsibleParserError("playbook import parameter must be a string indicating a file path, got %s instead" % type(v), obj=ds)
162
-
163
- # The import_playbook line must include at least one item, which is the filename
164
- # to import. Anything after that should be regarded as a parameter to the import
165
- items = split_args(v)
166
- if len(items) == 0:
167
- raise AnsibleParserError("import_playbook statements must specify the file name to import", obj=ds)
168
-
169
- new_ds['import_playbook'] = items[0].strip()